diff --git a/fast/stages/0-org-setup/datasets/hardened/README.md b/fast/stages/0-org-setup/datasets/hardened/README.md index bb1f09ac2..15b975e28 100644 --- a/fast/stages/0-org-setup/datasets/hardened/README.md +++ b/fast/stages/0-org-setup/datasets/hardened/README.md @@ -79,6 +79,7 @@ In that case, the controls placed in the `organization/scc-sha-custom-modules` f | `compute.disableNestedVirtualization` | Prevent the creation of Compute Engine instances with nested virtualization enabled. | | | `compute.disableSerialPortAccess` | Prevent the enablement of serial port access for VM instances. | **CIS for GCP 3.0**: 4.5
**CIS Controls 8.0**: 4.8
**PCI-DSS 4.0**: 1.2.1, 1.4.1
**NIST 800-53 R5**: CM-6, CM-7
**ISO-2700-1 v2022**: A.8.9
**SOC2 v2017**: CC6.6.1, CC6.6.3, CC6.6.4 | | `compute.disableVpcExternalIpv6` | Prevent configuration of subnets with external IPv6 ranges. | | +| `compute.disableVpcInternalIpv6` | Enforce the block of VPC subnetworks from using internal IPv6 addresses. A subnetwork with an internal IPv6 address might be exposed to potential risks due to its current limited support. | | | `compute.managed.blockPreviewFeatures` | Ensures that preview feature updates are blocked unless explicitly allowed | | | `compute.managed.disableSerialPortLogging` | Prevent serial port logging to Cloud Logging for VMs. | | | `compute.managed.vmCanIpForward` | Prevent IP forwarding from being enabled on Compute Engine instances. | **CIS for GCP 3.0**: 4.6
**CIS Controls 8.0**: 4.4, 4.5
**NIST 800-53 R5**: CA-9, SC-7
**SOC2 v2017**: CC6.6.1, CC6.6.4 | @@ -109,11 +110,14 @@ In that case, the controls placed in the `organization/scc-sha-custom-modules` f | `container.managed.enableGoogleGroupsRBAC` | Enforce that GKE is configured so Google Groups can be used with RBAC | **CIS for GKE 1.5**: 5.8.2
**PCI-DSS 4.0**: 1.1.2 | | `container.managed.enableNetworkPolicy` | Enforce that GKE clusters are configured with Network Policy enabled | **CIS for GKE 1.5**: 5.6.7
**PCI-DSS 4.0**: 1.2,1.1,1.4
**ISO-2700-1 v2013**: A.13.1.1 | | `container.managed.enablePrivateNodes` | Enforce that GKE clusters are created as private clusters with private nodes | **CIS for GKE 1.5**: 5.6.5
**PCI-DSS 4.0**: 1.3.1 | +| `container.managed.enableSecretsEncryption` | Enforce that the GKE clusters is configured to encrypt secret in etcd | **CIS for GKE 1.5**: 5.3.1
**PCI-DSS 4.0**: 3.6 | | `container.managed.enableSecurityBulletinNotifications` | Require enabling Security Bulletin Notifications in GKE clusters. | | | `container.managed.enableShieldedNodes` | Enforce that GKE nodes is configured with shielded GKE nodes | **CIS for GKE 1.5**: 5.5.5 | | `container.managed.enableWorkloadIdentityFederation` | Enforce that GKE clusters are enabled with Workload Identity | **CIS for GKE 1.5**: 5.2.2
**PCI-DSS 4.0**: 7.2.2 | | `essentialcontacts.allowedContactDomains` | Restrict essential contact domains to an authorized list. | | | `gcp.resourceLocations` | Restrict resource locations. | | +| `gcp.restrictCmekCryptoKeyProjects` | Prevent the use of CMEKs from unauthorized projects. | | +| `gcp.restrictNonCmekServices` | Ensure That All BigQuery Tables Are Encrypted With Customer-Managed Encryption Key (CMEK) | **CIS for GCP 3.0**: 7.2
**CIS Controls 8.0**: 3.11
**PCI-DSS 4.0**: 3.1.1, 3.3.2, 3.3.3, 3.5.1, 3.5.1.2, 3.5.1.3, 8.3.2
**NIST 800-53 R5**: IA-5, SC-28
**NIST Cybersecurity Framework 1.0**: PR-DS-1
**ISO-2700-1 v2022**: A.5.33
**HIPAA**: 164.312(a)(2)(iv), 164.312(e)(2)(ii)
**Cloud Controls Matrix 4**: CEK-03 | | `gcp.restrictTLSCipherSuites` | Prevent the use of weak cipher suites and TLS versions on HTTPS and SSL Proxy load balancers. | **CIS for GCP 3.0**: 3.9
**NIST 800-53 R4**: SC-7
**ISO-2700-1 v2013**: A.14.1.3 | | `gcp.restrictTLSVersion` | Prevent the use of weak cipher suites and TLS versions on HTTPS and SSL Proxy load balancers. | **CIS for GCP 3.0**: 3.9
**NIST 800-53 R4**: SC-7
**ISO-2700-1 v2013**: A.14.1.3 | | `iam.allowedPolicyMemberDomains` | Restrict domain sharing to authorized domains. | **CIS for GCP 3.0**: 1.1
**NIST 800-53 R4**: AC-3
**ISO-2700-1 v2013**: A.9.2.3 | @@ -142,7 +146,9 @@ In that case, the controls placed in the `organization/scc-sha-custom-modules` f |---|---|---| | `accesscontextmanagerDisableBridgePerimeters` | Ensure no perimeter bridges are used. Instead, use ingress and egress rules. | | | `cloudbuildDisableWorkerPoolExternalIP` | Prevent the configuration of Cloud Build worker pools with external IP addresses. | | +| `cloudkmsAllowedAlgorithms` | Ensure the algorithm used for Cloud KMS keys is configured correctly. | | | `cloudkmsAllowedProtectionLevel` | Ensure Cloud KMS keys are configured with the correct protection level. | | +| `cloudkmsAllowedRotationPeriod` | Ensure Cloud KMS keys have the correct rotation period configured. | **CIS for GCP 3.0**: 1.10
**CIS Controls 8.0**: 3.11
**PCI-DSS 4.0**: 3.1.1, 3.3.2, 3.3.3, 3.5.1, 3.5.1.2, 3.5.1.3, 8.3.2
**NIST 800-53 R4**: SC-12
**NIST 800-53 R5**: IA-5, SC-28
**ISO-2700-1 v2013**: A.10.1.2
**ISO-2700-1 v2022**: A.5.33
**SOC2 v2017**: CC6.1.10, CC6.1.3
**HIPAA**: 164.312(a)(2)(iv), 164.312(e)(2)(ii)
**Cloud Controls Matrix 4**: CEK-03 | | `cloudrunDisableEnvironmentVariablePattern` | Prevent secrets from being stored in Cloud Run environment variables. | **CIS for GCP 3.0**: 1.17 | | `cloudrunJobDisableDefaultServiceAccount` | Ensure all Cloud Run jobs use a non-default service account. | | | `cloudrunJobRequireBinaryAuthorization` | Enforce all Cloud Run jobs use binary authorization. | | @@ -159,6 +165,7 @@ In that case, the controls placed in the `organization/scc-sha-custom-modules` f | `cloudsqlRequireSQLServerDatabaseFlags` | Ensure 'external scripts enabled' database flag for Cloud SQL SQL Server instance is set to 'off' | **CIS for GCP 3.0**: 6.3.1
**CIS Controls 8.0**: 2.7
**PCI-DSS 4.0**: 1.2.5, 2.2.4, 6.4.3
**NIST 800-53 R5**: CM-7, SI-7
**NIST Cybersecurity Framework 1.0**: PR-IP-1, PR-PT-3
**SOC2 v2017**: CC5.2.1, CC5.2.2, CC5.2.3, CC5.2.4 | | `cloudsqlRequireSSLConnection` | Ensure That the Cloud SQL Database Instance Requires All Incoming Connections To Use SSL | **CIS for GCP 3.0**: 6.4
**NIST 800-53 R4**: SC-7
**ISO-2700-1 v2013**: A.13.2.1, A.14.1.3, A.8.2.3 | | `dataprocDisableDefaultServiceAccount` | Prevent Dataproc VMs from using default user-managed service accounts. | | +| `dataprocRequireDiskCmekEncryption` | Enforce encryption of Dataproc clusters with a Customer-Managed Encryption Key (CMEK). | **CIS for GCP 3.0**: 8.1
**CIS Controls 8.0**: 3.11
**PCI-DSS 4.0**: 3.1.1, 3.3.2, 3.3.3, 3.5.1, 3.5.1.2, 3.5.1.3, 8.3.2
**NIST 800-53 R5**: IA-5, SC-28
**NIST Cybersecurity Framework 1.0**: PR-DS-1
**ISO-2700-1 v2013**: A.5.33
**SOC2 v2017**: CC6.1.10, CC6.1.3
**HIPAA**: 164.312(a)(2)(iv), 164.312(e)(2)(ii)
**Cloud Controls Matrix 4**: CEK-03 | | `dataprocRequireInternalIp` | Enforce the use of internal IP addresses only for Dataproc clusters. | | | `dataprocRequireKerberos` | Enforce the use of Kerberos for secure authentication on all Dataproc clusters. | | | `dnsAllowedSigningAlgorithms` | Prevent the use of the RSASHA1 algorithm for the Key-Signing Key in Cloud DNS DNSSEC. | **CIS for GCP 3.0**: 3.4
**PCI-DSS 4.0**: 1.1.1, 1.2.1, 1.2.6, 1.2.7, 1.4.2, 1.5.1, 2.1.1, 2.2.1
**NIST 800-53 R4**: 4.2
**NIST 800-53 R5**: AC-18, CM-2, CM-6, CM-7, CM-9
**NIST Cybersecurity Framework 1.0**: PR-IP-1
**ISO-2700-1 v2022**: A.8.9
**SOC2 v2017**: CC5.2.2
**Cloud Controls Matrix 4**: IVS-04 | @@ -171,6 +178,8 @@ In that case, the controls placed in the `organization/scc-sha-custom-modules` f | `firewallRestrictCacheSearchDatabasesRule` | Prevent Cassandra port access from the internet via VPC firewall rules. | **CIS Controls 8.0**: 4.4, 4.5
**PCI-DSS 4.0**: 1.2.1, 1.4.1
**NIST 800-53 R4**: SC-7
**NIST 800-53 R5**: CA-9, SC-7
**ISO-2700-1 v2013**: A.13.1.1
**SOC2 v2017**: CC6.6.1, CC6.6.4 | | `firewallRestrictDirectoryServicesPolicyRule` | Prevent directory services port access from the internet via firewall policies. | **CIS Controls 8.0**: 4.4, 4.5
**PCI-DSS 4.0**: 1.2.1, 1.4.1
**NIST 800-53 R4**: SC-7
**NIST 800-53 R5**: CA-9, SC-7
**ISO-2700-1 v2013**: A.13.1.1
**SOC2 v2017**: CC6.6.1, CC6.6.4 | | `firewallRestrictDirectoryServicesRule` | Prevent directory services port access from the internet via VPC firewall rules. | **CIS Controls 8.0**: 4.4, 4.5
**PCI-DSS 4.0**: 1.2.1, 1.4.1
**NIST 800-53 R4**: SC-7
**NIST 800-53 R5**: CA-9, SC-7
**ISO-2700-1 v2013**: A.13.1.1
**SOC2 v2017**: CC6.6.1, CC6.6.4 | +| `firewallRestrictExplicitAllPortsPolicyRule` | Prevent rules that explicitly specify all TCP/UDP ports using ranges like 0-65535 or 1-65535 via firewall policies. | | +| `firewallRestrictExplicitAllPortsRule` | Prevent rules that explicitly specify all TCP/UDP ports using ranges like 0-65535 or 1-65535 via VPC firewall rules or any ports. | | | `firewallRestrictInsecureProtocolsPolicyRule` | Prevent FTP port access from the internet via firewall policies. | **CIS Controls 8.0**: 4.4, 4.5
**PCI-DSS 4.0**: 1.2.1, 1.4.1
**NIST 800-53 R4**: SC-7
**NIST 800-53 R5**: CA-9, SC-7
**ISO-2700-1 v2013**: A.13.1.1
**SOC2 v2017**: CC6.6.1, CC6.6.4 | | `firewallRestrictInsecureProtocolsRule` | Prevent FTP port access from the internet via VPC firewall rules. | **CIS Controls 8.0**: 4.4, 4.5
**PCI-DSS 4.0**: 1.2.1, 1.4.1
**NIST 800-53 R4**: SC-7
**NIST 800-53 R5**: CA-9, SC-7
**ISO-2700-1 v2013**: A.13.1.1
**SOC2 v2017**: CC6.6.1, CC6.6.4 | | `firewallRestrictMailProtocolsPolicyRule` | Prevent POP3 port access from the internet via firewall policies. | **CIS Controls 8.0**: 4.4, 4.5
**PCI-DSS 4.0**: 1.2.1, 1.4.1
**NIST 800-53 R4**: SC-7
**NIST 800-53 R5**: CA-9, SC-7
**ISO-2700-1 v2013**: A.13.1.1
**SOC2 v2017**: CC6.6.1, CC6.6.4 | @@ -181,7 +190,8 @@ In that case, the controls placed in the `organization/scc-sha-custom-modules` f | `firewallRestrictNetworkServicesRule` | Prevent DNS port access from the internet via VPC firewall rules. | **CIS Controls 8.0**: 4.4, 4.5
**PCI-DSS 4.0**: 1.2.1, 1.4.1
**NIST 800-53 R4**: SC-7
**NIST 800-53 R5**: CA-9, SC-7
**ISO-2700-1 v2013**: A.13.1.1
**SOC2 v2017**: CC6.6.1, CC6.6.4 | | `firewallRestrictNoSQLDatabasesPolicyRule` | Prevent Elasticsearch port access from the internet via firewall policies. | **CIS Controls 8.0**: 4.4, 4.5
**PCI-DSS 4.0**: 1.2.1, 1.4.1
**NIST 800-53 R4**: SC-7
**NIST 800-53 R5**: CA-9, SC-7
**ISO-2700-1 v2013**: A.13.1.1
**SOC2 v2017**: CC6.6.1, CC6.6.4 | | `firewallRestrictNoSQLDatabasesRule` | Prevent Elasticsearch port access from the internet via VPC firewall rules. | **CIS Controls 8.0**: 4.4, 4.5
**PCI-DSS 4.0**: 1.2.1, 1.4.1
**NIST 800-53 R4**: SC-7
**NIST 800-53 R5**: CA-9, SC-7
**ISO-2700-1 v2013**: A.13.1.1
**SOC2 v2017**: CC6.6.1, CC6.6.4 | -| `firewallRestrictPublicAccessRule` | Prevent the creation of VPC firewall rules with a source or destination of `0.0.0.0/0`. | | +| `firewallRestrictPublicAccessPolicyRule` | Prevent open to public access via firewall policies. | | +| `firewallRestrictPublicAccessRule` | Prevent open to public access via VPC firewall rules. | | | `firewallRestrictRdpPolicyRule` | Prevent RDP access from the internet via firewall policies. | **CIS for GCP 3.0**: 3.7
**CIS Controls 8.0**: 4.4, 4.5
**PCI-DSS 4.0**: 1.2.1, 1.4.1
**NIST 800-53 R4**: SC-7
**NIST 800-53 R5**: CA-9, SC-7
**ISO-2700-1 v2013**: A.13.1.1
**SOC2 v2017**: CC6.6.1, CC6.6.4 | | `firewallRestrictRdpRule` | Prevent RDP access from the internet via VPC firewall rules. | **CIS for GCP 3.0**: 3.7
**CIS Controls 8.0**: 4.4, 4.5
**PCI-DSS 4.0**: 1.2.1, 1.4.1
**NIST 800-53 R4**: SC-7
**NIST 800-53 R5**: CA-9, SC-7
**ISO-2700-1 v2013**: A.13.1.1
**SOC2 v2017**: CC6.6.1, CC6.6.4 | | `firewallRestrictSQLDatabasesPolicyRule` | Prevent MySQL port access from the internet via firewall policies. | **CIS Controls 8.0**: 4.4, 4.5
**PCI-DSS 4.0**: 1.2.1, 1.4.1
**NIST 800-53 R4**: SC-7
**NIST 800-53 R5**: CA-9, SC-7
**ISO-2700-1 v2013**: A.13.1.1
**SOC2 v2017**: CC6.6.1, CC6.6.4 | @@ -204,6 +214,7 @@ In that case, the controls placed in the `organization/scc-sha-custom-modules` f | `gkeRequireMonitoring` | Enforce that GKE clusters monitoring is enabled | **CIS for GKE 1.5**: 5.7.1
**PCI-DSS 4.0**: 10.2 | | `gkeRequireNodePoolAutoRepair` | Enforce that GKE clusters are configured with node auto-repair enabled | **CIS for GKE 1.5**: 5.5.2
**PCI-DSS 4.0**: 2.2.6 | | `gkeRequireNodePoolAutoUpgrade` | Enforce that GKE clusters are configured with node auto-upgrade enabled | **CIS for GKE 1.5**: 5.5.3
**PCI-DSS 4.0**: 2.2.6 | +| `gkeRequireNodePoolCMEKEncryption` | Enforce that GKE nodes are configured with CMEK Encryption | **CIS for GKE 1.5**: 5.9.1
**PCI-DSS 4.0**: 3.6 | | `gkeRequireNodePoolSandbox` | Enforce that the GKE clusters nodes are isolated using GKE sandbox | **CIS for GKE 1.5**: 5.10.3
**PCI-DSS 4.0**: 6.2.1 | | `gkeRequirePrivateEndpoint` | Enforce that GKE clusters are created as private clusters with public endpoint disabled | **CIS for GKE 1.5**: 5.6.4
**PCI-DSS 4.0**: 1.3.1 | | `gkeRequireRegionalClusters` | Enforce the creation of regional GKE clusters | | @@ -231,8 +242,10 @@ SCC Custom SHA Detectors are available only for organization have subscribed to | Module | Description | Compliance Mapping | |---|---|---| +| `artifactregistryRequireCMEK` | Ensure Artifact Registry repositories are encrypted with a Customer-Managed Encryption Key (CMEK). | | | `cloudfunctionsV1RequireIngressInternalAndLoadBalancer` | Ensure Cloud Functions Gen1 only allows internal and load balancer traffic. | | | `cloudfunctionsV1RequireVPCConnector` | Ensure Cloud Functions v1 are configured with a VPC connector. | | +| `cloudkmsAllowedAlgorithms` | Ensure the algorithm used for Cloud KMS keys is configured correctly. | | | `cloudkmsAllowedProtectionLevel` | Ensure Cloud KMS keys are configured with the correct protection level. | | | `cloudrunDisableJobDefaultServiceAccount` | Ensure all Cloud Run services use a non-default service account. | | | `cloudrunDisableServiceDefaultServiceAccount` | Ensure all Cloud Run jobs use a non-default service account. | | @@ -276,8 +289,8 @@ region: $locations:primary ip_cidr_range: 10.73.0.0/24 description: Default primary-region subnet for dev flow_logs_config: # This section enables VPC Flow Logs - aggregation_interval: "INTERVAL_15_MIN" - flow_sampling: 0.5 + aggregation_interval: "INTERVAL_5_SEC" + flow_sampling: 1.0 metadata: "INCLUDE_ALL_METADATA" ``` diff --git a/fast/stages/0-org-setup/datasets/hardened/folders/data-platform/.config.yaml b/fast/stages/0-org-setup/datasets/hardened/folders/data-platform/.config.yaml index 7ea777cc8..0f3c9fec9 100644 --- a/fast/stages/0-org-setup/datasets/hardened/folders/data-platform/.config.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/folders/data-platform/.config.yaml @@ -15,3 +15,10 @@ # yaml-language-server: $schema=../../../../schemas/folder.schema.json name: Data Platform +org_policies: + custom.iamDisableAdminServiceAccount: + rules: + - enforce: false + custom.iamDisableProjectServiceAccountImpersonationRoles: + rules: + - enforce: false diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudkmsAllowedAlgorithms.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudkmsAllowedAlgorithms.yaml new file mode 100644 index 000000000..db0f24fe2 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudkmsAllowedAlgorithms.yaml @@ -0,0 +1,34 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +custom.cloudkmsAllowedAlgorithms: + action_type: DENY + condition: |- + has(resource.versionTemplate.algorithm) && resource.versionTemplate.algorithm in [ + 'GOOGLE_SYMMETRIC_ENCRYPTION', + 'RSA_SIGN_PSS_2048_SHA256', + 'RSA_SIGN_PSS_3072_SHA256', + 'RSA_SIGN_PSS_4096_SHA256', + 'RSA_DECRYPT_OAEP_2048_SHA256', + 'RSA_DECRYPT_OAEP_4096_SHA256', + 'RSA_DECRYPT_OAEP_2048_SHA1', + 'RSA_DECRYPT_OAEP_4096_SHA1' + ] == false + description: Ensure the algorithm for Cloud KMS keys is configured correctly + display_name: Require Cloud KMS keys algorithm to be configured correctly + method_types: + - CREATE + - UPDATE + resource_types: + - cloudkms.googleapis.com/CryptoKey diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudkmsAllowedRotationPeriod.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudkmsAllowedRotationPeriod.yaml new file mode 100644 index 000000000..fe3074669 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudkmsAllowedRotationPeriod.yaml @@ -0,0 +1,25 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +custom.cloudkmsAllowedRotationPeriod: + action_type: DENY + condition: |- + has(resource.rotationPeriod) && resource.rotationPeriod > duration("7776000s") + description: Ensure the rotation period for Cloud KMS keys is configured correctly + display_name: Require Cloud KMS keys to have rotation period configured correctly + method_types: + - CREATE + - UPDATE + resource_types: + - cloudkms.googleapis.com/CryptoKey diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.dataprocRequireDiskCmekEncryption.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.dataprocRequireDiskCmekEncryption.yaml new file mode 100644 index 000000000..e9bda23da --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.dataprocRequireDiskCmekEncryption.yaml @@ -0,0 +1,26 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +custom.dataprocRequireDiskCmekEncryption: + action_type: DENY + condition: |- + has(resource.config.encryptionConfig.gcePdKmsKeyName) == false + description: Enforce that the Dataproc cluster is created with an CMEK encryption + key. + display_name: Enable Dataproc CMEK encryption + method_types: + - CREATE + - UPDATE + resource_types: + - dataproc.googleapis.com/Cluster diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictExplicitAllPortsPolicyRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictExplicitAllPortsPolicyRule.yaml new file mode 100644 index 000000000..31c3e9090 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictExplicitAllPortsPolicyRule.yaml @@ -0,0 +1,37 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +custom.firewallRestrictExplicitAllPortsPolicyRule: + action_type: DENY + condition: |- + resource.rules.exists(rule, + rule.action == 'allow' && + rule.priority < 2147483644 && + rule.direction == 'INGRESS' && + rule.match.layer4Configs.exists(l4, + l4.ipProtocol in ['tcp', 'udp'] && ( + !has(l4.ports) || + '0-65535' in l4.ports || + '1-65535' in l4.ports + ) + ) + ) + description: Prevent Firewall Policy rules that explicitly specify all TCP/UDP ports + using ranges like 0-65535 or 1-65535 + display_name: Restrict Firewall Policy rules with explicit all-ports specifications + method_types: + - CREATE + - UPDATE + resource_types: + - compute.googleapis.com/FirewallPolicy diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictExplicitAllPortsRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictExplicitAllPortsRule.yaml new file mode 100644 index 000000000..191c7c5a8 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictExplicitAllPortsRule.yaml @@ -0,0 +1,39 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +custom.firewallRestrictExplicitAllPortsRule: + action_type: DENY + condition: |- + resource.direction == 'INGRESS' && + resource.allowed.exists(rule, + rule.IPProtocol in ['tcp', 'udp'] && ( + !has(rule.ports) || + '0-65535' in rule.ports || + '1-65535' in rule.ports + ) + ) && + !resource.name.startsWith('gke-') && + !resource.name.startsWith('k8s-') && + !resource.name.endsWith('-hc') && + !resource.name.startsWith('k8s2-') && + !resource.name.startsWith('gkegw1-l7-') && + !resource.name.startsWith('gkemcg1-l7-') + description: Prevent VPC firewall rules that explicitly specify all TCP/UDP ports + using ranges like 0-65535 or 1-65535 + display_name: Restrict VPC Firewall rules with explicit all-ports specifications + method_types: + - CREATE + - UPDATE + resource_types: + - compute.googleapis.com/Firewall diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictPublicAccessPolicyRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictPublicAccessPolicyRule.yaml new file mode 100644 index 000000000..a96f37578 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictPublicAccessPolicyRule.yaml @@ -0,0 +1,33 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +custom.firewallRestrictPublicAccessPolicyRule: + action_type: DENY + condition: |- + resource.rules.exists(rule, + rule.action == 'allow' && + rule.priority < 2147483644 && + rule.direction == 'INGRESS' && + rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0') && + !rule.match.layer4Configs.exists(l4, + l4.ipProtocol == 'icmp' + ) + ) + description: Prevent Firewall Policy ingress rules from 0.0.0.0/0 except for allowed protocols (ICMP) + display_name: Restrict Firewall Policy ingress rules allowing public Internet access + method_types: + - CREATE + - UPDATE + resource_types: + - compute.googleapis.com/FirewallPolicy diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictPublicAccessRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictPublicAccessRule.yaml index 13c119111..4e548cf4a 100644 --- a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictPublicAccessRule.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictPublicAccessRule.yaml @@ -15,15 +15,16 @@ custom.firewallRestrictPublicAccessRule: action_type: DENY condition: |- - (size(resource.allowed) > 0) && - ( - resource.sourceRanges.exists(range, range == '0.0.0.0/0') || - resource.destinationRanges.exists(range, range == '0.0.0.0/0') + resource.direction == 'INGRESS' && + size(resource.allowed) > 0 && + resource.sourceRanges.exists(r, r == '0.0.0.0/0') && + !resource.allowed.exists(a, + a.IPProtocol == 'icmp' ) - description: Prevent the creation of VPC firewall rules with source or destination - any IP address (0.0.0.0/0) - display_name: Restrict VPC Firewall rules allowing public Internet access + description: Prevent VPC Firewall ingress rules from 0.0.0.0/0 except for allowed protocols (ICMP). + display_name: Restrict VPC Firewall ingress rules allowing public Internet access method_types: - CREATE + - UPDATE resource_types: - compute.googleapis.com/Firewall diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.iamAllowedMembers.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.iamAllowedMembers.yaml index 9443cd4df..505d75977 100644 --- a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.iamAllowedMembers.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.iamAllowedMembers.yaml @@ -17,7 +17,8 @@ custom.iamAllowedMembers: condition: |- resource.bindings.exists(binding, binding.members.exists(member, - !MemberSubjectEndsWith(member, ['@${organization.domain}', '.gserviceaccount.com']) + MemberSubjectStartsWith(member, ['user:', 'group:']) && + !MemberSubjectEndsWith(member, ['@${organization.domain}', '${iam_principals.gcp-organization-admins}']) ) ) description: Ensure no binding are done with members outside the organization domain diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.iamDisableAdminServiceAccount.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.iamDisableAdminServiceAccount.yaml new file mode 100644 index 000000000..d50775090 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.iamDisableAdminServiceAccount.yaml @@ -0,0 +1,38 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +custom.iamDisableAdminServiceAccount: + action_type: DENY + condition: |- + resource.bindings.exists(binding, + binding.members.exists(member, + !MemberSubjectEndsWith(member, ['@cloudservices.gserviceaccount.com']) && + MemberSubjectStartsWith(member, ['serviceAccount:']) && + !MemberSubjectEndsWith(member, ['@${project_ids.iac-0}.iam.gserviceaccount.com']) + ) && + ( + RoleNameMatches(binding.role, ['roles/owner', 'roles/admin']) || + RoleNameMatches(binding.role, ['roles/editor', 'roles/writer']) || + RoleNameContains(binding.role, ['admin', 'Admin']) + ) + ) + description: Ensure no use of the legacy basic roles (owner and editor), basic roles + (admin, writer) and usage of admin roles for service account + display_name: Deny use of the legacy basic roles, basic roles and usage of admin role + for service account + method_types: + - CREATE + - UPDATE + resource_types: + - iam.googleapis.com/AllowPolicy diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.iamDisableBasicRoles.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.iamDisableBasicRoles.yaml new file mode 100644 index 000000000..5a2eba910 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.iamDisableBasicRoles.yaml @@ -0,0 +1,36 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +custom.iamDisableBasicRoles: + action_type: DENY + condition: |- + resource.bindings.exists(binding, + binding.members.exists(member, + MemberSubjectStartsWith(member, ['user:', 'group:']) && + !MemberSubjectStartsWith(member, ['${iam_principals.gcp-organization-admins}']) && + ( + RoleNameMatches(binding.role, ['roles/owner', 'roles/admin']) || + RoleNameMatches(binding.role, ['roles/editor', 'roles/writer']) || + RoleNameContains(binding.role, ['roles/viewer', 'roles/reader']) + ) + ) + ) + description: Ensure no use of the legacy basic roles (viewer, editor and owner) and + basic roles (reader, writer and admin) + display_name: Deny use of the basic roles + method_types: + - CREATE + - UPDATE + resource_types: + - iam.googleapis.com/AllowPolicy diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.iamDisableProjectServiceAccountImpersonationRoles.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.iamDisableProjectServiceAccountImpersonationRoles.yaml new file mode 100644 index 000000000..3293330db --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.iamDisableProjectServiceAccountImpersonationRoles.yaml @@ -0,0 +1,37 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +custom.iamDisableProjectServiceAccountImpersonationRoles: + action_type: DENY + condition: |- + resource.bindings.exists(binding, + binding.members.exists(member, + MemberSubjectStartsWith(member, ['user:', 'group:']) && + !MemberSubjectStartsWith(member, ['${iam_principals.gcp-organization-admins}']) + ) && + ( + RoleNameMatches(binding.role, ['roles/iam.serviceAccountUser']) || + RoleNameMatches(binding.role, ['roles/iam.serviceAccountTokenCreator']) + ) + ) + description: Ensure that IAM Users are not assigned the service account user or + service account token creator roles (requires usage of IAM Condition and tags + to ensure the constraint is not applied on allowed service accounts) + display_name: Deny assignment of the service account user or service account token + creator roles to users + method_types: + - CREATE + - UPDATE + resource_types: + - iam.googleapis.com/AllowPolicy diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/cloudkms.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/cloudkms.yaml index a8b5a71ee..3272e5475 100644 --- a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/cloudkms.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/cloudkms.yaml @@ -18,10 +18,22 @@ # yaml-language-server: $schema=../../../../schemas/org-policies.schema.json +custom.cloudkmsAllowedAlgorithms: + rules: + - enforce: true + custom.cloudkmsAllowedProtectionLevel: rules: - enforce: true +custom.cloudkmsAllowedRotationPeriod: + rules: + - enforce: true + +custom.dataprocRequireDiskCmekEncryption: + rules: + - enforce: true + gcp.restrictCmekCryptoKeyProjects: rules: - allow: @@ -77,7 +89,9 @@ gcp.restrictNonCmekServices: - "run.googleapis.com" - "secretmanager.googleapis.com" - "securesourcemanager.googleapis.com" - - "securitycenter.googleapis.com" + # To enabled when needed: https://docs.cloud.google.com/security-command-center/docs/cmek + # CMEK needs can be configured at activation time only + # - "securitycenter.googleapis.com" - "spanner.googleapis.com" - "speech.googleapis.com" - "sqladmin.googleapis.com" diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/firewall.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/firewall.yaml index 9d15f7c24..e1b6d2866 100644 --- a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/firewall.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/firewall.yaml @@ -46,6 +46,14 @@ custom.firewallRestrictDirectoryServicesRule: rules: - enforce: true +custom.firewallRestrictExplicitAllPortsPolicyRule: + rules: + - enforce: true + +custom.firewallRestrictExplicitAllPortsRule: + rules: + - enforce: true + custom.firewallRestrictInsecureProtocolsPolicyRule: rules: - enforce: true @@ -86,6 +94,10 @@ custom.firewallRestrictNoSQLDatabasesRule: rules: - enforce: true +custom.firewallRestrictPublicAccessPolicyRule: + rules: + - enforce: true + custom.firewallRestrictPublicAccessRule: rules: - enforce: true diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/gke.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/gke.yaml index 8e0f40544..8afea5c9f 100644 --- a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/gke.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/gke.yaml @@ -58,6 +58,10 @@ container.managed.enablePrivateNodes: rules: - enforce: true +container.managed.enableSecretsEncryption: + rules: + - enforce: true + container.managed.enableSecurityBulletinNotifications: rules: - enforce: true @@ -134,6 +138,10 @@ custom.gkeRequireNodePoolAutoUpgrade: rules: - enforce: true +custom.gkeRequireNodePoolCMEKEncryption: + rules: + - enforce: true + custom.gkeRequireNodePoolSandbox: rules: - enforce: true diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/iam.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/iam.yaml index 5a0c0dbf0..f359a5d18 100644 --- a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/iam.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/iam.yaml @@ -18,6 +18,23 @@ # yaml-language-server: $schema=../../../../schemas/org-policies.schema.json +custom.iamDisableAdminServiceAccount: + rules: + - enforce: true + +custom.iamDisableBasicRoles: + rules: + - enforce: true + +custom.iamDisableProjectServiceAccountImpersonationRoles: + rules: + - enforce: false + condition: + title: Allow service account impersonation for tagged users + expression: | + resource.matchTag('${organization.id}/org-policies', 'allowed-sa-impersonation') + - enforce: true + custom.iamDisableRedisAdminRoles: rules: - enforce: false @@ -68,6 +85,10 @@ iam.managed.disableServiceAccountApiKeyCreation: rules: - enforce: true +iam.managed.preventPrivilegedBasicRolesForDefaultServiceAccounts: + rules: + - enforce: true + iam.serviceAccountKeyExposureResponse: rules: - allow: diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/serviceusage.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/serviceusage.yaml new file mode 100644 index 000000000..d4f49292d --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/serviceusage.yaml @@ -0,0 +1,103 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +--- +# sample subset of useful organization policies, edit to suit requirements +# start of document (---) avoids errors if the file only contains comments + +# yaml-language-server: $schema=../../../../schemas/org-policies.schema.json + +gcp.restrictServiceUsage: + rules: + - allow: + values: + - "accesscontextmanager.googleapis.com" + - "analyticshub.googleapis.com" + - "anthos.googleapis.com" + - "anthosconfigmanagement.googleapis.com" + - "appoptimize.googleapis.com" + - "artifactregistry.googleapis.com" + - "autoscaling.googleapis.com" + - "bigquery.googleapis.com" + - "bigqueryconnection.googleapis.com" + - "bigquerydatapolicy.googleapis.com" + - "bigquerydatatransfer.googleapis.com" + - "bigquerymigration.googleapis.com" + - "bigqueryreservation.googleapis.com" + - "bigquerystorage.googleapis.com" + - "billingbudgets.googleapis.com" + - "certificatemanager.googleapis.com" + - "cloudaicompanion.googleapis.com" + - "cloudapis.googleapis.com" + - "cloudasset.googleapis.com" + - "cloudbilling.googleapis.com" + - "cloudbuild.googleapis.com" + - "cloudkms.googleapis.com" + - "cloudquotas.googleapis.com" + - "cloudresourcemanager.googleapis.com" + - "cloudsecuritycompliance.googleapis.com" + - "cloudtrace.googleapis.com" + - "composer.googleapis.com" + - "compute.googleapis.com" + - "container.googleapis.com" + - "containerfilesystem.googleapis.com" + - "containerregistry.googleapis.com" + - "containersecurity.googleapis.com" + - "containerthreatdetection.googleapis.com" + - "datacatalog.googleapis.com" + - "dataform.googleapis.com" + - "datalineage.googleapis.com" + - "dataplex.googleapis.com" + - "datastore.googleapis.com" + - "deploymentmanager.googleapis.com" + - "dns.googleapis.com" + - "essentialcontacts.googleapis.com" + - "geminicloudassist.googleapis.com" + - "gkebackup.googleapis.com" + - "gkeconnect.googleapis.com" + - "gkehub.googleapis.com" + - "iam.googleapis.com" + - "iamcredentials.googleapis.com" + - "iap.googleapis.com" + - "logging.googleapis.com" + - "monitoring.googleapis.com" + - "multiclusteringress.googleapis.com" + - "multiclustermetering.googleapis.com" + - "multiclusterservicediscovery.googleapis.com" + - "networkconnectivity.googleapis.com" + - "networkmanagement.googleapis.com" + - "networksecurity.googleapis.com" + - "notebooksecurityscanner.googleapis.com" + - "orgpolicy.googleapis.com" + - "oslogin.googleapis.com" + - "privateca.googleapis.com" + - "pubsub.googleapis.com" + - "recommender.googleapis.com" + - "secretmanager.googleapis.com" + - "securitycenter.googleapis.com" + - "securitycentermanagement.googleapis.com" + - "servicedirectory.googleapis.com" + - "servicemanagement.googleapis.com" + - "servicenetworking.googleapis.com" + - "serviceusage.googleapis.com" + - "sql-component.googleapis.com" + - "sqladmin.googleapis.com" + - "stackdriver.googleapis.com" + - "storage-api.googleapis.com" + - "storage-component.googleapis.com" + - "storage.googleapis.com" + - "sts.googleapis.com" + - "trafficdirector.googleapis.com" + - "vpcaccess.googleapis.com" + - "websecurityscanner.googleapis.com" diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/artifactregistryRequireCMEK.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/artifactregistryRequireCMEK.yaml new file mode 100644 index 000000000..42dff4663 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/artifactregistryRequireCMEK.yaml @@ -0,0 +1,23 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +artifactregistryRequireCMEK: + description: Detect if Artifact Registry repositories are not encrypted using CMEK + predicate: + expression: (!has(resource.kmsKeyName)) + recommendation: Ensure the Artifact Registry repositoriesa are encrypted using CMEK + resource_selector: + resource_types: + - artifactregistry.googleapis.com/Repository + severity: HIGH diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudkmsAllowedAlgorithms.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudkmsAllowedAlgorithms.yaml new file mode 100644 index 000000000..dd69e09a2 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudkmsAllowedAlgorithms.yaml @@ -0,0 +1,23 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cloudkmsAllowedAlgorithms: + description: Detect if the the algorithm for Cloud KMS keys is not configured correctly + predicate: + expression: resource.algorithm in ["GOOGLE_SYMMETRIC_ENCRYPTION", "EXTERNAL_SYMMETRIC_ENCRYPTION"] == false + recommendation: Ensure the algorithm for Cloud KMS keys is configured correctly + resource_selector: + resource_types: + - cloudkms.googleapis.com/CryptoKeyVersion + severity: MEDIUM diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/gkeRequireDataplaneV2.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/gkeRequireDataplaneV2.yaml index e2f7dea71..cf133e8b9 100644 --- a/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/gkeRequireDataplaneV2.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/gkeRequireDataplaneV2.yaml @@ -15,7 +15,7 @@ gkeRequireDataplaneV2: description: Detect if GKE clusters are configured with a version different than Dataplane V2 predicate: - expression: resource.networkConfig.datapathProvider == 'ADVANCED_DATAPATH' + expression: resource.networkConfig.datapathProvider != 'ADVANCED_DATAPATH' recommendation: Ensure only GKE Dataplane V2 are configured resource_selector: resource_types: diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/tags/org-policies.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/tags/org-policies.yaml index ebf85412f..119f2dfee 100644 --- a/fast/stages/0-org-setup/datasets/hardened/organization/tags/org-policies.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/organization/tags/org-policies.yaml @@ -23,3 +23,5 @@ values: description: "Allow all domains in essntial contacts org policy." allowed-policy-member-domains-all: description: "Allow all domains in DRS org policy." + allowed-sa-impersonation: + description: "Allow service account impersonation for tagged principals." diff --git a/fast/stages/0-org-setup/organization.tf b/fast/stages/0-org-setup/organization.tf index 0786ded42..4a067e4ea 100644 --- a/fast/stages/0-org-setup/organization.tf +++ b/fast/stages/0-org-setup/organization.tf @@ -92,10 +92,9 @@ module "organization" { } contacts = lookup(local.organization, "contacts", {}) factories_config = { - org_policy_custom_constraints = "${local.paths.organization}/custom-constraints" - custom_roles = "${local.paths.organization}/custom-roles" - tags = "${local.paths.organization}/tags" - scc_sha_custom_modules = "${local.paths.organization}/scc-sha-custom-modules" + custom_roles = "${local.paths.organization}/custom-roles" + tags = "${local.paths.organization}/tags" + scc_sha_custom_modules = "${local.paths.organization}/scc-sha-custom-modules" } tags_config = { ignore_iam = true @@ -113,7 +112,8 @@ module "organization-iam" { condition_vars = merge( local.ctx_condition_vars, { folder_ids = module.factory.folder_ids }, - { project_ids = module.factory.project_ids } + { project_ids = module.factory.project_ids }, + { iam_principals = local.ctx.iam_principals }, ) custom_roles = merge( local.ctx.custom_roles, @@ -139,8 +139,9 @@ module "organization-iam" { ) }) factories_config = { - org_policies = "${local.paths.organization}/org-policies" - tags = "${local.paths.organization}/tags" + org_policy_custom_constraints = "${local.paths.organization}/custom-constraints" + org_policies = "${local.paths.organization}/org-policies" + tags = "${local.paths.organization}/tags" } iam = lookup( local.organization, "iam", {} diff --git a/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/dev/.config.yaml b/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/dev/.config.yaml index dff43aee4..d633827a3 100644 --- a/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/dev/.config.yaml +++ b/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/dev/.config.yaml @@ -19,3 +19,5 @@ routes: dest_range: 0.0.0.0/0 next_hop_type: "gateway" next_hop: "default-internet-gateway" +# dns_policy: +# logging: true diff --git a/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/dev/subnets/dev-default.yaml b/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/dev/subnets/dev-default.yaml index 8e55d098f..b3961f5d5 100644 --- a/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/dev/subnets/dev-default.yaml +++ b/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/dev/subnets/dev-default.yaml @@ -7,6 +7,6 @@ region: $locations:primary ip_cidr_range: 10.73.0.0/24 description: Default primary-region subnet for dev # flow_logs_config: -# aggregation_interval: "INTERVAL_15_MIN" -# flow_sampling: 0.5 +# aggregation_interval: "INTERVAL_5_SEC" +# flow_sampling: 1.0 # metadata: "INCLUDE_ALL_METADATA" diff --git a/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/hub/.config.yaml b/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/hub/.config.yaml index 7738355ea..ec9b0e468 100644 --- a/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/hub/.config.yaml +++ b/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/hub/.config.yaml @@ -24,3 +24,5 @@ routes: dest_range: 0.0.0.0/0 next_hop_type: "gateway" next_hop: "default-internet-gateway" +# dns_policy: +# logging: true diff --git a/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/hub/subnets/hub-default.yaml b/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/hub/subnets/hub-default.yaml index 11f2d5ca7..5c9236a7c 100644 --- a/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/hub/subnets/hub-default.yaml +++ b/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/hub/subnets/hub-default.yaml @@ -7,6 +7,6 @@ region: $locations:primary ip_cidr_range: 10.71.0.0/24 description: Default primary-region subnet for hub # flow_logs_config: -# aggregation_interval: "INTERVAL_15_MIN" -# flow_sampling: 0.5 +# aggregation_interval: "INTERVAL_5_SEC" +# flow_sampling: 1.0 # metadata: "INCLUDE_ALL_METADATA" diff --git a/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/prod/.config.yaml b/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/prod/.config.yaml index ce8c859bc..276180569 100644 --- a/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/prod/.config.yaml +++ b/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/prod/.config.yaml @@ -31,3 +31,5 @@ subnets_proxy_only: region: $locations:primary name: primary-region-proxy-only active: true +# dns_policy: +# logging: true diff --git a/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/prod/subnets/prod-default.yaml b/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/prod/subnets/prod-default.yaml index b4f4028c4..3a5e024f3 100644 --- a/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/prod/subnets/prod-default.yaml +++ b/fast/stages/2-networking/datasets/hub-and-spokes-peerings/vpcs/prod/subnets/prod-default.yaml @@ -7,6 +7,6 @@ region: $locations:primary ip_cidr_range: 10.72.0.0/24 description: Default primary-region subnet for prod # flow_logs_config: -# aggregation_interval: "INTERVAL_15_MIN" -# flow_sampling: 0.5 +# aggregation_interval: "INTERVAL_5_SEC" +# flow_sampling: 1.0 # metadata: "INCLUDE_ALL_METADATA" diff --git a/fast/stages/UPGRADING.md b/fast/stages/UPGRADING.md index 8c7d6a739..223a4569c 100644 --- a/fast/stages/UPGRADING.md +++ b/fast/stages/UPGRADING.md @@ -12,5 +12,17 @@ As usual, consider this a guideline with no guarantees. Migrations between FAST > v44.0.0 and v45.0.0 deprecated several legacy stages, refer to those releases or branches for legacy upgrading instructions. Upgrades from legacy to current stages are not directly supported. +> v52.0.0 moves creation of custom constraints to `module.organization-iam` (from `module.organization`) in stage `0-org-setup`. As `moved` block is not possible and supported for this change, manual state migration is required to avoid destroying existing constraints. +> This can be done executing this in stage `0-org-setup`: +> ```bash +> constraints=$(terraform state list | grep 'module.organization\[0\].google_org_policy_custom_constraint.constraint') +> for old in $constraints; do +> terraform state mv "$old" "${old/module.organization\[0\]/module.organization-iam\[0\]}" +> done +> ``` +> **Warning**: If you skip this step and run `terraform apply`, Terraform will destroy the existing constraints. Because deleted custom constraints cannot be immediately recreated with the same name, the subsequent creation step will fail, breaking your deployment (refer to this [documentation](https://docs.cloud.google.com/resource-manager/docs/organization-policy/creating-managing-custom-constraints#delete_custom_constraint)) for more information. + + + diff --git a/modules/organization/org-policy-custom-constraints.tf b/modules/organization/org-policy-custom-constraints.tf index 0f8cff724..2ba44150e 100644 --- a/modules/organization/org-policy-custom-constraints.tf +++ b/modules/organization/org-policy-custom-constraints.tf @@ -53,7 +53,7 @@ resource "google_org_policy_custom_constraint" "constraint" { display_name = each.value.display_name description = each.value.description action_type = each.value.action_type - condition = each.value.condition + condition = templatestring(each.value.condition, var.context.condition_vars) method_types = each.value.method_types resource_types = each.value.resource_types } diff --git a/tests/fast/stages/s0_org_setup/hardened.yaml b/tests/fast/stages/s0_org_setup/hardened.yaml index b221d5676..03bc4380e 100644 --- a/tests/fast/stages/s0_org_setup/hardened.yaml +++ b/tests/fast/stages/s0_org_setup/hardened.yaml @@ -1286,6 +1286,32 @@ values: parent: organizations/1234567890 tags: null timeouts: null + module.factory.module.folder-1["data-platform"].google_org_policy_policy.default["custom.iamDisableAdminServiceAccount"]: + dry_run_spec: [] + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'FALSE' + parameters: null + values: [] + timeouts: null + ? module.factory.module.folder-1["data-platform"].google_org_policy_policy.default["custom.iamDisableProjectServiceAccountImpersonationRoles"] + : dry_run_spec: [] + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'FALSE' + parameters: null + values: [] + timeouts: null module.factory.module.folder-1["networking"].google_folder.folder[0]: deletion_protection: false display_name: Networking @@ -2497,6 +2523,1465 @@ values: intercept_children: false name: vpc-sc org_id: '1234567890' + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.accesscontextmanagerDisableBridgePerimeters"] + : action_type: DENY + condition: resource.perimeterType == 'PERIMETER_TYPE_BRIDGE' + description: Ensure no perimeter bridges are used. Instead, use ingress and egress + rules. + display_name: Deny usage of perimeter bridges + method_types: + - CREATE + - UPDATE + name: custom.accesscontextmanagerDisableBridgePerimeters + parent: organizations/1234567890 + resource_types: + - accesscontextmanager.googleapis.com/ServicePerimeter + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudbuildDisableWorkerPoolExternalIP"]: + action_type: DENY + condition: (resource.privatePoolV1Config.networkConfig.egressOption != "NO_PUBLIC_EGRESS") + description: Ensure no unauthorized worker pools external ip used for each build + display_name: Deny unauthorized worker pools external ip used for each build + method_types: + - CREATE + - UPDATE + name: custom.cloudbuildDisableWorkerPoolExternalIP + parent: organizations/1234567890 + resource_types: + - cloudbuild.googleapis.com/WorkerPool + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudkmsAllowedAlgorithms"]: + action_type: DENY + condition: "has(resource.versionTemplate.algorithm) && resource.versionTemplate.algorithm\ + \ in [\n 'GOOGLE_SYMMETRIC_ENCRYPTION',\n 'RSA_SIGN_PSS_2048_SHA256',\n 'RSA_SIGN_PSS_3072_SHA256',\n\ + \ 'RSA_SIGN_PSS_4096_SHA256',\n 'RSA_DECRYPT_OAEP_2048_SHA256',\n 'RSA_DECRYPT_OAEP_4096_SHA256',\n\ + \ 'RSA_DECRYPT_OAEP_2048_SHA1',\n 'RSA_DECRYPT_OAEP_4096_SHA1'\n] == false" + description: Ensure the algorithm for Cloud KMS keys is configured correctly + display_name: Require Cloud KMS keys algorithm to be configured correctly + method_types: + - CREATE + - UPDATE + name: custom.cloudkmsAllowedAlgorithms + parent: organizations/1234567890 + resource_types: + - cloudkms.googleapis.com/CryptoKey + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudkmsAllowedProtectionLevel"]: + action_type: DENY + condition: has(resource.versionTemplate.protectionLevel) && resource.versionTemplate.protectionLevel + in ["SOFTWARE"] == false + description: Ensure the protection level for Cloud KMS keys is configured correctly + display_name: Require Cloud KMS keys protection level to be configured correctly + method_types: + - CREATE + - UPDATE + name: custom.cloudkmsAllowedProtectionLevel + parent: organizations/1234567890 + resource_types: + - cloudkms.googleapis.com/CryptoKey + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudkmsAllowedRotationPeriod"]: + action_type: DENY + condition: has(resource.rotationPeriod) && resource.rotationPeriod > duration("7776000s") + description: Ensure the rotation period for Cloud KMS keys is configured correctly + display_name: Require Cloud KMS keys to have rotation period configured correctly + method_types: + - CREATE + - UPDATE + name: custom.cloudkmsAllowedRotationPeriod + parent: organizations/1234567890 + resource_types: + - cloudkms.googleapis.com/CryptoKey + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudrunDisableEnvironmentVariablePattern"] + : action_type: DENY + condition: "resource.spec.template.spec.containers.exists(container,\n container.env.exists(env,\n\ + \ [\"[sS][eE][cC][rR][eE][tT]\", \"[kK][eE][yY]\", \"[pP][aA][sS][sS][wW][oO][rR][dD]\"\ + , \"[tT][oO][kK][eE][nN]\"].exists(\n pattern, env.name.matches(pattern)\n\ + \ )\n )\n)" + description: Enforce that certain patterns are not used in environment variables + of Cloud Run Service or Cloud Run Functions + display_name: Disable usage of certain patterns in Cloud Run Service or Cloud + Run Functions environment variables + method_types: + - CREATE + - UPDATE + name: custom.cloudrunDisableEnvironmentVariablePattern + parent: organizations/1234567890 + resource_types: + - run.googleapis.com/Service + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudrunJobDisableDefaultServiceAccount"] + : action_type: DENY + condition: resource.spec.template.spec.template.spec.serviceAccountName.endsWith('@developer.gserviceaccount.com') + description: Enforce that service account associated with Cloud Run Job use a + non-default service account + display_name: Disable creation of Cloud Run Job using default service account + method_types: + - CREATE + - UPDATE + name: custom.cloudrunJobDisableDefaultServiceAccount + parent: organizations/1234567890 + resource_types: + - run.googleapis.com/Job + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudrunJobRequireBinaryAuthorization"]: + action_type: DENY + condition: '!(''run.googleapis.com/binary-authorization'' in resource.metadata.annotations)' + description: Enforce that Cloud Run Job are using binary authorization + display_name: Disable creation of Cloud Run Job without Binary Authorization + method_types: + - CREATE + - UPDATE + name: custom.cloudrunJobRequireBinaryAuthorization + parent: organizations/1234567890 + resource_types: + - run.googleapis.com/Job + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudrunServiceDisableDefaultServiceAccount"] + : action_type: DENY + condition: resource.spec.template.spec.serviceAccountName.endsWith('@developer.gserviceaccount.com') + description: Enforce that service account associated with Cloud Run Service use + a non-default service account + display_name: Disable creation of Cloud Run Service using default service account + method_types: + - CREATE + - UPDATE + name: custom.cloudrunServiceDisableDefaultServiceAccount + parent: organizations/1234567890 + resource_types: + - run.googleapis.com/Service + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudrunServiceRequireBinaryAuthorization"] + : action_type: DENY + condition: '!(''run.googleapis.com/binary-authorization'' in resource.metadata.annotations)' + description: Enforce that Cloud Run Service are using binary authorization + display_name: Disable creation of Cloud Run Service without Binary Authorization + method_types: + - CREATE + - UPDATE + name: custom.cloudrunServiceRequireBinaryAuthorization + parent: organizations/1234567890 + resource_types: + - run.googleapis.com/Service + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlDisablePublicAuthorizedNetworks"] + : action_type: DENY + condition: resource.settings.ipConfiguration.authorizedNetworks.exists(network, + network.value == '0.0.0.0/0') + description: Ensure That Cloud SQL database instances do not implicitly whitelist + all public IP addresses + display_name: Require Cloud SQL database instances to not whitelist all public + IP addresses + method_types: + - CREATE + - UPDATE + name: custom.cloudsqlDisablePublicAuthorizedNetworks + parent: organizations/1234567890 + resource_types: + - sqladmin.googleapis.com/Instance + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlEnforcePasswordComplexity"]: + action_type: DENY + condition: 'resource.settings.passwordValidationPolicy.complexity != ''COMPLEXITY_DEFAULT'' + || + + resource.settings.passwordValidationPolicy.minLength < 12' + description: Ensure that Cloud SQL instance is configured with a password complexity + to be combination of lowercase, uppercase, numeric, and non-alphanumeric characters + display_name: Require Cloud SQL instances to configure password complexity to + COMPLEXITY_DEFAULT + method_types: + - CREATE + - UPDATE + name: custom.cloudsqlEnforcePasswordComplexity + parent: organizations/1234567890 + resource_types: + - sqladmin.googleapis.com/Instance + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequireAutomatedBackup"]: + action_type: DENY + condition: resource.settings.backupConfiguration.enabled != true + description: Ensure that Cloud SQL instance have automated backup enabled + display_name: Require Cloud SQL instances to have automated backup enabled + method_types: + - CREATE + - UPDATE + name: custom.cloudsqlRequireAutomatedBackup + parent: organizations/1234567890 + resource_types: + - sqladmin.googleapis.com/Instance + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequireHighAvailability"]: + action_type: DENY + condition: resource.settings.availabilityType != "REGIONAL" + description: Ensure that Cloud SQL instance is configured with high availability + display_name: Require Cloud SQL instances to be configured with high availability + method_types: + - CREATE + - UPDATE + name: custom.cloudsqlRequireHighAvailability + parent: organizations/1234567890 + resource_types: + - sqladmin.googleapis.com/Instance + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequireMySQLDatabaseFlags"]: + action_type: DENY + condition: "resource.databaseVersion.startsWith('MYSQL') && (\n !resource.settings.databaseFlags.exists(flag,\n\ + \ flag.name == 'skip_show_database' && flag.value == 'on'\n ) ||\n !resource.settings.databaseFlags.exists(flag,\n\ + \ flag.name == 'local_infile' && flag.value == 'off'\n )\n)" + description: Ensure Cloud SQL for MySQL instance database flags are set correctly + (e.g skip_show_database, local_infile) + display_name: Require Cloud SQL for MySQL instance database flags to be configured + correctly (e.g skip_show_database, local_infile) + method_types: + - CREATE + - UPDATE + name: custom.cloudsqlRequireMySQLDatabaseFlags + parent: organizations/1234567890 + resource_types: + - sqladmin.googleapis.com/Instance + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequirePointInTimeRecovery"]: + action_type: DENY + condition: "(resource.databaseVersion.contains(\"POSTGRES\")\n || resource.databaseVersion.contains(\"\ + SQLSERVER\"))\n && resource.settings.backupConfiguration.pointInTimeRecoveryEnabled\ + \ == false" + description: Ensure that Cloud SQL instance is configure enable point in time + recovery in the backup configuration. This setting is possibly for Postgres + and SQLServer databases. + display_name: Require Cloud SQL instances to enable point in time recovery + method_types: + - CREATE + - UPDATE + name: custom.cloudsqlRequirePointInTimeRecovery + parent: organizations/1234567890 + resource_types: + - sqladmin.googleapis.com/Instance + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequirePostgreSQLDatabaseAdditionalFlags"] + : action_type: DENY + condition: "resource.databaseVersion.startsWith('POSTGRES') && (\n !resource.settings.databaseFlags.exists(flag,\ + \ flag.name == 'log_checkpoints' && flag.value == 'on') ||\n !resource.settings.databaseFlags.exists(flag,\ + \ flag.name == 'log_executor_stats' && flag.value == 'off') ||\n !resource.settings.databaseFlags.exists(flag,\ + \ flag.name == 'log_lock_waits' && flag.value == 'on')\n)" + description: Ensure Cloud SQL for PostgreSQL instance database flags are set correctly + (e.g log_checkpoints, log_executor_stats, log_lock_waits) + display_name: Require Cloud SQL for PostgreSQL instance database flags to be configured + correctly (e.g log_checkpoints, log_executor_stats, log_lock_waits) + method_types: + - CREATE + - UPDATE + name: custom.cloudsqlRequirePostgreSQLDatabaseAdditionalFlags + parent: organizations/1234567890 + resource_types: + - sqladmin.googleapis.com/Instance + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequirePostgreSQLDatabaseFlags"]: + action_type: DENY + condition: "resource.databaseVersion.startsWith('POSTGRES') && (\n !resource.settings.databaseFlags.exists(f,\ + \ f.name == 'log_connections' && f.value == 'on') ||\n !resource.settings.databaseFlags.exists(f,\ + \ f.name == 'log_disconnections' && f.value == 'on') ||\n !resource.settings.databaseFlags.exists(f,\ + \ f.name == 'log_min_duration_statement' && f.value == '-1') ||\n !resource.settings.databaseFlags.exists(f,\ + \ f.name == 'cloudsql.enable_pgaudit' && f.value == 'on') ||\n resource.settings.databaseFlags.exists(f,\ + \ f.name == 'log_error_verbosity' && f.value == 'terse') ||\n resource.settings.databaseFlags.exists(f,\ + \ f.name == 'log_statement' && f.value == 'none') ||\n resource.settings.databaseFlags.exists(f,\n\ + \ f.name == 'log_min_messages' && f.value in ['error' , 'log', 'fatal', 'panic']\n\ + \ ) ||\n resource.settings.databaseFlags.exists(f,\n f.name == 'log_min_error_statement'\ + \ && f.value in ['log', 'fatal', 'panic']\n )\n)" + description: Ensure Cloud SQL for PostgreSQL instance database flags are set correctly + (e.g log_connections) + display_name: Require Cloud SQL for PostgreSQL instance database flags to be configured + correctly (e.g log_connections) + method_types: + - CREATE + - UPDATE + name: custom.cloudsqlRequirePostgreSQLDatabaseFlags + parent: organizations/1234567890 + resource_types: + - sqladmin.googleapis.com/Instance + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequireRootPassword"]: + action_type: DENY + condition: resource.settings.passwordValidationPolicy.minLength == 0 + description: Ensure that Cloud SQL instance is configured to use a root password + display_name: Require Cloud SQL instances to configure root password + method_types: + - CREATE + - UPDATE + name: custom.cloudsqlRequireRootPassword + parent: organizations/1234567890 + resource_types: + - sqladmin.googleapis.com/Instance + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequireSQLServerDatabaseFlags"]: + action_type: DENY + condition: "resource.databaseVersion.startsWith('SQLSERVER') && (\n resource.settings.databaseFlags.exists(flag,\n\ + \ flag.name == 'external scripts enabled' && flag.value == 'on'\n ) ||\n\ + \ resource.settings.databaseFlags.exists(flag,\n flag.name == 'cross db\ + \ ownership chaining' && flag.value == 'on'\n ) ||\n resource.settings.databaseFlags.exists(flag,\n\ + \ flag.name == 'contained database authentication' && flag.value == 'on'\n\ + \ ) ||\n resource.settings.databaseFlags.exists(flag,\n flag.name == 'user\ + \ connections' && flag.value != '0'\n ) ||\n resource.settings.databaseFlags.exists(flag,\n\ + \ flag.name == 'user options' && flag.value != '0'\n ) ||\n !resource.settings.databaseFlags.exists(flag,\n\ + \ flag.name == 'remote access' && flag.value == 'off'\n ) ||\n !resource.settings.databaseFlags.exists(flag,\n\ + \ flag.name == '3625' && flag.value == 'on'\n )\n)" + description: Ensure Cloud SQL for SQLServer instance database flags are set correctly + (e.g external scripts enabled ...) + display_name: Require Cloud SQL for SQLServer instance database flags to be configured + correctly (e.g external scripts enabled ...) + method_types: + - CREATE + - UPDATE + name: custom.cloudsqlRequireSQLServerDatabaseFlags + parent: organizations/1234567890 + resource_types: + - sqladmin.googleapis.com/Instance + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequireSSLConnection"]: + action_type: DENY + condition: resource.settings.ipConfiguration.sslMode in ['ENCRYPTED_ONLY', 'TRUSTED_CLIENT_CERTIFICATE_REQUIRED'] + == false + description: Ensure that Cloud SQL instance is configured to allow only connections + that are encrypted with SSL/TLS + display_name: Require Cloud SQL instances to allow only connections that are encrypted + with SSL/TLS + method_types: + - CREATE + - UPDATE + name: custom.cloudsqlRequireSSLConnection + parent: organizations/1234567890 + resource_types: + - sqladmin.googleapis.com/Instance + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.dataprocDisableDefaultServiceAccount"]: + action_type: DENY + condition: "has(resource.config.gceClusterConfig.serviceAccount) == false ||\n\ + \ resource.config.gceClusterConfig.serviceAccount.contains('-compute@developer.gserviceaccount.com')" + description: Enforce that the Dataproc VMs is not using default user-managed service + accounts + display_name: Disable Dataproc cluster with default service accounts + method_types: + - CREATE + - UPDATE + name: custom.dataprocDisableDefaultServiceAccount + parent: organizations/1234567890 + resource_types: + - dataproc.googleapis.com/Cluster + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.dataprocRequireDiskCmekEncryption"]: + action_type: DENY + condition: has(resource.config.encryptionConfig.gcePdKmsKeyName) == false + description: Enforce that the Dataproc cluster is created with an CMEK encryption + key. + display_name: Enable Dataproc CMEK encryption + method_types: + - CREATE + - UPDATE + name: custom.dataprocRequireDiskCmekEncryption + parent: organizations/1234567890 + resource_types: + - dataproc.googleapis.com/Cluster + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.dataprocRequireInternalIp"]: + action_type: DENY + condition: resource.config.gceClusterConfig.internalIpOnly == false + description: Enforce that the Dataproc cluster is created with Internal IPs only + display_name: Require Dataproc with internal IPs + method_types: + - CREATE + - UPDATE + name: custom.dataprocRequireInternalIp + parent: organizations/1234567890 + resource_types: + - dataproc.googleapis.com/Cluster + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.dataprocRequireKerberos"]: + action_type: DENY + condition: resource.config.securityConfig.kerberosConfig.enableKerberos == false + description: Enforce that Dataproc cluster is configured using secure mode via + Kerberos for authentication + display_name: Require Dataproc with Kerberos authentication + method_types: + - CREATE + - UPDATE + name: custom.dataprocRequireKerberos + parent: organizations/1234567890 + resource_types: + - dataproc.googleapis.com/Cluster + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.dnsAllowedSigningAlgorithms"]: + action_type: DENY + condition: "resource.visibility == 'PUBLIC' &&\nresource.dnssecConfig.state ==\ + \ 'ON' &&\nresource.dnssecConfig.defaultKeySpecs.exists(spec,\n spec.algorithm\ + \ in [\"ECDSAP256SHA256\"] == false\n)" + description: Ensure that allowed signing algorithms are used for the Key-Signing + key and Zone-Signing key in Cloud DNS DNSSEC + display_name: Require Cloud DNS DNSSEC configured to use only allowed algorithms + in Cloud DNS DNSSEC + method_types: + - CREATE + - UPDATE + name: custom.dnsAllowedSigningAlgorithms + parent: organizations/1234567890 + resource_types: + - dns.googleapis.com/ManagedZone + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.dnsRequireManageZoneDNSSEC"]: + action_type: DENY + condition: resource.visibility == "PUBLIC" && (resource.dnssecConfig.state in + ["ON", "TRANSFER"] == false) + description: Ensure that Cloud DNS DNSSEC is enabled when configuring a DNS Public + Managed Zone + display_name: Require Cloud DNS DNSSEC enabled when configuring a DNS Public Managed + Zone + method_types: + - CREATE + - UPDATE + name: custom.dnsRequireManageZoneDNSSEC + parent: organizations/1234567890 + resource_types: + - dns.googleapis.com/ManagedZone + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.dnsRequirePolicyLogging"]: + action_type: DENY + condition: resource.enableLogging != true + description: Ensure that Cloud DNS logging is enabled when configuring a DNS Policy + display_name: Require Cloud DNS logging enabled when configuring a DNS Policy + method_types: + - CREATE + - UPDATE + name: custom.dnsRequirePolicyLogging + parent: organizations/1234567890 + resource_types: + - dns.googleapis.com/Policy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallEnforcePolicyRuleLogging"]: + action_type: DENY + condition: resource.rules.exists(rule, rule.action != 'goto_next' && rule.enableLogging + == false) + description: Ensure that Firewall Policy rules have logging enabled + display_name: Require Firewall Policy rules to have logging enabled + method_types: + - CREATE + - UPDATE + name: custom.firewallEnforcePolicyRuleLogging + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/FirewallPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallEnforceRuleLogging"]: + action_type: DENY + condition: "(\n (has(resource.logConfig) == false || resource.logConfig.enable\ + \ == false) &&\n !resource.name.startsWith(\"gke-\") &&\n !resource.name.startsWith(\"\ + k8s-\") &&\n !resource.name.endsWith(\"-hc\") &&\n !resource.name.startsWith(\"\ + k8s2-\") &&\n !resource.name.startsWith(\"gkegw1-l7-\") &&\n !resource.name.startsWith(\"\ + gkemcg1-l7-\")\n)" + description: Ensure that VPC Firewall rules have logging enabled + display_name: Require VPC Firewall rules to have logging enabled + method_types: + - CREATE + - UPDATE + name: custom.firewallEnforceRuleLogging + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/Firewall + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRequireDescription"]: + action_type: DENY + condition: "(\n resource.description == \"\" &&\n !resource.name.startsWith(\"\ + gke-\") &&\n !resource.name.startsWith(\"k8s-\") &&\n !resource.name.endsWith(\"\ + -hc\") &&\n !resource.name.startsWith(\"k8s2-\") &&\n !resource.name.startsWith(\"\ + gkegw1-l7-\") &&\n !resource.name.startsWith(\"gkemcg1-l7-\")\n)" + description: Prevent the creation of VPC firewall rule that does not have description + provided. Description can be used for auditing to refer to security control + display_name: Require description on Firewall rule + method_types: + - CREATE + name: custom.firewallRequireDescription + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/Firewall + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictCacheSearchDatabasesPolicyRule"] + : action_type: DENY + condition: "resource.rules.exists(r, r.priority < 2147483644 && r.direction ==\ + \ 'INGRESS' &&\n r.match.srcIpRanges.exists(r, r == '0.0.0.0/0') &&\n (\n\ + \ r.match.layer4Configs.containsIpProtocolAndPort('tcp', '6379') ||\n \ + \ r.match.layer4Configs.containsIpProtocolAndPort('udp', '6379') ||\n r.match.layer4Configs.containsIpProtocolAndPort('tcp',\ + \ '9200') ||\n r.match.layer4Configs.containsIpProtocolAndPort('udp', '9200')\ + \ ||\n r.match.layer4Configs.containsIpProtocolAndPort('tcp', '9300') ||\n\ + \ r.match.layer4Configs.containsIpProtocolAndPort('udp', '9300') ||\n \ + \ r.match.layer4Configs.containsIpProtocolAndPort('tcp', '11211') ||\n r.match.layer4Configs.containsIpProtocolAndPort('udp',\ + \ '11211') ||\n r.match.layer4Configs.containsIpProtocolAndPort('tcp', '11214')\ + \ ||\n r.match.layer4Configs.containsIpProtocolAndPort('udp', '11214') ||\n\ + \ r.match.layer4Configs.containsIpProtocolAndPort('tcp', '11215') ||\n \ + \ r.match.layer4Configs.containsIpProtocolAndPort('udp', '11215')\n )\n)" + description: Ensure that cache and search database ports (Elasticsearch, Memcached, + Redis) are not accessible from any source when using Firewall Policy Rule + display_name: Restrict Firewall Policy rules allowing cache/search database port + access from any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictCacheSearchDatabasesPolicyRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/FirewallPolicy + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictCacheSearchDatabasesRule"] + : action_type: DENY + condition: "resource.direction.matches('INGRESS') &&\n resource.sourceRanges.exists(range,\ + \ range == '0.0.0.0/0') &&\n (\n resource.allowed.containsFirewallPort('tcp',\ + \ '9200') ||\n resource.allowed.containsFirewallPort('tcp', '9300') ||\n\ + \ resource.allowed.containsFirewallPort('tcp', '11211') ||\n resource.allowed.containsFirewallPort('tcp',\ + \ '11214') ||\n resource.allowed.containsFirewallPort('tcp', '11215') ||\n\ + \ resource.allowed.containsFirewallPort('tcp', '6379') ||\n resource.allowed.containsFirewallPort('udp',\ + \ '11211') ||\n resource.allowed.containsFirewallPort('udp', '11214') ||\n\ + \ resource.allowed.containsFirewallPort('udp', '11215')\n )" + description: Ensure that cache and search database ports (Elasticsearch, Memcached, + Redis) are not accessible from any source when using VPC Firewall Rule. + display_name: Restrict VPC Firewall rules allowing cache/search database port + access from any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictCacheSearchDatabasesRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/Firewall + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictDirectoryServicesPolicyRule"] + : action_type: DENY + condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n rule.direction\ + \ == 'INGRESS' &&\n rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0')\ + \ &&\n (\n rule.match.layer4Configs.containsIpProtocolAndPort('udp', '445')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('udp', '389') ||\n\ + \ rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '445') ||\n \ + \ rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '389') ||\n \ + \ rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '636')\n )\n)" + description: Ensure that directory and authentication services (SMB/CIFS, LDAP) + are not accessible from the Internet when using Firewall Policy Rule + display_name: Restrict Firewall Policy rules allowing directory service access + from any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictDirectoryServicesPolicyRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/FirewallPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictDirectoryServicesRule"]: + action_type: DENY + condition: "resource.direction.matches('INGRESS') &&\n resource.sourceRanges.exists(range,\ + \ range == '0.0.0.0/0') &&\n (\n resource.allowed.containsFirewallPort('tcp',\ + \ '445') ||\n resource.allowed.containsFirewallPort('tcp', '389') ||\n \ + \ resource.allowed.containsFirewallPort('tcp', '636') ||\n resource.allowed.containsFirewallPort('udp',\ + \ '445') ||\n resource.allowed.containsFirewallPort('udp', '389')\n )" + description: Ensure that directory and authentication services (SMB/CIFS, LDAP) + are not accessible from the Internet when using VPC Firewall Rule + display_name: Restrict VPC Firewall rules allowing directory service access from + any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictDirectoryServicesRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/Firewall + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictExplicitAllPortsPolicyRule"] + : action_type: DENY + condition: "resource.rules.exists(rule,\n rule.action == 'allow' &&\n rule.priority\ + \ < 2147483644 &&\n rule.direction == 'INGRESS' &&\n rule.match.layer4Configs.exists(l4,\n\ + \ l4.ipProtocol in ['tcp', 'udp'] && (\n !has(l4.ports) ||\n '0-65535'\ + \ in l4.ports ||\n '1-65535' in l4.ports\n )\n )\n)" + description: Prevent Firewall Policy rules that explicitly specify all TCP/UDP + ports using ranges like 0-65535 or 1-65535 + display_name: Restrict Firewall Policy rules with explicit all-ports specifications + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictExplicitAllPortsPolicyRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/FirewallPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictExplicitAllPortsRule"]: + action_type: DENY + condition: "resource.direction == 'INGRESS' &&\nresource.allowed.exists(rule,\n\ + \ rule.IPProtocol in ['tcp', 'udp'] && (\n !has(rule.ports) ||\n '0-65535'\ + \ in rule.ports ||\n '1-65535' in rule.ports\n )\n) &&\n!resource.name.startsWith('gke-')\ + \ &&\n!resource.name.startsWith('k8s-') &&\n!resource.name.endsWith('-hc') &&\n\ + !resource.name.startsWith('k8s2-') &&\n!resource.name.startsWith('gkegw1-l7-')\ + \ &&\n!resource.name.startsWith('gkemcg1-l7-')" + description: Prevent VPC firewall rules that explicitly specify all TCP/UDP ports + using ranges like 0-65535 or 1-65535 + display_name: Restrict VPC Firewall rules with explicit all-ports specifications + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictExplicitAllPortsRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/Firewall + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictInsecureProtocolsPolicyRule"] + : action_type: DENY + condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n rule.direction\ + \ == 'INGRESS' &&\n rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0')\ + \ &&\n (\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '21')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '23') ||\n\ + \ rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '80')\n )\n)" + description: Ensure that insecure legacy protocols (Telnet, FTP, HTTP) are not + accessible from any source when using Firewall Policy Rule + display_name: Restrict Firewall Policy rules allowing insecure protocol access + from any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictInsecureProtocolsPolicyRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/FirewallPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictInsecureProtocolsRule"]: + action_type: DENY + condition: "resource.direction.matches('INGRESS') &&\n resource.sourceRanges.exists(range,\ + \ range == '0.0.0.0/0') &&\n (\n resource.allowed.containsFirewallPort('tcp',\ + \ '21') ||\n resource.allowed.containsFirewallPort('tcp', '23') ||\n resource.allowed.containsFirewallPort('tcp',\ + \ '80')\n )" + description: Ensure that insecure legacy protocols (Telnet, FTP, HTTP) are not + accessible from any source when using VPC Firewall Rule + display_name: Restrict VPC Firewall rules allowing insecure protocol access from + any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictInsecureProtocolsRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/Firewall + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictMailProtocolsPolicyRule"] + : action_type: DENY + condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n rule.direction\ + \ == 'INGRESS' &&\n rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0')\ + \ &&\n (\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '25')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '110')\n\ + \ )\n)" + description: Ensure that mail protocols (SMTP, POP3) are not accessible from any + source when using Firewall Policy Rule + display_name: Restrict Firewall Policy rules allowing mail protocol access from + any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictMailProtocolsPolicyRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/FirewallPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictMailProtocolsRule"]: + action_type: DENY + condition: "resource.direction.matches('INGRESS') &&\n resource.sourceRanges.exists(range,\ + \ range == '0.0.0.0/0') &&\n (\n resource.allowed.containsFirewallPort('tcp',\ + \ '25') ||\n resource.allowed.containsFirewallPort('tcp', '110')\n )" + description: Ensure that mail protocols (SMTP, POP3) are not accessible from any + source when using VPC Firewall Rule + display_name: Restrict VPC Firewall rules allowing mail protocol access from any + source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictMailProtocolsRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/Firewall + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictManagementPortsPolicyRule"] + : action_type: DENY + condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n rule.direction\ + \ == 'INGRESS' &&\n rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0')\ + \ &&\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '9090')\n)" + description: Ensure that management interfaces (Cisco Secure WebSM) are not accessible + from any source when using Firewall Policy Rule + display_name: Restrict Firewall Policy rules allowing management port access from + any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictManagementPortsPolicyRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/FirewallPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictManagementPortsRule"]: + action_type: DENY + condition: "resource.direction.matches('INGRESS') &&\n resource.sourceRanges.exists(range,\ + \ range == '0.0.0.0/0') &&\n resource.allowed.containsFirewallPort('tcp', '9090')" + description: Ensure that management interfaces (Cisco Secure WebSM) are not accessible + from any source when using VPC Firewall Rule + display_name: Restrict VPC Firewall rules allowing management port access from + any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictManagementPortsRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/Firewall + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictNetworkServicesPolicyRule"] + : action_type: DENY + condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n rule.direction\ + \ == 'INGRESS' &&\n rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0')\ + \ &&\n (\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '53')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('udp', '53') ||\n\ + \ rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '137') ||\n \ + \ rule.match.layer4Configs.containsIpProtocolAndPort('udp', '137') ||\n \ + \ rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '138') ||\n \ + \ rule.match.layer4Configs.containsIpProtocolAndPort('udp', '138') ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp',\ + \ '139') ||\n rule.match.layer4Configs.containsIpProtocolAndPort('udp', '139')\n\ + \ )\n)" + description: Ensure that network infrastructure services (DNS, NetBIOS) are not + accessible from any source when using Firewall Policy Rule + display_name: Restrict Firewall Policy rules allowing network service access from + any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictNetworkServicesPolicyRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/FirewallPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictNetworkServicesRule"]: + action_type: DENY + condition: "resource.direction.matches('INGRESS') &&\n resource.sourceRanges.exists(range,\ + \ range == '0.0.0.0/0') &&\n (\n resource.allowed.containsFirewallPort('tcp',\ + \ '53') ||\n resource.allowed.containsFirewallPort('udp', '53') ||\n resource.allowed.containsFirewallPort('tcp',\ + \ '137') ||\n resource.allowed.containsFirewallPort('udp', '137') ||\n \ + \ resource.allowed.containsFirewallPort('tcp', '138') ||\n resource.allowed.containsFirewallPort('udp',\ + \ '138') ||\n resource.allowed.containsFirewallPort('tcp', '139') ||\n \ + \ resource.allowed.containsFirewallPort('udp', '139')\n )" + description: Ensure that network infrastructure services (DNS, NetBIOS) are not + accessible from any source when using VPC Firewall Rule + display_name: Restrict VPC Firewall rules allowing network service access from + any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictNetworkServicesRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/Firewall + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictNoSQLDatabasesPolicyRule"] + : action_type: DENY + condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n rule.direction\ + \ == 'INGRESS' &&\n rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0')\ + \ &&\n (\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '7000')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '7001')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '7199')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '8888')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '9042')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '9160')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '61620')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '61621')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '27017')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '27018')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '27019')\n\ + \ )\n)" + description: Ensure that NoSQL database ports (Cassandra, MongoDB) are not accessible + from any source when using Firewall Policy Rule + display_name: Restrict Firewall Policy rules allowing NoSQL database port access + from any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictNoSQLDatabasesPolicyRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/FirewallPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictNoSQLDatabasesRule"]: + action_type: DENY + condition: "resource.direction.matches('INGRESS') &&\n resource.sourceRanges.exists(range,\ + \ range == '0.0.0.0/0') &&\n (\n resource.allowed.containsFirewallPort('tcp',\ + \ '7000') ||\n resource.allowed.containsFirewallPort('tcp', '7001') ||\n\ + \ resource.allowed.containsFirewallPort('tcp', '7199') ||\n resource.allowed.containsFirewallPort('tcp',\ + \ '8888') ||\n resource.allowed.containsFirewallPort('tcp', '9042') ||\n\ + \ resource.allowed.containsFirewallPort('tcp', '9160') ||\n resource.allowed.containsFirewallPort('tcp',\ + \ '61620') ||\n resource.allowed.containsFirewallPort('tcp', '61621') ||\n\ + \ resource.allowed.containsFirewallPort('tcp', '27017') ||\n resource.allowed.containsFirewallPort('tcp',\ + \ '27018') ||\n resource.allowed.containsFirewallPort('tcp', '27019')\n \ + \ )" + description: Ensure that NoSQL database ports (Cassandra, MongoDB) are not accessible + from any source when using Firewall Policy Rule + display_name: Restrict VPC Firewall rules allowing NoSQL database port access + from any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictNoSQLDatabasesRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/Firewall + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictPublicAccessPolicyRule"]: + action_type: DENY + condition: "resource.rules.exists(rule,\n rule.action == 'allow' &&\n rule.priority\ + \ < 2147483644 &&\n rule.direction == 'INGRESS' &&\n rule.match.srcIpRanges.exists(range,\ + \ range == '0.0.0.0/0') &&\n !rule.match.layer4Configs.exists(l4,\n l4.ipProtocol\ + \ == 'icmp'\n )\n)" + description: Prevent Firewall Policy ingress rules from 0.0.0.0/0 except for allowed + protocols (ICMP) + display_name: Restrict Firewall Policy ingress rules allowing public Internet + access + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictPublicAccessPolicyRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/FirewallPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictPublicAccessRule"]: + action_type: DENY + condition: "resource.direction == 'INGRESS' &&\nsize(resource.allowed) > 0 &&\n\ + resource.sourceRanges.exists(r, r == '0.0.0.0/0') &&\n!resource.allowed.exists(a,\n\ + \ a.IPProtocol == 'icmp'\n)" + description: Prevent VPC Firewall ingress rules from 0.0.0.0/0 except for allowed + protocols (ICMP). + display_name: Restrict VPC Firewall ingress rules allowing public Internet access + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictPublicAccessRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/Firewall + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictRdpPolicyRule"]: + action_type: DENY + condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n \ + \ rule.direction == 'INGRESS' &&\n !rule.match.srcIpRanges.all(ipRange,\n\ + \ ipRange == '35.235.240.0/20' ||\n ipRange.startsWith('192.168.')\ + \ ||\n ipRange.matches('^172\\\\.(?:1[6-9]|2\\\\d|3[0-1]).*') ||\n \ + \ ipRange.startsWith('10.')\n ) &&\n rule.match.layer4Configs.all(l4config,\n\ + \ l4config.ipProtocol == 'tcp' &&\n l4config.ports.all(port, port\ + \ == '3389')\n )\n)" + description: Ensure that RDP access is restricted from any source when using Firewall + Policy Rule + display_name: Restrict Firewall Policy rules allowing RDP access from any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictRdpPolicyRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/FirewallPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictRdpRule"]: + action_type: DENY + condition: "resource.direction.matches('INGRESS') &&\n!resource.name.startsWith('gke-')\ + \ &&\n!resource.name.startsWith('k8s-') &&\n!resource.name.endsWith('-hc') &&\n\ + !resource.name.startsWith('k8s2-') &&\n!resource.name.startsWith('gkegw1-l7-')\ + \ &&\n!resource.name.startsWith('gkemcg1-l7-') &&\nresource.allowed.containsFirewallPort('tcp',\ + \ '3389') &&\n!resource.sourceRanges.all(range,\n range == '35.235.240.0/20'\ + \ ||\n range.startsWith('10.') ||\n range.matches('^172\\\\.(?:1[6-9]|2\\\\\ + d|3[0-1]).*') ||\n range.startsWith('192.168.')\n)" + description: Ensure that RDP access is restricted from any source when using VPC + Firewall Rule + display_name: Restrict VPC Firewall rules allowing RDP access from any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictRdpRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/Firewall + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictSQLDatabasesPolicyRule"]: + action_type: DENY + condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n rule.direction\ + \ == 'INGRESS' &&\n rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0')\ + \ &&\n (\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '3306')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '1521')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '2483')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '2484')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '5432')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('udp', '2483')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('udp', '2484')\ + \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('udp', '5432')\n\ + \ )\n)" + description: Ensure that SQL database ports (MySQL, Oracle, PostgreSQL) are not + accessible from any source when using Firewall Policy Rule + display_name: Restrict Firewall Policy rules allowing SQL database port access + from any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictSQLDatabasesPolicyRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/FirewallPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictSQLDatabasesRule"]: + action_type: DENY + condition: "resource.direction.matches('INGRESS') &&\n resource.sourceRanges.exists(range,\ + \ range == '0.0.0.0/0') &&\n (\n resource.allowed.containsFirewallPort('tcp',\ + \ '3306') ||\n resource.allowed.containsFirewallPort('tcp', '1521') ||\n\ + \ resource.allowed.containsFirewallPort('tcp', '2483') ||\n resource.allowed.containsFirewallPort('tcp',\ + \ '2484') ||\n resource.allowed.containsFirewallPort('tcp', '5432') ||\n\ + \ resource.allowed.containsFirewallPort('udp', '2483') ||\n resource.allowed.containsFirewallPort('udp',\ + \ '2484') ||\n resource.allowed.containsFirewallPort('udp', '5432')\n )" + description: Ensure that SQL database ports (MySQL, Oracle, PostgreSQL) are not + accessible from any source when using VPC Firewall Rule + display_name: Restrict VPC Firewall rules allowing SQL database port access from + any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictSQLDatabasesRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/Firewall + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictSshPolicyRule"]: + action_type: DENY + condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n \ + \ rule.direction == 'INGRESS' &&\n !rule.match.srcIpRanges.all(ipRange,\n\ + \ ipRange == '35.235.240.0/20' ||\n ipRange.startsWith('192.168.')\ + \ ||\n ipRange.matches('^172\\\\.(?:1[6-9]|2\\\\d|3[0-1]).*') ||\n \ + \ ipRange.startsWith('10.')\n ) &&\n rule.match.layer4Configs.all(l4config,\n\ + \ l4config.ipProtocol == 'tcp' &&\n l4config.ports.all(port, port\ + \ == '22')\n )\n)" + description: Ensure that SSH access is restricted from any source when using Firewall + Policy Rule + display_name: Restrict Firewall Policy rules allowing SSH access from any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictSshPolicyRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/FirewallPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictSshRule"]: + action_type: DENY + condition: "resource.direction.matches('INGRESS') &&\n!resource.name.startsWith('gke-')\ + \ &&\n!resource.name.startsWith('k8s-') &&\n!resource.name.endsWith('-hc') &&\n\ + !resource.name.startsWith('k8s2-') &&\n!resource.name.startsWith('gkegw1-l7-')\ + \ &&\n!resource.name.startsWith('gkemcg1-l7-') &&\nresource.allowed.containsFirewallPort('tcp',\ + \ '22') &&\n!resource.sourceRanges.all(range,\n range == '35.235.240.0/20'\ + \ ||\n range.startsWith('10.') ||\n range.matches('^172\\\\.(?:1[6-9]|2\\\\\ + d|3[0-1]).*') ||\n range.startsWith('192.168.')\n)" + description: Ensure that SSH access is restricted from any source when using VPC + Firewall Rule + display_name: Restrict VPC Firewall rules allowing SSH access from any source + method_types: + - CREATE + - UPDATE + name: custom.firewallRestrictSshRule + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/Firewall + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeAllowedNodePoolImages"]: + action_type: DENY + condition: resource.config.imageType in ["COS_CONTAINERD"] == false + description: Enforce that GKE nodes are using authorized node images + display_name: Allow only authorized node pool images + method_types: + - CREATE + - UPDATE + name: custom.gkeAllowedNodePoolImages + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/NodePool + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeAllowedReleaseChannels"]: + action_type: DENY + condition: resource.releaseChannel.channel in ["REGULAR", "STABLE"] == false + description: Enforce that GKE cluster are using authorized release channels + display_name: Allow only authorized release channels + method_types: + - CREATE + - UPDATE + name: custom.gkeAllowedReleaseChannels + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/Cluster + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeDisableAlphaCluster"]: + action_type: DENY + condition: resource.enableKubernetesAlpha == true + description: Enforce that GKE clusters are not using alpha features for production + workloads + display_name: Disable alpha features for production workloads + method_types: + - CREATE + - UPDATE + name: custom.gkeDisableAlphaCluster + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/Cluster + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeDisableKubernetesDashboard"]: + action_type: DENY + condition: resource.addonsConfig.kubernetesDashboard.disabled == false + description: Enforce that GKE clusters does not have Web UI dashboard enabled + display_name: Disable Web UI dashboard + method_types: + - CREATE + - UPDATE + name: custom.gkeDisableKubernetesDashboard + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/Cluster + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeDisableLegacyAbac"]: + action_type: DENY + condition: resource.legacyAbac.enabled == true + description: Enforce that GKE clusters is configured with no legacy ABAC enabled + display_name: Disable legacy ABAC + method_types: + - CREATE + - UPDATE + name: custom.gkeDisableLegacyAbac + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/Cluster + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeDisableLegacyMetadataEndpoints"]: + action_type: DENY + condition: '(''disable-legacy-endpoints'' in resource.config.metadata && + + resource.config.metadata[''disable-legacy-endpoints''] == ''false'')' + description: Enforce that GKE clusters are created with legacy metadata endpoints + disabled + display_name: Disable legacy metadata endpoints + method_types: + - CREATE + - UPDATE + name: custom.gkeDisableLegacyMetadataEndpoints + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/NodePool + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireCOSImage"]: + action_type: DENY + condition: resource.config.imageType != "COS_CONTAINERD" + description: Enforce the nodes pool are using Container-Optimized OS for running + containers + display_name: Require Container-Optimized OS on node pools + method_types: + - CREATE + - UPDATE + name: custom.gkeRequireCOSImage + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/NodePool + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireConfidentialNodes"]: + action_type: DENY + condition: resource.confidentialNodes.enabled == false + description: Enforce that the GKE clusters is using confidential nodes + display_name: Require confidential nodes + method_types: + - CREATE + - UPDATE + name: custom.gkeRequireConfidentialNodes + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/Cluster + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireDataplaneV2"]: + action_type: DENY + condition: resource.networkConfig.datapathProvider != 'ADVANCED_DATAPATH' + description: Enforce that the GKE clusters is configured to use dataplane v2 + display_name: Require dataplane v2 + method_types: + - CREATE + - UPDATE + name: custom.gkeRequireDataplaneV2 + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/Cluster + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireGKEMetadataServer"]: + action_type: DENY + condition: resource.config.workloadMetadataConfig.mode != 'GKE_METADATA' + description: Enforce that GKE clusters are configured with GKE metadata server + enabled + display_name: Require GKE metadata server + method_types: + - CREATE + - UPDATE + name: custom.gkeRequireGKEMetadataServer + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/NodePool + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireIntegrityMonitoring"]: + action_type: DENY + condition: resource.config.shieldedInstanceConfig.enableIntegrityMonitoring == + false + description: Enforce that GKE nodes are configured with integrity monitoring enabled + display_name: Enable integrity monitoring + method_types: + - CREATE + - UPDATE + name: custom.gkeRequireIntegrityMonitoring + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/NodePool + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireIntraNodeVisibility"]: + action_type: DENY + condition: resource.networkConfig.enableIntraNodeVisibility == false + description: Enforce that GKE clusters intranode visibility is enabled + display_name: Enable intranode visibility + method_types: + - CREATE + - UPDATE + name: custom.gkeRequireIntraNodeVisibility + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/Cluster + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireMasterAuthorizedNetworks"]: + action_type: DENY + condition: resource.masterAuthorizedNetworksConfig.enabled == false + description: Enforce that GKE clusters restrict network access to the control + planes by configuring master authorized networks with authorized CIDR IP ranges + display_name: Require master authorized network with authorized CIDR IP ranges + method_types: + - CREATE + - UPDATE + name: custom.gkeRequireMasterAuthorizedNetworks + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/Cluster + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireMonitoring"]: + action_type: DENY + condition: resource.monitoringService != 'monitoring.googleapis.com/kubernetes' + description: Enforce that GKE clusters monitoring is enabled + display_name: Enable monitoring + method_types: + - CREATE + - UPDATE + name: custom.gkeRequireMonitoring + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/Cluster + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireNodePoolAutoRepair"]: + action_type: DENY + condition: resource.management.autoRepair == false + description: Enforce that GKE clusters are configured with node auto-repair enabled + display_name: Enable node auto-repair + method_types: + - CREATE + - UPDATE + name: custom.gkeRequireNodePoolAutoRepair + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/NodePool + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireNodePoolAutoUpgrade"]: + action_type: DENY + condition: resource.management.autoUpgrade == false + description: Enforce that GKE clusters are configured with node auto-upgrade enabled + display_name: Enable node auto-upgrade + method_types: + - CREATE + - UPDATE + name: custom.gkeRequireNodePoolAutoUpgrade + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/NodePool + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireNodePoolCMEKEncryption"]: + action_type: DENY + condition: has(resource.config.bootDiskKmsKey) == false + description: Enforce that GKE nodes are configured with CMEK Encryption + display_name: Require NodePool CMEK Encryption + method_types: + - CREATE + - UPDATE + name: custom.gkeRequireNodePoolCMEKEncryption + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/NodePool + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireNodePoolSandbox"]: + action_type: DENY + condition: "resource.name.matches(\"default-pool\") == false &&\n has(resource.config.sandboxConfig)\ + \ == false &&\n resource.config.sandboxConfig.type != 'GVISOR'" + description: Enforce that the GKE clusters nodes are isolated using GKE sandbox + (excepting the default node pool) + display_name: Require GKE Sandbox runtime + method_types: + - CREATE + - UPDATE + name: custom.gkeRequireNodePoolSandbox + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/NodePool + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeRequirePrivateEndpoint"]: + action_type: DENY + condition: resource.privateClusterConfig.enablePrivateEndpoint == false + description: Enforce that GKE clusters are created as private clusters with public + endpoint disabled + display_name: Disable public endpoints + method_types: + - CREATE + - UPDATE + name: custom.gkeRequirePrivateEndpoint + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/Cluster + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireRegionalClusters"]: + action_type: DENY + condition: resource.location.matches("^[a-z]+(-[a-z, 1-9]+)$") == false + description: Enforce the creation of regional GKE clusters + display_name: Require regional GKE cluster + method_types: + - CREATE + - UPDATE + name: custom.gkeRequireRegionalClusters + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/Cluster + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireSecureBoot"]: + action_type: DENY + condition: resource.config.shieldedInstanceConfig.enableSecureBoot == false + description: Enforce that GKE nodes are configured with secure boot enabled + display_name: Enable secure boot + method_types: + - CREATE + - UPDATE + name: custom.gkeRequireSecureBoot + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/NodePool + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireVPCNativeCluster"]: + action_type: DENY + condition: resource.ipAllocationPolicy.useIpAliases == false + description: Enforce that GKE clusters are created with VPC-native + display_name: Require VPC-native + method_types: + - CREATE + - UPDATE + name: custom.gkeRequireVPCNativeCluster + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/Cluster + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.iamAllowedMembers"]: + action_type: DENY + condition: "resource.bindings.exists(binding,\n binding.members.exists(member,\n\ + \ MemberSubjectStartsWith(member, ['user:', 'group:']) &&\n !MemberSubjectEndsWith(member,\ + \ ['@example.org', 'group:fabric-fast-owners@google.com'])\n )\n)" + description: Ensure no binding are done with members outside the organization + domain + display_name: Deny principals and members outside the organization domain + method_types: + - CREATE + - UPDATE + name: custom.iamAllowedMembers + parent: organizations/1234567890 + resource_types: + - iam.googleapis.com/AllowPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.iamDisableAdminServiceAccount"]: + action_type: DENY + condition: "resource.bindings.exists(binding,\n binding.members.exists(member,\n\ + \ !MemberSubjectEndsWith(member, ['@cloudservices.gserviceaccount.com'])\ + \ &&\n MemberSubjectStartsWith(member, ['serviceAccount:']) &&\n !MemberSubjectEndsWith(member,\ + \ ['@ft0-prod-iac-core-0.iam.gserviceaccount.com'])\n ) &&\n (\n RoleNameMatches(binding.role,\ + \ ['roles/owner', 'roles/admin']) ||\n RoleNameMatches(binding.role, ['roles/editor',\ + \ 'roles/writer']) ||\n RoleNameContains(binding.role, ['admin', 'Admin'])\n\ + \ )\n)" + description: Ensure no use of the legacy basic roles (owner and editor), basic + roles (admin, writer) and usage of admin roles for service account + display_name: Deny use of the legacy basic roles, basic roles and usage of admin + role for service account + method_types: + - CREATE + - UPDATE + name: custom.iamDisableAdminServiceAccount + parent: organizations/1234567890 + resource_types: + - iam.googleapis.com/AllowPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.iamDisableBasicRoles"]: + action_type: DENY + condition: "resource.bindings.exists(binding,\n binding.members.exists(member,\n\ + \ MemberSubjectStartsWith(member, ['user:', 'group:']) &&\n !MemberSubjectStartsWith(member,\ + \ ['group:fabric-fast-owners@google.com']) &&\n (\n RoleNameMatches(binding.role,\ + \ ['roles/owner', 'roles/admin']) ||\n RoleNameMatches(binding.role, ['roles/editor',\ + \ 'roles/writer']) ||\n RoleNameContains(binding.role, ['roles/viewer',\ + \ 'roles/reader'])\n )\n )\n)" + description: Ensure no use of the legacy basic roles (viewer, editor and owner) + and basic roles (reader, writer and admin) + display_name: Deny use of the basic roles + method_types: + - CREATE + - UPDATE + name: custom.iamDisableBasicRoles + parent: organizations/1234567890 + resource_types: + - iam.googleapis.com/AllowPolicy + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.iamDisableProjectServiceAccountImpersonationRoles"] + : action_type: DENY + condition: "resource.bindings.exists(binding,\n binding.members.exists(member,\n\ + \ MemberSubjectStartsWith(member, ['user:', 'group:']) &&\n !MemberSubjectStartsWith(member,\ + \ ['group:fabric-fast-owners@google.com'])\n ) &&\n (\n RoleNameMatches(binding.role,\ + \ ['roles/iam.serviceAccountUser']) ||\n RoleNameMatches(binding.role, ['roles/iam.serviceAccountTokenCreator'])\n\ + \ )\n)" + description: Ensure that IAM Users are not assigned the service account user or + service account token creator roles (requires usage of IAM Condition and tags + to ensure the constraint is not applied on allowed service accounts) + display_name: Deny assignment of the service account user or service account token + creator roles to users + method_types: + - CREATE + - UPDATE + name: custom.iamDisableProjectServiceAccountImpersonationRoles + parent: organizations/1234567890 + resource_types: + - iam.googleapis.com/AllowPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.iamDisablePublicBindings"]: + action_type: DENY + condition: "resource.bindings.exists(binding,\n binding.members.exists(member,\n\ + \ MemberSubjectMatches(member, ['allUsers', 'allAuthenticatedUsers'])\n \ + \ )\n)" + description: Ensure no use of public bindings (allUsers, allAuthenticatedUsers) + display_name: Deny use of public access bindings with allUsers or allAuthenticatedUsers + method_types: + - CREATE + - UPDATE + name: custom.iamDisablePublicBindings + parent: organizations/1234567890 + resource_types: + - iam.googleapis.com/AllowPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.iamDisableRedisAdminRoles"]: + action_type: DENY + condition: "resource.bindings.exists(binding,\n binding.members.exists(member,\n\ + \ !MemberSubjectMatches(member, []) &&\n (\n RoleNameMatches(binding.role,\ + \ ['roles/redis.admin']) ||\n RoleNameMatches(binding.role, ['roles/redis.editor'])\ + \ ||\n RoleNameContains(binding.role, ['roles/redis.viewer'])\n )\n\ + \ )\n)" + description: Ensure no use of the basic roles (viewer, editor and owner) + display_name: Deny use of the basic roles + method_types: + - CREATE + - UPDATE + name: custom.iamDisableRedisAdminRoles + parent: organizations/1234567890 + resource_types: + - iam.googleapis.com/AllowPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.networkDisableTargetHTTPProxy"]: + action_type: DENY + condition: true == true + description: Ensure Target HTTP Proxy are not used + display_name: Deny usage and creation of Target HTTP Proxy + method_types: + - CREATE + - UPDATE + name: custom.networkDisableTargetHTTPProxy + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/TargetHttpProxy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.networkDisableWeakSSLPolicy"]: + action_type: DENY + condition: "(resource.profile == \"COMPATIBLE\") || (resource.profile == \"CUSTOM\"\ + \ &&\n resource.customFeatures.exists(feature, feature in [\n \"TLS_RSA_WITH_AES_128_GCM_SHA256\"\ + ,\n \"TLS_RSA_WITH_AES_256_GCM_SHA384\",\n \"TLS_RSA_WITH_AES_128_CBC_SHA\"\ + ,\n \"TLS_RSA_WITH_AES_256_CBC_SHA\",\n \"TLS_RSA_WITH_3DES_EDE_CBC_SHA\"\ + ,\n ])\n) || (resource.profile == \"CUSTOM\" &&\n resource.minTlsVersion in\ + \ [\"TLS_1_2\", \"TLS_1_3\"] == false\n) || (resource.profile == \"MODERN\"\ + \ &&\n resource.minTlsVersion in [\"TLS_1_2\", \"TLS_1_3\"] == false\n) ||\ + \ (resource.profile == \"RESTRICTED\" &&\n resource.minTlsVersion in [\"TLS_1_2\"\ + , \"TLS_1_3\"] == false\n)" + description: Ensure SSL Policies created does not have weak cipher suites + display_name: Deny usage of SSL Policies with weak cipher suites + method_types: + - CREATE + - UPDATE + name: custom.networkDisableWeakSSLPolicy + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/SslPolicy + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.networkRequireBackendServiceLogging"]: + action_type: DENY + condition: has(resource.logConfig) == false || resource.logConfig.enable == false + description: Enforce that Backend Services have logging enabled + display_name: Require logging to be enabled on Backend Services + method_types: + - CREATE + - UPDATE + name: custom.networkRequireBackendServiceLogging + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/BackendService + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.networkRequireCustomModeVpc"]: + action_type: DENY + condition: resource.autoCreateSubnetworks == true + description: Enforce that the subnets creation is using custom mode for a VPC + network + display_name: Require custom mode VPC network + method_types: + - CREATE + name: custom.networkRequireCustomModeVpc + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/Network + timeouts: null + ? module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.networkRequireSubnetPrivateGoogleAccess"] + : action_type: DENY + condition: '!resource.privateIpGoogleAccess && resource.purpose in [''REGIONAL_MANAGED_PROXY'', + ''GLOBAL_MANAGED_PROXY''] == false' + description: Enforce that the VPC network subnets are configured with private + Google access + display_name: Require Private Google Access + method_types: + - CREATE + name: custom.networkRequireSubnetPrivateGoogleAccess + parent: organizations/1234567890 + resource_types: + - compute.googleapis.com/Subnetwork + timeouts: null + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.storageRequireBucketObjectVersionning"]: + action_type: DENY + condition: resource.versioning.enabled == false + description: Enforce Cloud Storage bucket object versioning to be configured + display_name: Require object versioning + method_types: + - CREATE + - UPDATE + name: custom.storageRequireBucketObjectVersionning + parent: organizations/1234567890 + resource_types: + - storage.googleapis.com/Bucket + timeouts: null module.organization-iam[0].google_org_policy_policy.default["ainotebooks.disableFileDownloads"]: dry_run_spec: [] name: organizations/1234567890/policies/ainotebooks.disableFileDownloads @@ -3252,6 +4737,21 @@ values: parameters: null values: [] timeouts: null + module.organization-iam[0].google_org_policy_policy.default["container.managed.enableSecretsEncryption"]: + dry_run_spec: [] + name: organizations/1234567890/policies/container.managed.enableSecretsEncryption + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + timeouts: null module.organization-iam[0].google_org_policy_policy.default["container.managed.enableSecurityBulletinNotifications"]: dry_run_spec: [] name: organizations/1234567890/policies/container.managed.enableSecurityBulletinNotifications @@ -3327,6 +4827,21 @@ values: parameters: null values: [] timeouts: null + module.organization-iam[0].google_org_policy_policy.default["custom.cloudkmsAllowedAlgorithms"]: + dry_run_spec: [] + name: organizations/1234567890/policies/custom.cloudkmsAllowedAlgorithms + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + timeouts: null module.organization-iam[0].google_org_policy_policy.default["custom.cloudkmsAllowedProtectionLevel"]: dry_run_spec: [] name: organizations/1234567890/policies/custom.cloudkmsAllowedProtectionLevel @@ -3342,6 +4857,21 @@ values: parameters: null values: [] timeouts: null + module.organization-iam[0].google_org_policy_policy.default["custom.cloudkmsAllowedRotationPeriod"]: + dry_run_spec: [] + name: organizations/1234567890/policies/custom.cloudkmsAllowedRotationPeriod + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + timeouts: null module.organization-iam[0].google_org_policy_policy.default["custom.cloudrunDisableEnvironmentVariablePattern"]: dry_run_spec: [] name: organizations/1234567890/policies/custom.cloudrunDisableEnvironmentVariablePattern @@ -3597,6 +5127,21 @@ values: parameters: null values: [] timeouts: null + module.organization-iam[0].google_org_policy_policy.default["custom.dataprocRequireDiskCmekEncryption"]: + dry_run_spec: [] + name: organizations/1234567890/policies/custom.dataprocRequireDiskCmekEncryption + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + timeouts: null module.organization-iam[0].google_org_policy_policy.default["custom.dataprocRequireInternalIp"]: dry_run_spec: [] name: organizations/1234567890/policies/custom.dataprocRequireInternalIp @@ -3777,6 +5322,36 @@ values: parameters: null values: [] timeouts: null + module.organization-iam[0].google_org_policy_policy.default["custom.firewallRestrictExplicitAllPortsPolicyRule"]: + dry_run_spec: [] + name: organizations/1234567890/policies/custom.firewallRestrictExplicitAllPortsPolicyRule + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + timeouts: null + module.organization-iam[0].google_org_policy_policy.default["custom.firewallRestrictExplicitAllPortsRule"]: + dry_run_spec: [] + name: organizations/1234567890/policies/custom.firewallRestrictExplicitAllPortsRule + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + timeouts: null module.organization-iam[0].google_org_policy_policy.default["custom.firewallRestrictInsecureProtocolsPolicyRule"]: dry_run_spec: [] name: organizations/1234567890/policies/custom.firewallRestrictInsecureProtocolsPolicyRule @@ -3927,6 +5502,21 @@ values: parameters: null values: [] timeouts: null + module.organization-iam[0].google_org_policy_policy.default["custom.firewallRestrictPublicAccessPolicyRule"]: + dry_run_spec: [] + name: organizations/1234567890/policies/custom.firewallRestrictPublicAccessPolicyRule + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + timeouts: null module.organization-iam[0].google_org_policy_policy.default["custom.firewallRestrictPublicAccessRule"]: dry_run_spec: [] name: organizations/1234567890/policies/custom.firewallRestrictPublicAccessRule @@ -4257,6 +5847,21 @@ values: parameters: null values: [] timeouts: null + module.organization-iam[0].google_org_policy_policy.default["custom.gkeRequireNodePoolCMEKEncryption"]: + dry_run_spec: [] + name: organizations/1234567890/policies/custom.gkeRequireNodePoolCMEKEncryption + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + timeouts: null module.organization-iam[0].google_org_policy_policy.default["custom.gkeRequireNodePoolSandbox"]: dry_run_spec: [] name: organizations/1234567890/policies/custom.gkeRequireNodePoolSandbox @@ -4332,6 +5937,63 @@ values: parameters: null values: [] timeouts: null + module.organization-iam[0].google_org_policy_policy.default["custom.iamDisableAdminServiceAccount"]: + dry_run_spec: [] + name: organizations/1234567890/policies/custom.iamDisableAdminServiceAccount + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + timeouts: null + module.organization-iam[0].google_org_policy_policy.default["custom.iamDisableBasicRoles"]: + dry_run_spec: [] + name: organizations/1234567890/policies/custom.iamDisableBasicRoles + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + timeouts: null + module.organization-iam[0].google_org_policy_policy.default["custom.iamDisableProjectServiceAccountImpersonationRoles"]: + dry_run_spec: [] + name: organizations/1234567890/policies/custom.iamDisableProjectServiceAccountImpersonationRoles + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: + - description: null + expression: 'resource.matchTag(''1234567890/org-policies'', ''allowed-sa-impersonation'') + + ' + location: null + title: Allow service account impersonation for tagged users + deny_all: null + enforce: 'FALSE' + parameters: null + values: [] + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + timeouts: null module.organization-iam[0].google_org_policy_policy.default["custom.iamDisablePublicBindings"]: dry_run_spec: [] name: organizations/1234567890/policies/custom.iamDisablePublicBindings @@ -4552,7 +6214,6 @@ values: - run.googleapis.com - secretmanager.googleapis.com - securesourcemanager.googleapis.com - - securitycenter.googleapis.com - spanner.googleapis.com - speech.googleapis.com - sqladmin.googleapis.com @@ -4560,6 +6221,102 @@ values: - storagetransfer.googleapis.com - workstations.googleapis.com timeouts: null + module.organization-iam[0].google_org_policy_policy.default["gcp.restrictServiceUsage"]: + dry_run_spec: [] + name: organizations/1234567890/policies/gcp.restrictServiceUsage + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + parameters: null + values: + - allowed_values: + - accesscontextmanager.googleapis.com + - analyticshub.googleapis.com + - anthos.googleapis.com + - anthosconfigmanagement.googleapis.com + - appoptimize.googleapis.com + - artifactregistry.googleapis.com + - autoscaling.googleapis.com + - bigquery.googleapis.com + - bigqueryconnection.googleapis.com + - bigquerydatapolicy.googleapis.com + - bigquerydatatransfer.googleapis.com + - bigquerymigration.googleapis.com + - bigqueryreservation.googleapis.com + - bigquerystorage.googleapis.com + - billingbudgets.googleapis.com + - certificatemanager.googleapis.com + - cloudaicompanion.googleapis.com + - cloudapis.googleapis.com + - cloudasset.googleapis.com + - cloudbilling.googleapis.com + - cloudbuild.googleapis.com + - cloudkms.googleapis.com + - cloudquotas.googleapis.com + - cloudresourcemanager.googleapis.com + - cloudsecuritycompliance.googleapis.com + - cloudtrace.googleapis.com + - composer.googleapis.com + - compute.googleapis.com + - container.googleapis.com + - containerfilesystem.googleapis.com + - containerregistry.googleapis.com + - containersecurity.googleapis.com + - containerthreatdetection.googleapis.com + - datacatalog.googleapis.com + - dataform.googleapis.com + - datalineage.googleapis.com + - dataplex.googleapis.com + - datastore.googleapis.com + - deploymentmanager.googleapis.com + - dns.googleapis.com + - essentialcontacts.googleapis.com + - geminicloudassist.googleapis.com + - gkebackup.googleapis.com + - gkeconnect.googleapis.com + - gkehub.googleapis.com + - iam.googleapis.com + - iamcredentials.googleapis.com + - iap.googleapis.com + - logging.googleapis.com + - monitoring.googleapis.com + - multiclusteringress.googleapis.com + - multiclustermetering.googleapis.com + - multiclusterservicediscovery.googleapis.com + - networkconnectivity.googleapis.com + - networkmanagement.googleapis.com + - networksecurity.googleapis.com + - notebooksecurityscanner.googleapis.com + - orgpolicy.googleapis.com + - oslogin.googleapis.com + - privateca.googleapis.com + - pubsub.googleapis.com + - recommender.googleapis.com + - secretmanager.googleapis.com + - securitycenter.googleapis.com + - securitycentermanagement.googleapis.com + - servicedirectory.googleapis.com + - servicemanagement.googleapis.com + - servicenetworking.googleapis.com + - serviceusage.googleapis.com + - sql-component.googleapis.com + - sqladmin.googleapis.com + - stackdriver.googleapis.com + - storage-api.googleapis.com + - storage-component.googleapis.com + - storage.googleapis.com + - sts.googleapis.com + - trafficdirector.googleapis.com + - vpcaccess.googleapis.com + - websecurityscanner.googleapis.com + denied_values: null + timeouts: null module.organization-iam[0].google_org_policy_policy.default["gcp.restrictTLSCipherSuites"]: dry_run_spec: [] name: organizations/1234567890/policies/gcp.restrictTLSCipherSuites @@ -4708,6 +6465,21 @@ values: parameters: null values: [] timeouts: null + ? module.organization-iam[0].google_org_policy_policy.default["iam.managed.preventPrivilegedBasicRolesForDefaultServiceAccounts"] + : dry_run_spec: [] + name: organizations/1234567890/policies/iam.managed.preventPrivilegedBasicRolesForDefaultServiceAccounts + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + timeouts: null module.organization-iam[0].google_org_policy_policy.default["iam.serviceAccountKeyExposureResponse"]: dry_run_spec: [] name: organizations/1234567890/policies/iam.serviceAccountKeyExposureResponse @@ -5233,1307 +7005,6 @@ values: organization: '1234567890' storage_location: europe-west1 timeouts: null - ? module.organization[0].google_org_policy_custom_constraint.constraint["custom.accesscontextmanagerDisableBridgePerimeters"] - : action_type: DENY - condition: resource.perimeterType == 'PERIMETER_TYPE_BRIDGE' - description: Ensure no perimeter bridges are used. Instead, use ingress and egress - rules. - display_name: Deny usage of perimeter bridges - method_types: - - CREATE - - UPDATE - name: custom.accesscontextmanagerDisableBridgePerimeters - parent: organizations/1234567890 - resource_types: - - accesscontextmanager.googleapis.com/ServicePerimeter - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudbuildDisableWorkerPoolExternalIP"]: - action_type: DENY - condition: (resource.privatePoolV1Config.networkConfig.egressOption != "NO_PUBLIC_EGRESS") - description: Ensure no unauthorized worker pools external ip used for each build - display_name: Deny unauthorized worker pools external ip used for each build - method_types: - - CREATE - - UPDATE - name: custom.cloudbuildDisableWorkerPoolExternalIP - parent: organizations/1234567890 - resource_types: - - cloudbuild.googleapis.com/WorkerPool - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudkmsAllowedProtectionLevel"]: - action_type: DENY - condition: has(resource.versionTemplate.protectionLevel) && resource.versionTemplate.protectionLevel - in ["SOFTWARE"] == false - description: Ensure the protection level for Cloud KMS keys is configured correctly - display_name: Require Cloud KMS keys protection level to be configured correctly - method_types: - - CREATE - - UPDATE - name: custom.cloudkmsAllowedProtectionLevel - parent: organizations/1234567890 - resource_types: - - cloudkms.googleapis.com/CryptoKey - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudrunDisableEnvironmentVariablePattern"]: - action_type: DENY - condition: "resource.spec.template.spec.containers.exists(container,\n container.env.exists(env,\n\ - \ [\"[sS][eE][cC][rR][eE][tT]\", \"[kK][eE][yY]\", \"[pP][aA][sS][sS][wW][oO][rR][dD]\"\ - , \"[tT][oO][kK][eE][nN]\"].exists(\n pattern, env.name.matches(pattern)\n\ - \ )\n )\n)" - description: Enforce that certain patterns are not used in environment variables - of Cloud Run Service or Cloud Run Functions - display_name: Disable usage of certain patterns in Cloud Run Service or Cloud - Run Functions environment variables - method_types: - - CREATE - - UPDATE - name: custom.cloudrunDisableEnvironmentVariablePattern - parent: organizations/1234567890 - resource_types: - - run.googleapis.com/Service - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudrunJobDisableDefaultServiceAccount"]: - action_type: DENY - condition: resource.spec.template.spec.template.spec.serviceAccountName.endsWith('@developer.gserviceaccount.com') - description: Enforce that service account associated with Cloud Run Job use a - non-default service account - display_name: Disable creation of Cloud Run Job using default service account - method_types: - - CREATE - - UPDATE - name: custom.cloudrunJobDisableDefaultServiceAccount - parent: organizations/1234567890 - resource_types: - - run.googleapis.com/Job - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudrunJobRequireBinaryAuthorization"]: - action_type: DENY - condition: '!(''run.googleapis.com/binary-authorization'' in resource.metadata.annotations)' - description: Enforce that Cloud Run Job are using binary authorization - display_name: Disable creation of Cloud Run Job without Binary Authorization - method_types: - - CREATE - - UPDATE - name: custom.cloudrunJobRequireBinaryAuthorization - parent: organizations/1234567890 - resource_types: - - run.googleapis.com/Job - timeouts: null - ? module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudrunServiceDisableDefaultServiceAccount"] - : action_type: DENY - condition: resource.spec.template.spec.serviceAccountName.endsWith('@developer.gserviceaccount.com') - description: Enforce that service account associated with Cloud Run Service use - a non-default service account - display_name: Disable creation of Cloud Run Service using default service account - method_types: - - CREATE - - UPDATE - name: custom.cloudrunServiceDisableDefaultServiceAccount - parent: organizations/1234567890 - resource_types: - - run.googleapis.com/Service - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudrunServiceRequireBinaryAuthorization"]: - action_type: DENY - condition: '!(''run.googleapis.com/binary-authorization'' in resource.metadata.annotations)' - description: Enforce that Cloud Run Service are using binary authorization - display_name: Disable creation of Cloud Run Service without Binary Authorization - method_types: - - CREATE - - UPDATE - name: custom.cloudrunServiceRequireBinaryAuthorization - parent: organizations/1234567890 - resource_types: - - run.googleapis.com/Service - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlDisablePublicAuthorizedNetworks"]: - action_type: DENY - condition: resource.settings.ipConfiguration.authorizedNetworks.exists(network, - network.value == '0.0.0.0/0') - description: Ensure That Cloud SQL database instances do not implicitly whitelist - all public IP addresses - display_name: Require Cloud SQL database instances to not whitelist all public - IP addresses - method_types: - - CREATE - - UPDATE - name: custom.cloudsqlDisablePublicAuthorizedNetworks - parent: organizations/1234567890 - resource_types: - - sqladmin.googleapis.com/Instance - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlEnforcePasswordComplexity"]: - action_type: DENY - condition: 'resource.settings.passwordValidationPolicy.complexity != ''COMPLEXITY_DEFAULT'' - || - - resource.settings.passwordValidationPolicy.minLength < 12' - description: Ensure that Cloud SQL instance is configured with a password complexity - to be combination of lowercase, uppercase, numeric, and non-alphanumeric characters - display_name: Require Cloud SQL instances to configure password complexity to - COMPLEXITY_DEFAULT - method_types: - - CREATE - - UPDATE - name: custom.cloudsqlEnforcePasswordComplexity - parent: organizations/1234567890 - resource_types: - - sqladmin.googleapis.com/Instance - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequireAutomatedBackup"]: - action_type: DENY - condition: resource.settings.backupConfiguration.enabled != true - description: Ensure that Cloud SQL instance have automated backup enabled - display_name: Require Cloud SQL instances to have automated backup enabled - method_types: - - CREATE - - UPDATE - name: custom.cloudsqlRequireAutomatedBackup - parent: organizations/1234567890 - resource_types: - - sqladmin.googleapis.com/Instance - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequireHighAvailability"]: - action_type: DENY - condition: resource.settings.availabilityType != "REGIONAL" - description: Ensure that Cloud SQL instance is configured with high availability - display_name: Require Cloud SQL instances to be configured with high availability - method_types: - - CREATE - - UPDATE - name: custom.cloudsqlRequireHighAvailability - parent: organizations/1234567890 - resource_types: - - sqladmin.googleapis.com/Instance - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequireMySQLDatabaseFlags"]: - action_type: DENY - condition: "resource.databaseVersion.startsWith('MYSQL') && (\n !resource.settings.databaseFlags.exists(flag,\n\ - \ flag.name == 'skip_show_database' && flag.value == 'on'\n ) ||\n !resource.settings.databaseFlags.exists(flag,\n\ - \ flag.name == 'local_infile' && flag.value == 'off'\n )\n)" - description: Ensure Cloud SQL for MySQL instance database flags are set correctly - (e.g skip_show_database, local_infile) - display_name: Require Cloud SQL for MySQL instance database flags to be configured - correctly (e.g skip_show_database, local_infile) - method_types: - - CREATE - - UPDATE - name: custom.cloudsqlRequireMySQLDatabaseFlags - parent: organizations/1234567890 - resource_types: - - sqladmin.googleapis.com/Instance - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequirePointInTimeRecovery"]: - action_type: DENY - condition: "(resource.databaseVersion.contains(\"POSTGRES\")\n || resource.databaseVersion.contains(\"\ - SQLSERVER\"))\n && resource.settings.backupConfiguration.pointInTimeRecoveryEnabled\ - \ == false" - description: Ensure that Cloud SQL instance is configure enable point in time - recovery in the backup configuration. This setting is possibly for Postgres - and SQLServer databases. - display_name: Require Cloud SQL instances to enable point in time recovery - method_types: - - CREATE - - UPDATE - name: custom.cloudsqlRequirePointInTimeRecovery - parent: organizations/1234567890 - resource_types: - - sqladmin.googleapis.com/Instance - timeouts: null - ? module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequirePostgreSQLDatabaseAdditionalFlags"] - : action_type: DENY - condition: "resource.databaseVersion.startsWith('POSTGRES') && (\n !resource.settings.databaseFlags.exists(flag,\ - \ flag.name == 'log_checkpoints' && flag.value == 'on') ||\n !resource.settings.databaseFlags.exists(flag,\ - \ flag.name == 'log_executor_stats' && flag.value == 'off') ||\n !resource.settings.databaseFlags.exists(flag,\ - \ flag.name == 'log_lock_waits' && flag.value == 'on')\n)" - description: Ensure Cloud SQL for PostgreSQL instance database flags are set correctly - (e.g log_checkpoints, log_executor_stats, log_lock_waits) - display_name: Require Cloud SQL for PostgreSQL instance database flags to be configured - correctly (e.g log_checkpoints, log_executor_stats, log_lock_waits) - method_types: - - CREATE - - UPDATE - name: custom.cloudsqlRequirePostgreSQLDatabaseAdditionalFlags - parent: organizations/1234567890 - resource_types: - - sqladmin.googleapis.com/Instance - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequirePostgreSQLDatabaseFlags"]: - action_type: DENY - condition: "resource.databaseVersion.startsWith('POSTGRES') && (\n !resource.settings.databaseFlags.exists(f,\ - \ f.name == 'log_connections' && f.value == 'on') ||\n !resource.settings.databaseFlags.exists(f,\ - \ f.name == 'log_disconnections' && f.value == 'on') ||\n !resource.settings.databaseFlags.exists(f,\ - \ f.name == 'log_min_duration_statement' && f.value == '-1') ||\n !resource.settings.databaseFlags.exists(f,\ - \ f.name == 'cloudsql.enable_pgaudit' && f.value == 'on') ||\n resource.settings.databaseFlags.exists(f,\ - \ f.name == 'log_error_verbosity' && f.value == 'terse') ||\n resource.settings.databaseFlags.exists(f,\ - \ f.name == 'log_statement' && f.value == 'none') ||\n resource.settings.databaseFlags.exists(f,\n\ - \ f.name == 'log_min_messages' && f.value in ['error' , 'log', 'fatal', 'panic']\n\ - \ ) ||\n resource.settings.databaseFlags.exists(f,\n f.name == 'log_min_error_statement'\ - \ && f.value in ['log', 'fatal', 'panic']\n )\n)" - description: Ensure Cloud SQL for PostgreSQL instance database flags are set correctly - (e.g log_connections) - display_name: Require Cloud SQL for PostgreSQL instance database flags to be configured - correctly (e.g log_connections) - method_types: - - CREATE - - UPDATE - name: custom.cloudsqlRequirePostgreSQLDatabaseFlags - parent: organizations/1234567890 - resource_types: - - sqladmin.googleapis.com/Instance - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequireRootPassword"]: - action_type: DENY - condition: resource.settings.passwordValidationPolicy.minLength == 0 - description: Ensure that Cloud SQL instance is configured to use a root password - display_name: Require Cloud SQL instances to configure root password - method_types: - - CREATE - - UPDATE - name: custom.cloudsqlRequireRootPassword - parent: organizations/1234567890 - resource_types: - - sqladmin.googleapis.com/Instance - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequireSQLServerDatabaseFlags"]: - action_type: DENY - condition: "resource.databaseVersion.startsWith('SQLSERVER') && (\n resource.settings.databaseFlags.exists(flag,\n\ - \ flag.name == 'external scripts enabled' && flag.value == 'on'\n ) ||\n\ - \ resource.settings.databaseFlags.exists(flag,\n flag.name == 'cross db\ - \ ownership chaining' && flag.value == 'on'\n ) ||\n resource.settings.databaseFlags.exists(flag,\n\ - \ flag.name == 'contained database authentication' && flag.value == 'on'\n\ - \ ) ||\n resource.settings.databaseFlags.exists(flag,\n flag.name == 'user\ - \ connections' && flag.value != '0'\n ) ||\n resource.settings.databaseFlags.exists(flag,\n\ - \ flag.name == 'user options' && flag.value != '0'\n ) ||\n !resource.settings.databaseFlags.exists(flag,\n\ - \ flag.name == 'remote access' && flag.value == 'off'\n ) ||\n !resource.settings.databaseFlags.exists(flag,\n\ - \ flag.name == '3625' && flag.value == 'on'\n )\n)" - description: Ensure Cloud SQL for SQLServer instance database flags are set correctly - (e.g external scripts enabled ...) - display_name: Require Cloud SQL for SQLServer instance database flags to be configured - correctly (e.g external scripts enabled ...) - method_types: - - CREATE - - UPDATE - name: custom.cloudsqlRequireSQLServerDatabaseFlags - parent: organizations/1234567890 - resource_types: - - sqladmin.googleapis.com/Instance - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.cloudsqlRequireSSLConnection"]: - action_type: DENY - condition: resource.settings.ipConfiguration.sslMode in ['ENCRYPTED_ONLY', 'TRUSTED_CLIENT_CERTIFICATE_REQUIRED'] - == false - description: Ensure that Cloud SQL instance is configured to allow only connections - that are encrypted with SSL/TLS - display_name: Require Cloud SQL instances to allow only connections that are encrypted - with SSL/TLS - method_types: - - CREATE - - UPDATE - name: custom.cloudsqlRequireSSLConnection - parent: organizations/1234567890 - resource_types: - - sqladmin.googleapis.com/Instance - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.dataprocDisableDefaultServiceAccount"]: - action_type: DENY - condition: "has(resource.config.gceClusterConfig.serviceAccount) == false ||\n\ - \ resource.config.gceClusterConfig.serviceAccount.contains('-compute@developer.gserviceaccount.com')" - description: Enforce that the Dataproc VMs is not using default user-managed service - accounts - display_name: Disable Dataproc cluster with default service accounts - method_types: - - CREATE - - UPDATE - name: custom.dataprocDisableDefaultServiceAccount - parent: organizations/1234567890 - resource_types: - - dataproc.googleapis.com/Cluster - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.dataprocRequireInternalIp"]: - action_type: DENY - condition: resource.config.gceClusterConfig.internalIpOnly == false - description: Enforce that the Dataproc cluster is created with Internal IPs only - display_name: Require Dataproc with internal IPs - method_types: - - CREATE - - UPDATE - name: custom.dataprocRequireInternalIp - parent: organizations/1234567890 - resource_types: - - dataproc.googleapis.com/Cluster - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.dataprocRequireKerberos"]: - action_type: DENY - condition: resource.config.securityConfig.kerberosConfig.enableKerberos == false - description: Enforce that Dataproc cluster is configured using secure mode via - Kerberos for authentication - display_name: Require Dataproc with Kerberos authentication - method_types: - - CREATE - - UPDATE - name: custom.dataprocRequireKerberos - parent: organizations/1234567890 - resource_types: - - dataproc.googleapis.com/Cluster - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.dnsAllowedSigningAlgorithms"]: - action_type: DENY - condition: "resource.visibility == 'PUBLIC' &&\nresource.dnssecConfig.state ==\ - \ 'ON' &&\nresource.dnssecConfig.defaultKeySpecs.exists(spec,\n spec.algorithm\ - \ in [\"ECDSAP256SHA256\"] == false\n)" - description: Ensure that allowed signing algorithms are used for the Key-Signing - key and Zone-Signing key in Cloud DNS DNSSEC - display_name: Require Cloud DNS DNSSEC configured to use only allowed algorithms - in Cloud DNS DNSSEC - method_types: - - CREATE - - UPDATE - name: custom.dnsAllowedSigningAlgorithms - parent: organizations/1234567890 - resource_types: - - dns.googleapis.com/ManagedZone - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.dnsRequireManageZoneDNSSEC"]: - action_type: DENY - condition: resource.visibility == "PUBLIC" && (resource.dnssecConfig.state in - ["ON", "TRANSFER"] == false) - description: Ensure that Cloud DNS DNSSEC is enabled when configuring a DNS Public - Managed Zone - display_name: Require Cloud DNS DNSSEC enabled when configuring a DNS Public Managed - Zone - method_types: - - CREATE - - UPDATE - name: custom.dnsRequireManageZoneDNSSEC - parent: organizations/1234567890 - resource_types: - - dns.googleapis.com/ManagedZone - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.dnsRequirePolicyLogging"]: - action_type: DENY - condition: resource.enableLogging != true - description: Ensure that Cloud DNS logging is enabled when configuring a DNS Policy - display_name: Require Cloud DNS logging enabled when configuring a DNS Policy - method_types: - - CREATE - - UPDATE - name: custom.dnsRequirePolicyLogging - parent: organizations/1234567890 - resource_types: - - dns.googleapis.com/Policy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallEnforcePolicyRuleLogging"]: - action_type: DENY - condition: resource.rules.exists(rule, rule.action != 'goto_next' && rule.enableLogging - == false) - description: Ensure that Firewall Policy rules have logging enabled - display_name: Require Firewall Policy rules to have logging enabled - method_types: - - CREATE - - UPDATE - name: custom.firewallEnforcePolicyRuleLogging - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/FirewallPolicy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallEnforceRuleLogging"]: - action_type: DENY - condition: "(\n (has(resource.logConfig) == false || resource.logConfig.enable\ - \ == false) &&\n !resource.name.startsWith(\"gke-\") &&\n !resource.name.startsWith(\"\ - k8s-\") &&\n !resource.name.endsWith(\"-hc\") &&\n !resource.name.startsWith(\"\ - k8s2-\") &&\n !resource.name.startsWith(\"gkegw1-l7-\") &&\n !resource.name.startsWith(\"\ - gkemcg1-l7-\")\n)" - description: Ensure that VPC Firewall rules have logging enabled - display_name: Require VPC Firewall rules to have logging enabled - method_types: - - CREATE - - UPDATE - name: custom.firewallEnforceRuleLogging - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/Firewall - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRequireDescription"]: - action_type: DENY - condition: "(\n resource.description == \"\" &&\n !resource.name.startsWith(\"\ - gke-\") &&\n !resource.name.startsWith(\"k8s-\") &&\n !resource.name.endsWith(\"\ - -hc\") &&\n !resource.name.startsWith(\"k8s2-\") &&\n !resource.name.startsWith(\"\ - gkegw1-l7-\") &&\n !resource.name.startsWith(\"gkemcg1-l7-\")\n)" - description: Prevent the creation of VPC firewall rule that does not have description - provided. Description can be used for auditing to refer to security control - display_name: Require description on Firewall rule - method_types: - - CREATE - name: custom.firewallRequireDescription - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/Firewall - timeouts: null - ? module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictCacheSearchDatabasesPolicyRule"] - : action_type: DENY - condition: "resource.rules.exists(r, r.priority < 2147483644 && r.direction ==\ - \ 'INGRESS' &&\n r.match.srcIpRanges.exists(r, r == '0.0.0.0/0') &&\n (\n\ - \ r.match.layer4Configs.containsIpProtocolAndPort('tcp', '6379') ||\n \ - \ r.match.layer4Configs.containsIpProtocolAndPort('udp', '6379') ||\n r.match.layer4Configs.containsIpProtocolAndPort('tcp',\ - \ '9200') ||\n r.match.layer4Configs.containsIpProtocolAndPort('udp', '9200')\ - \ ||\n r.match.layer4Configs.containsIpProtocolAndPort('tcp', '9300') ||\n\ - \ r.match.layer4Configs.containsIpProtocolAndPort('udp', '9300') ||\n \ - \ r.match.layer4Configs.containsIpProtocolAndPort('tcp', '11211') ||\n r.match.layer4Configs.containsIpProtocolAndPort('udp',\ - \ '11211') ||\n r.match.layer4Configs.containsIpProtocolAndPort('tcp', '11214')\ - \ ||\n r.match.layer4Configs.containsIpProtocolAndPort('udp', '11214') ||\n\ - \ r.match.layer4Configs.containsIpProtocolAndPort('tcp', '11215') ||\n \ - \ r.match.layer4Configs.containsIpProtocolAndPort('udp', '11215')\n )\n)" - description: Ensure that cache and search database ports (Elasticsearch, Memcached, - Redis) are not accessible from any source when using Firewall Policy Rule - display_name: Restrict Firewall Policy rules allowing cache/search database port - access from any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictCacheSearchDatabasesPolicyRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/FirewallPolicy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictCacheSearchDatabasesRule"]: - action_type: DENY - condition: "resource.direction.matches('INGRESS') &&\n resource.sourceRanges.exists(range,\ - \ range == '0.0.0.0/0') &&\n (\n resource.allowed.containsFirewallPort('tcp',\ - \ '9200') ||\n resource.allowed.containsFirewallPort('tcp', '9300') ||\n\ - \ resource.allowed.containsFirewallPort('tcp', '11211') ||\n resource.allowed.containsFirewallPort('tcp',\ - \ '11214') ||\n resource.allowed.containsFirewallPort('tcp', '11215') ||\n\ - \ resource.allowed.containsFirewallPort('tcp', '6379') ||\n resource.allowed.containsFirewallPort('udp',\ - \ '11211') ||\n resource.allowed.containsFirewallPort('udp', '11214') ||\n\ - \ resource.allowed.containsFirewallPort('udp', '11215')\n )" - description: Ensure that cache and search database ports (Elasticsearch, Memcached, - Redis) are not accessible from any source when using VPC Firewall Rule. - display_name: Restrict VPC Firewall rules allowing cache/search database port - access from any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictCacheSearchDatabasesRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/Firewall - timeouts: null - ? module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictDirectoryServicesPolicyRule"] - : action_type: DENY - condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n rule.direction\ - \ == 'INGRESS' &&\n rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0')\ - \ &&\n (\n rule.match.layer4Configs.containsIpProtocolAndPort('udp', '445')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('udp', '389') ||\n\ - \ rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '445') ||\n \ - \ rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '389') ||\n \ - \ rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '636')\n )\n)" - description: Ensure that directory and authentication services (SMB/CIFS, LDAP) - are not accessible from the Internet when using Firewall Policy Rule - display_name: Restrict Firewall Policy rules allowing directory service access - from any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictDirectoryServicesPolicyRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/FirewallPolicy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictDirectoryServicesRule"]: - action_type: DENY - condition: "resource.direction.matches('INGRESS') &&\n resource.sourceRanges.exists(range,\ - \ range == '0.0.0.0/0') &&\n (\n resource.allowed.containsFirewallPort('tcp',\ - \ '445') ||\n resource.allowed.containsFirewallPort('tcp', '389') ||\n \ - \ resource.allowed.containsFirewallPort('tcp', '636') ||\n resource.allowed.containsFirewallPort('udp',\ - \ '445') ||\n resource.allowed.containsFirewallPort('udp', '389')\n )" - description: Ensure that directory and authentication services (SMB/CIFS, LDAP) - are not accessible from the Internet when using VPC Firewall Rule - display_name: Restrict VPC Firewall rules allowing directory service access from - any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictDirectoryServicesRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/Firewall - timeouts: null - ? module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictInsecureProtocolsPolicyRule"] - : action_type: DENY - condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n rule.direction\ - \ == 'INGRESS' &&\n rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0')\ - \ &&\n (\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '21')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '23') ||\n\ - \ rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '80')\n )\n)" - description: Ensure that insecure legacy protocols (Telnet, FTP, HTTP) are not - accessible from any source when using Firewall Policy Rule - display_name: Restrict Firewall Policy rules allowing insecure protocol access - from any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictInsecureProtocolsPolicyRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/FirewallPolicy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictInsecureProtocolsRule"]: - action_type: DENY - condition: "resource.direction.matches('INGRESS') &&\n resource.sourceRanges.exists(range,\ - \ range == '0.0.0.0/0') &&\n (\n resource.allowed.containsFirewallPort('tcp',\ - \ '21') ||\n resource.allowed.containsFirewallPort('tcp', '23') ||\n resource.allowed.containsFirewallPort('tcp',\ - \ '80')\n )" - description: Ensure that insecure legacy protocols (Telnet, FTP, HTTP) are not - accessible from any source when using VPC Firewall Rule - display_name: Restrict VPC Firewall rules allowing insecure protocol access from - any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictInsecureProtocolsRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/Firewall - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictMailProtocolsPolicyRule"]: - action_type: DENY - condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n rule.direction\ - \ == 'INGRESS' &&\n rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0')\ - \ &&\n (\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '25')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '110')\n\ - \ )\n)" - description: Ensure that mail protocols (SMTP, POP3) are not accessible from any - source when using Firewall Policy Rule - display_name: Restrict Firewall Policy rules allowing mail protocol access from - any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictMailProtocolsPolicyRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/FirewallPolicy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictMailProtocolsRule"]: - action_type: DENY - condition: "resource.direction.matches('INGRESS') &&\n resource.sourceRanges.exists(range,\ - \ range == '0.0.0.0/0') &&\n (\n resource.allowed.containsFirewallPort('tcp',\ - \ '25') ||\n resource.allowed.containsFirewallPort('tcp', '110')\n )" - description: Ensure that mail protocols (SMTP, POP3) are not accessible from any - source when using VPC Firewall Rule - display_name: Restrict VPC Firewall rules allowing mail protocol access from any - source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictMailProtocolsRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/Firewall - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictManagementPortsPolicyRule"]: - action_type: DENY - condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n rule.direction\ - \ == 'INGRESS' &&\n rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0')\ - \ &&\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '9090')\n)" - description: Ensure that management interfaces (Cisco Secure WebSM) are not accessible - from any source when using Firewall Policy Rule - display_name: Restrict Firewall Policy rules allowing management port access from - any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictManagementPortsPolicyRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/FirewallPolicy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictManagementPortsRule"]: - action_type: DENY - condition: "resource.direction.matches('INGRESS') &&\n resource.sourceRanges.exists(range,\ - \ range == '0.0.0.0/0') &&\n resource.allowed.containsFirewallPort('tcp', '9090')" - description: Ensure that management interfaces (Cisco Secure WebSM) are not accessible - from any source when using VPC Firewall Rule - display_name: Restrict VPC Firewall rules allowing management port access from - any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictManagementPortsRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/Firewall - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictNetworkServicesPolicyRule"]: - action_type: DENY - condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n rule.direction\ - \ == 'INGRESS' &&\n rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0')\ - \ &&\n (\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '53')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('udp', '53') ||\n\ - \ rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '137') ||\n \ - \ rule.match.layer4Configs.containsIpProtocolAndPort('udp', '137') ||\n \ - \ rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '138') ||\n \ - \ rule.match.layer4Configs.containsIpProtocolAndPort('udp', '138') ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp',\ - \ '139') ||\n rule.match.layer4Configs.containsIpProtocolAndPort('udp', '139')\n\ - \ )\n)" - description: Ensure that network infrastructure services (DNS, NetBIOS) are not - accessible from any source when using Firewall Policy Rule - display_name: Restrict Firewall Policy rules allowing network service access from - any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictNetworkServicesPolicyRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/FirewallPolicy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictNetworkServicesRule"]: - action_type: DENY - condition: "resource.direction.matches('INGRESS') &&\n resource.sourceRanges.exists(range,\ - \ range == '0.0.0.0/0') &&\n (\n resource.allowed.containsFirewallPort('tcp',\ - \ '53') ||\n resource.allowed.containsFirewallPort('udp', '53') ||\n resource.allowed.containsFirewallPort('tcp',\ - \ '137') ||\n resource.allowed.containsFirewallPort('udp', '137') ||\n \ - \ resource.allowed.containsFirewallPort('tcp', '138') ||\n resource.allowed.containsFirewallPort('udp',\ - \ '138') ||\n resource.allowed.containsFirewallPort('tcp', '139') ||\n \ - \ resource.allowed.containsFirewallPort('udp', '139')\n )" - description: Ensure that network infrastructure services (DNS, NetBIOS) are not - accessible from any source when using VPC Firewall Rule - display_name: Restrict VPC Firewall rules allowing network service access from - any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictNetworkServicesRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/Firewall - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictNoSQLDatabasesPolicyRule"]: - action_type: DENY - condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n rule.direction\ - \ == 'INGRESS' &&\n rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0')\ - \ &&\n (\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '7000')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '7001')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '7199')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '8888')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '9042')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '9160')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '61620')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '61621')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '27017')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '27018')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '27019')\n\ - \ )\n)" - description: Ensure that NoSQL database ports (Cassandra, MongoDB) are not accessible - from any source when using Firewall Policy Rule - display_name: Restrict Firewall Policy rules allowing NoSQL database port access - from any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictNoSQLDatabasesPolicyRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/FirewallPolicy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictNoSQLDatabasesRule"]: - action_type: DENY - condition: "resource.direction.matches('INGRESS') &&\n resource.sourceRanges.exists(range,\ - \ range == '0.0.0.0/0') &&\n (\n resource.allowed.containsFirewallPort('tcp',\ - \ '7000') ||\n resource.allowed.containsFirewallPort('tcp', '7001') ||\n\ - \ resource.allowed.containsFirewallPort('tcp', '7199') ||\n resource.allowed.containsFirewallPort('tcp',\ - \ '8888') ||\n resource.allowed.containsFirewallPort('tcp', '9042') ||\n\ - \ resource.allowed.containsFirewallPort('tcp', '9160') ||\n resource.allowed.containsFirewallPort('tcp',\ - \ '61620') ||\n resource.allowed.containsFirewallPort('tcp', '61621') ||\n\ - \ resource.allowed.containsFirewallPort('tcp', '27017') ||\n resource.allowed.containsFirewallPort('tcp',\ - \ '27018') ||\n resource.allowed.containsFirewallPort('tcp', '27019')\n \ - \ )" - description: Ensure that NoSQL database ports (Cassandra, MongoDB) are not accessible - from any source when using Firewall Policy Rule - display_name: Restrict VPC Firewall rules allowing NoSQL database port access - from any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictNoSQLDatabasesRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/Firewall - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictPublicAccessRule"]: - action_type: DENY - condition: "(size(resource.allowed) > 0) &&\n(\n resource.sourceRanges.exists(range,\ - \ range == '0.0.0.0/0') ||\n resource.destinationRanges.exists(range, range\ - \ == '0.0.0.0/0')\n)" - description: Prevent the creation of VPC firewall rules with source or destination - any IP address (0.0.0.0/0) - display_name: Restrict VPC Firewall rules allowing public Internet access - method_types: - - CREATE - name: custom.firewallRestrictPublicAccessRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/Firewall - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictRdpPolicyRule"]: - action_type: DENY - condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n \ - \ rule.direction == 'INGRESS' &&\n !rule.match.srcIpRanges.all(ipRange,\n\ - \ ipRange == '35.235.240.0/20' ||\n ipRange.startsWith('192.168.')\ - \ ||\n ipRange.matches('^172\\\\.(?:1[6-9]|2\\\\d|3[0-1]).*') ||\n \ - \ ipRange.startsWith('10.')\n ) &&\n rule.match.layer4Configs.all(l4config,\n\ - \ l4config.ipProtocol == 'tcp' &&\n l4config.ports.all(port, port\ - \ == '3389')\n )\n)" - description: Ensure that RDP access is restricted from any source when using Firewall - Policy Rule - display_name: Restrict Firewall Policy rules allowing RDP access from any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictRdpPolicyRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/FirewallPolicy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictRdpRule"]: - action_type: DENY - condition: "resource.direction.matches('INGRESS') &&\n!resource.name.startsWith('gke-')\ - \ &&\n!resource.name.startsWith('k8s-') &&\n!resource.name.endsWith('-hc') &&\n\ - !resource.name.startsWith('k8s2-') &&\n!resource.name.startsWith('gkegw1-l7-')\ - \ &&\n!resource.name.startsWith('gkemcg1-l7-') &&\nresource.allowed.containsFirewallPort('tcp',\ - \ '3389') &&\n!resource.sourceRanges.all(range,\n range == '35.235.240.0/20'\ - \ ||\n range.startsWith('10.') ||\n range.matches('^172\\\\.(?:1[6-9]|2\\\\\ - d|3[0-1]).*') ||\n range.startsWith('192.168.')\n)" - description: Ensure that RDP access is restricted from any source when using VPC - Firewall Rule - display_name: Restrict VPC Firewall rules allowing RDP access from any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictRdpRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/Firewall - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictSQLDatabasesPolicyRule"]: - action_type: DENY - condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n rule.direction\ - \ == 'INGRESS' &&\n rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0')\ - \ &&\n (\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '3306')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '1521')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '2483')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '2484')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '5432')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('udp', '2483')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('udp', '2484')\ - \ ||\n rule.match.layer4Configs.containsIpProtocolAndPort('udp', '5432')\n\ - \ )\n)" - description: Ensure that SQL database ports (MySQL, Oracle, PostgreSQL) are not - accessible from any source when using Firewall Policy Rule - display_name: Restrict Firewall Policy rules allowing SQL database port access - from any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictSQLDatabasesPolicyRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/FirewallPolicy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictSQLDatabasesRule"]: - action_type: DENY - condition: "resource.direction.matches('INGRESS') &&\n resource.sourceRanges.exists(range,\ - \ range == '0.0.0.0/0') &&\n (\n resource.allowed.containsFirewallPort('tcp',\ - \ '3306') ||\n resource.allowed.containsFirewallPort('tcp', '1521') ||\n\ - \ resource.allowed.containsFirewallPort('tcp', '2483') ||\n resource.allowed.containsFirewallPort('tcp',\ - \ '2484') ||\n resource.allowed.containsFirewallPort('tcp', '5432') ||\n\ - \ resource.allowed.containsFirewallPort('udp', '2483') ||\n resource.allowed.containsFirewallPort('udp',\ - \ '2484') ||\n resource.allowed.containsFirewallPort('udp', '5432')\n )" - description: Ensure that SQL database ports (MySQL, Oracle, PostgreSQL) are not - accessible from any source when using VPC Firewall Rule - display_name: Restrict VPC Firewall rules allowing SQL database port access from - any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictSQLDatabasesRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/Firewall - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictSshPolicyRule"]: - action_type: DENY - condition: "resource.rules.exists(rule,\n rule.priority < 2147483644 &&\n \ - \ rule.direction == 'INGRESS' &&\n !rule.match.srcIpRanges.all(ipRange,\n\ - \ ipRange == '35.235.240.0/20' ||\n ipRange.startsWith('192.168.')\ - \ ||\n ipRange.matches('^172\\\\.(?:1[6-9]|2\\\\d|3[0-1]).*') ||\n \ - \ ipRange.startsWith('10.')\n ) &&\n rule.match.layer4Configs.all(l4config,\n\ - \ l4config.ipProtocol == 'tcp' &&\n l4config.ports.all(port, port\ - \ == '22')\n )\n)" - description: Ensure that SSH access is restricted from any source when using Firewall - Policy Rule - display_name: Restrict Firewall Policy rules allowing SSH access from any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictSshPolicyRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/FirewallPolicy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.firewallRestrictSshRule"]: - action_type: DENY - condition: "resource.direction.matches('INGRESS') &&\n!resource.name.startsWith('gke-')\ - \ &&\n!resource.name.startsWith('k8s-') &&\n!resource.name.endsWith('-hc') &&\n\ - !resource.name.startsWith('k8s2-') &&\n!resource.name.startsWith('gkegw1-l7-')\ - \ &&\n!resource.name.startsWith('gkemcg1-l7-') &&\nresource.allowed.containsFirewallPort('tcp',\ - \ '22') &&\n!resource.sourceRanges.all(range,\n range == '35.235.240.0/20'\ - \ ||\n range.startsWith('10.') ||\n range.matches('^172\\\\.(?:1[6-9]|2\\\\\ - d|3[0-1]).*') ||\n range.startsWith('192.168.')\n)" - description: Ensure that SSH access is restricted from any source when using VPC - Firewall Rule - display_name: Restrict VPC Firewall rules allowing SSH access from any source - method_types: - - CREATE - - UPDATE - name: custom.firewallRestrictSshRule - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/Firewall - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeAllowedNodePoolImages"]: - action_type: DENY - condition: resource.config.imageType in ["COS_CONTAINERD"] == false - description: Enforce that GKE nodes are using authorized node images - display_name: Allow only authorized node pool images - method_types: - - CREATE - - UPDATE - name: custom.gkeAllowedNodePoolImages - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/NodePool - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeAllowedReleaseChannels"]: - action_type: DENY - condition: resource.releaseChannel.channel in ["REGULAR", "STABLE"] == false - description: Enforce that GKE cluster are using authorized release channels - display_name: Allow only authorized release channels - method_types: - - CREATE - - UPDATE - name: custom.gkeAllowedReleaseChannels - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/Cluster - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeDisableAlphaCluster"]: - action_type: DENY - condition: resource.enableKubernetesAlpha == true - description: Enforce that GKE clusters are not using alpha features for production - workloads - display_name: Disable alpha features for production workloads - method_types: - - CREATE - - UPDATE - name: custom.gkeDisableAlphaCluster - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/Cluster - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeDisableKubernetesDashboard"]: - action_type: DENY - condition: resource.addonsConfig.kubernetesDashboard.disabled == false - description: Enforce that GKE clusters does not have Web UI dashboard enabled - display_name: Disable Web UI dashboard - method_types: - - CREATE - - UPDATE - name: custom.gkeDisableKubernetesDashboard - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/Cluster - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeDisableLegacyAbac"]: - action_type: DENY - condition: resource.legacyAbac.enabled == true - description: Enforce that GKE clusters is configured with no legacy ABAC enabled - display_name: Disable legacy ABAC - method_types: - - CREATE - - UPDATE - name: custom.gkeDisableLegacyAbac - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/Cluster - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeDisableLegacyMetadataEndpoints"]: - action_type: DENY - condition: '(''disable-legacy-endpoints'' in resource.config.metadata && - - resource.config.metadata[''disable-legacy-endpoints''] == ''false'')' - description: Enforce that GKE clusters are created with legacy metadata endpoints - disabled - display_name: Disable legacy metadata endpoints - method_types: - - CREATE - - UPDATE - name: custom.gkeDisableLegacyMetadataEndpoints - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/NodePool - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireCOSImage"]: - action_type: DENY - condition: resource.config.imageType != "COS_CONTAINERD" - description: Enforce the nodes pool are using Container-Optimized OS for running - containers - display_name: Require Container-Optimized OS on node pools - method_types: - - CREATE - - UPDATE - name: custom.gkeRequireCOSImage - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/NodePool - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireConfidentialNodes"]: - action_type: DENY - condition: resource.confidentialNodes.enabled == false - description: Enforce that the GKE clusters is using confidential nodes - display_name: Require confidential nodes - method_types: - - CREATE - - UPDATE - name: custom.gkeRequireConfidentialNodes - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/Cluster - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireDataplaneV2"]: - action_type: DENY - condition: resource.networkConfig.datapathProvider != 'ADVANCED_DATAPATH' - description: Enforce that the GKE clusters is configured to use dataplane v2 - display_name: Require dataplane v2 - method_types: - - CREATE - - UPDATE - name: custom.gkeRequireDataplaneV2 - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/Cluster - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireGKEMetadataServer"]: - action_type: DENY - condition: resource.config.workloadMetadataConfig.mode != 'GKE_METADATA' - description: Enforce that GKE clusters are configured with GKE metadata server - enabled - display_name: Require GKE metadata server - method_types: - - CREATE - - UPDATE - name: custom.gkeRequireGKEMetadataServer - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/NodePool - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireIntegrityMonitoring"]: - action_type: DENY - condition: resource.config.shieldedInstanceConfig.enableIntegrityMonitoring == - false - description: Enforce that GKE nodes are configured with integrity monitoring enabled - display_name: Enable integrity monitoring - method_types: - - CREATE - - UPDATE - name: custom.gkeRequireIntegrityMonitoring - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/NodePool - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireIntraNodeVisibility"]: - action_type: DENY - condition: resource.networkConfig.enableIntraNodeVisibility == false - description: Enforce that GKE clusters intranode visibility is enabled - display_name: Enable intranode visibility - method_types: - - CREATE - - UPDATE - name: custom.gkeRequireIntraNodeVisibility - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/Cluster - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireMasterAuthorizedNetworks"]: - action_type: DENY - condition: resource.masterAuthorizedNetworksConfig.enabled == false - description: Enforce that GKE clusters restrict network access to the control - planes by configuring master authorized networks with authorized CIDR IP ranges - display_name: Require master authorized network with authorized CIDR IP ranges - method_types: - - CREATE - - UPDATE - name: custom.gkeRequireMasterAuthorizedNetworks - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/Cluster - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireMonitoring"]: - action_type: DENY - condition: resource.monitoringService != 'monitoring.googleapis.com/kubernetes' - description: Enforce that GKE clusters monitoring is enabled - display_name: Enable monitoring - method_types: - - CREATE - - UPDATE - name: custom.gkeRequireMonitoring - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/Cluster - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireNodePoolAutoRepair"]: - action_type: DENY - condition: resource.management.autoRepair == false - description: Enforce that GKE clusters are configured with node auto-repair enabled - display_name: Enable node auto-repair - method_types: - - CREATE - - UPDATE - name: custom.gkeRequireNodePoolAutoRepair - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/NodePool - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireNodePoolAutoUpgrade"]: - action_type: DENY - condition: resource.management.autoUpgrade == false - description: Enforce that GKE clusters are configured with node auto-upgrade enabled - display_name: Enable node auto-upgrade - method_types: - - CREATE - - UPDATE - name: custom.gkeRequireNodePoolAutoUpgrade - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/NodePool - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireNodePoolCMEKEncryption"]: - action_type: DENY - condition: has(resource.config.bootDiskKmsKey) == false - description: Enforce that GKE nodes are configured with CMEK Encryption - display_name: Require NodePool CMEK Encryption - method_types: - - CREATE - - UPDATE - name: custom.gkeRequireNodePoolCMEKEncryption - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/NodePool - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireNodePoolSandbox"]: - action_type: DENY - condition: "resource.name.matches(\"default-pool\") == false &&\n has(resource.config.sandboxConfig)\ - \ == false &&\n resource.config.sandboxConfig.type != 'GVISOR'" - description: Enforce that the GKE clusters nodes are isolated using GKE sandbox - (excepting the default node pool) - display_name: Require GKE Sandbox runtime - method_types: - - CREATE - - UPDATE - name: custom.gkeRequireNodePoolSandbox - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/NodePool - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeRequirePrivateEndpoint"]: - action_type: DENY - condition: resource.privateClusterConfig.enablePrivateEndpoint == false - description: Enforce that GKE clusters are created as private clusters with public - endpoint disabled - display_name: Disable public endpoints - method_types: - - CREATE - - UPDATE - name: custom.gkeRequirePrivateEndpoint - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/Cluster - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireRegionalClusters"]: - action_type: DENY - condition: resource.location.matches("^[a-z]+(-[a-z, 1-9]+)$") == false - description: Enforce the creation of regional GKE clusters - display_name: Require regional GKE cluster - method_types: - - CREATE - - UPDATE - name: custom.gkeRequireRegionalClusters - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/Cluster - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireSecureBoot"]: - action_type: DENY - condition: resource.config.shieldedInstanceConfig.enableSecureBoot == false - description: Enforce that GKE nodes are configured with secure boot enabled - display_name: Enable secure boot - method_types: - - CREATE - - UPDATE - name: custom.gkeRequireSecureBoot - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/NodePool - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.gkeRequireVPCNativeCluster"]: - action_type: DENY - condition: resource.ipAllocationPolicy.useIpAliases == false - description: Enforce that GKE clusters are created with VPC-native - display_name: Require VPC-native - method_types: - - CREATE - - UPDATE - name: custom.gkeRequireVPCNativeCluster - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/Cluster - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.iamAllowedMembers"]: - action_type: DENY - condition: "resource.bindings.exists(binding,\n binding.members.exists(member,\n\ - \ !MemberSubjectEndsWith(member, ['@${organization.domain}', '.gserviceaccount.com'])\n\ - \ )\n)" - description: Ensure no binding are done with members outside the organization - domain - display_name: Deny principals and members outside the organization domain - method_types: - - CREATE - - UPDATE - name: custom.iamAllowedMembers - parent: organizations/1234567890 - resource_types: - - iam.googleapis.com/AllowPolicy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.iamDisablePublicBindings"]: - action_type: DENY - condition: "resource.bindings.exists(binding,\n binding.members.exists(member,\n\ - \ MemberSubjectMatches(member, ['allUsers', 'allAuthenticatedUsers'])\n \ - \ )\n)" - description: Ensure no use of public bindings (allUsers, allAuthenticatedUsers) - display_name: Deny use of public access bindings with allUsers or allAuthenticatedUsers - method_types: - - CREATE - - UPDATE - name: custom.iamDisablePublicBindings - parent: organizations/1234567890 - resource_types: - - iam.googleapis.com/AllowPolicy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.iamDisableRedisAdminRoles"]: - action_type: DENY - condition: "resource.bindings.exists(binding,\n binding.members.exists(member,\n\ - \ !MemberSubjectMatches(member, []) &&\n (\n RoleNameMatches(binding.role,\ - \ ['roles/redis.admin']) ||\n RoleNameMatches(binding.role, ['roles/redis.editor'])\ - \ ||\n RoleNameContains(binding.role, ['roles/redis.viewer'])\n )\n\ - \ )\n)" - description: Ensure no use of the basic roles (viewer, editor and owner) - display_name: Deny use of the basic roles - method_types: - - CREATE - - UPDATE - name: custom.iamDisableRedisAdminRoles - parent: organizations/1234567890 - resource_types: - - iam.googleapis.com/AllowPolicy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.networkDisableTargetHTTPProxy"]: - action_type: DENY - condition: true == true - description: Ensure Target HTTP Proxy are not used - display_name: Deny usage and creation of Target HTTP Proxy - method_types: - - CREATE - - UPDATE - name: custom.networkDisableTargetHTTPProxy - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/TargetHttpProxy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.networkDisableWeakSSLPolicy"]: - action_type: DENY - condition: "(resource.profile == \"COMPATIBLE\") || (resource.profile == \"CUSTOM\"\ - \ &&\n resource.customFeatures.exists(feature, feature in [\n \"TLS_RSA_WITH_AES_128_GCM_SHA256\"\ - ,\n \"TLS_RSA_WITH_AES_256_GCM_SHA384\",\n \"TLS_RSA_WITH_AES_128_CBC_SHA\"\ - ,\n \"TLS_RSA_WITH_AES_256_CBC_SHA\",\n \"TLS_RSA_WITH_3DES_EDE_CBC_SHA\"\ - ,\n ])\n) || (resource.profile == \"CUSTOM\" &&\n resource.minTlsVersion in\ - \ [\"TLS_1_2\", \"TLS_1_3\"] == false\n) || (resource.profile == \"MODERN\"\ - \ &&\n resource.minTlsVersion in [\"TLS_1_2\", \"TLS_1_3\"] == false\n) ||\ - \ (resource.profile == \"RESTRICTED\" &&\n resource.minTlsVersion in [\"TLS_1_2\"\ - , \"TLS_1_3\"] == false\n)" - description: Ensure SSL Policies created does not have weak cipher suites - display_name: Deny usage of SSL Policies with weak cipher suites - method_types: - - CREATE - - UPDATE - name: custom.networkDisableWeakSSLPolicy - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/SslPolicy - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.networkRequireBackendServiceLogging"]: - action_type: DENY - condition: has(resource.logConfig) == false || resource.logConfig.enable == false - description: Enforce that Backend Services have logging enabled - display_name: Require logging to be enabled on Backend Services - method_types: - - CREATE - - UPDATE - name: custom.networkRequireBackendServiceLogging - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/BackendService - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.networkRequireCustomModeVpc"]: - action_type: DENY - condition: resource.autoCreateSubnetworks == true - description: Enforce that the subnets creation is using custom mode for a VPC - network - display_name: Require custom mode VPC network - method_types: - - CREATE - name: custom.networkRequireCustomModeVpc - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/Network - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.networkRequireSubnetPrivateGoogleAccess"]: - action_type: DENY - condition: '!resource.privateIpGoogleAccess && resource.purpose in [''REGIONAL_MANAGED_PROXY'', - ''GLOBAL_MANAGED_PROXY''] == false' - description: Enforce that the VPC network subnets are configured with private - Google access - display_name: Require Private Google Access - method_types: - - CREATE - name: custom.networkRequireSubnetPrivateGoogleAccess - parent: organizations/1234567890 - resource_types: - - compute.googleapis.com/Subnetwork - timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.storageRequireBucketObjectVersionning"]: - action_type: DENY - condition: resource.versioning.enabled == false - description: Enforce Cloud Storage bucket object versioning to be configured - display_name: Require object versioning - method_types: - - CREATE - - UPDATE - name: custom.storageRequireBucketObjectVersionning - parent: organizations/1234567890 - resource_types: - - storage.googleapis.com/Bucket - timeouts: null module.organization[0].google_organization_iam_custom_role.roles["cloudkms_viewer"]: description: Terraform-managed. org_id: '1234567890' @@ -6824,6 +7295,27 @@ values: role_id: tagViewer stage: GA title: Custom role tagViewer + ? module.organization[0].google_scc_management_organization_security_health_analytics_custom_module.scc_organization_custom_module["artifactregistryRequireCMEK"] + : custom_config: + - custom_output: [] + description: Detect if Artifact Registry repositories are not encrypted using + CMEK + predicate: + - description: null + expression: (!has(resource.kmsKeyName)) + location: null + title: null + recommendation: Ensure the Artifact Registry repositoriesa are encrypted using + CMEK + resource_selector: + - resource_types: + - artifactregistry.googleapis.com/Repository + severity: HIGH + display_name: artifactregistryRequireCMEK + enablement_state: ENABLED + location: global + organization: '1234567890' + timeouts: null ? module.organization[0].google_scc_management_organization_security_health_analytics_custom_module.scc_organization_custom_module["cloudfunctionsV1RequireIngressInternalAndLoadBalancer"] : custom_config: - custom_output: [] @@ -6864,6 +7356,27 @@ values: location: global organization: '1234567890' timeouts: null + ? module.organization[0].google_scc_management_organization_security_health_analytics_custom_module.scc_organization_custom_module["cloudkmsAllowedAlgorithms"] + : custom_config: + - custom_output: [] + description: Detect if the the algorithm for Cloud KMS keys is not configured + correctly + predicate: + - description: null + expression: resource.algorithm in ["GOOGLE_SYMMETRIC_ENCRYPTION", "EXTERNAL_SYMMETRIC_ENCRYPTION"] + == false + location: null + title: null + recommendation: Ensure the algorithm for Cloud KMS keys is configured correctly + resource_selector: + - resource_types: + - cloudkms.googleapis.com/CryptoKeyVersion + severity: MEDIUM + display_name: cloudkmsAllowedAlgorithms + enablement_state: ENABLED + location: global + organization: '1234567890' + timeouts: null ? module.organization[0].google_scc_management_organization_security_health_analytics_custom_module.scc_organization_custom_module["cloudkmsAllowedProtectionLevel"] : custom_config: - custom_output: [] @@ -7103,7 +7616,7 @@ values: than Dataplane V2 predicate: - description: null - expression: resource.networkConfig.datapathProvider == 'ADVANCED_DATAPATH' + expression: resource.networkConfig.datapathProvider != 'ADVANCED_DATAPATH' location: null title: null recommendation: Ensure only GKE Dataplane V2 are configured @@ -7196,6 +7709,10 @@ values: description: Allow all domains in DRS org policy. short_name: allowed-policy-member-domains-all timeouts: null + module.organization[0].google_tags_tag_value.default["org-policies/allowed-sa-impersonation"]: + description: Allow service account impersonation for tagged principals. + short_name: allowed-sa-impersonation + timeouts: null module.projects-observability[0].google_logging_metric.metrics["auditConfigChanges"]: bucket_options: [] description: Audit Configuration Changes @@ -8083,8 +8600,8 @@ counts: google_logging_project_bucket_config: 6 google_logging_project_settings: 3 google_monitoring_alert_policy: 10 - google_org_policy_custom_constraint: 80 - google_org_policy_policy: 155 + google_org_policy_custom_constraint: 89 + google_org_policy_policy: 170 google_organization_iam_audit_config: 1 google_organization_iam_binding: 40 google_organization_iam_custom_role: 14 @@ -8093,7 +8610,7 @@ counts: google_project_iam_member: 17 google_project_service: 37 google_project_service_identity: 11 - google_scc_management_organization_security_health_analytics_custom_module: 16 + google_scc_management_organization_security_health_analytics_custom_module: 18 google_service_account: 14 google_service_account_iam_binding: 2 google_service_account_iam_member: 4 @@ -8105,9 +8622,9 @@ counts: google_storage_project_service_account: 3 google_tags_tag_binding: 7 google_tags_tag_key: 3 - google_tags_tag_value: 5 + google_tags_tag_value: 6 google_tags_tag_value_iam_binding: 4 local_file: 9 modules: 58 - resources: 691 + resources: 718 terraform_data: 4 diff --git a/tests/fast/stages/s0_org_setup/simple.yaml b/tests/fast/stages/s0_org_setup/simple.yaml index d69d5bdee..c9c855a3a 100644 --- a/tests/fast/stages/s0_org_setup/simple.yaml +++ b/tests/fast/stages/s0_org_setup/simple.yaml @@ -1759,6 +1759,20 @@ values: intercept_children: false name: vpc-sc org_id: '1234567890' + module.organization-iam[0].google_org_policy_custom_constraint.constraint["custom.denyBridgePerimeters"]: + action_type: DENY + condition: resource.perimeterType == 'PERIMETER_TYPE_BRIDGE' + description: Disables the use of perimeter bridges. Instead, use ingress and egress + rules. + display_name: Disable perimeter bridges + method_types: + - CREATE + - UPDATE + name: custom.denyBridgePerimeters + parent: organizations/1234567890 + resource_types: + - accesscontextmanager.googleapis.com/ServicePerimeter + timeouts: null module.organization-iam[0].google_org_policy_policy.default["cloudbuild.disableCreateDefaultServiceAccount"]: dry_run_spec: [] name: organizations/1234567890/policies/cloudbuild.disableCreateDefaultServiceAccount @@ -2678,20 +2692,6 @@ values: organization: '1234567890' storage_location: europe-west1 timeouts: null - module.organization[0].google_org_policy_custom_constraint.constraint["custom.denyBridgePerimeters"]: - action_type: DENY - condition: resource.perimeterType == 'PERIMETER_TYPE_BRIDGE' - description: Disables the use of perimeter bridges. Instead, use ingress and egress - rules. - display_name: Disable perimeter bridges - method_types: - - CREATE - - UPDATE - name: custom.denyBridgePerimeters - parent: organizations/1234567890 - resource_types: - - accesscontextmanager.googleapis.com/ServicePerimeter - timeouts: null module.organization[0].google_organization_iam_custom_role.roles["network_firewall_policies_admin"]: description: Terraform-managed. org_id: '1234567890' diff --git a/tools/duplicate-diff.py b/tools/duplicate-diff.py index af94db4c2..e105c49f3 100755 --- a/tools/duplicate-diff.py +++ b/tools/duplicate-diff.py @@ -21,11 +21,6 @@ import os # List of folders and files that are expected to have same content duplicates = [ - # deep recursive folder comparison - [ - "fast/stages/0-org-setup/datasets/classic/organization/tags", - "fast/stages/0-org-setup/datasets/hardened/organization/tags", - ], # schemas [ "fast/stages/1-vpcsc/schemas/access-level.schema.json",