diff --git a/fast/stages/0-org-setup/datasets/hardened/README.md b/fast/stages/0-org-setup/datasets/hardened/README.md index b31b0ad5d..f212defe0 100644 --- a/fast/stages/0-org-setup/datasets/hardened/README.md +++ b/fast/stages/0-org-setup/datasets/hardened/README.md @@ -65,14 +65,17 @@ In that case, the controls placed in the `organization/scc-sha-custom-modules` f | `cloudbuild.allowedIntegrations` | Restrict Cloud Build integrations to an approved list. | | | `cloudbuild.allowedWorkerPools` | Restrict Cloud Build jobs to an authorized list of worker pools. | | | `cloudbuild.disableCreateDefaultServiceAccount` | Prevent Default Service Account for Cloud Build to be created | | -| `cloudfunctions.allowedVpcConnectorEgressSettings` | Ensure Cloud Functions Gen1 only allows internal and load balancer traffic. | | -| `cloudfunctions.requireVPCConnector` | Ensure Cloud Functions Gen1 are configured with a VPC connector. | | +| `cloudfunctions.allowedIngressSettings` | Ensure Cloud Functions Gen1 only allows internal and load balancer traffic. | | +| `cloudfunctions.allowedVpcConnectorEgressSettings` | Ensure Cloud Functions v1 Egress VPC Connector settings are configured correctly. | | +| `cloudfunctions.requireVPCConnector` | Ensure Cloud Functions v1 are configured with a VPC connector. | | | `compute.disableGuestAttributesAccess` | Prevent the use of Guest Attributes for Compute Engine instance metadata. | | | `compute.disableInternetNetworkEndpointGroup` | Prevent configuration of internet network endpoint groups. | | | `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.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 | | `compute.requireOsLogin` | Enforce the use of OS Login for all Compute Engine instances. | **CIS for GCP 3.0**: 4.4
**CIS Controls 8.0**: 5.6, 6.7
**PCI-DSS 4.0**: 1.2.5,
2.2.4
6.4.1
**NIST 800-53 R5**: AC-2
**ISO-2700-1 v2022**: A.5.15
**SOC2 v2017**: CC6.1.4, CC6.1.6, CC6.1.8, CC6.1.9 | | `compute.requireShieldedVm` | Enforce the use of Shielded VM for all Compute Engine instances. | **CIS for GCP 3.0**: 4.8 | | `compute.requireSslPolicy` | 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 | @@ -80,10 +83,12 @@ In that case, the controls placed in the `organization/scc-sha-custom-modules` f | `compute.restrictCloudNATUsage` | Restrict Cloud NAT usage to an authorized list. | | | `compute.restrictDedicatedInterconnectUsage` | Restrict the use of Dedicated Interconnect. | | | `compute.restrictLoadBalancerCreationForTypes` | Restrict the creation of load balancers based on type. | | +| `compute.restrictNonConfidentialComputing` | Enforce the use of Confidential Computing for all Compute Engine instances. | **CIS for GCP 3.0**: 4.11
**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
**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 | | `compute.restrictPartnerInterconnectUsage` | Restrict the use of Partner Interconnect. | | | `compute.restrictProtocolForwardingCreationForTypes` | Restrict the creation of forwarding rules based on type. | | | `compute.restrictSharedVpcHostProjects` | Restrict the use of Shared VPC host projects. | | | `compute.restrictVpcPeering` | Restrict the use of VPC peering. | | +| `compute.restrictVpnPeerIPs` | Restrict VPN peer IP addresses. | | | `compute.setNewProjectDefaultToZonalDNSOnly` | Ensure project created use Zonal DNS instead of global. | | | `compute.skipDefaultNetworkCreation` | Prevent the automatic creation of the default VPC network in new projects. | **CIS Controls 8.0**: 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**: ISV-04 | | `compute.trustedImageProjects` | Restrict the use of VM images to an authorized list of projects. | | @@ -93,13 +98,16 @@ In that case, the controls placed in the `organization/scc-sha-custom-modules` f | `container.managed.disableLegacyClientCertificateIssuance` | Prevent the use of legacy authentication methods for GKE API servers. | **CIS for GKE 1.5**: 2.1.1
5.8.1
**PCI-DSS 4.0**: 4.1 | | `container.managed.disableRBACSystemBindings` | Requires disabling RBAC bindings to system identities in GKE clusters. | | | `container.managed.disallowDefaultComputeServiceAccount` | Enforce that GKE cluster nodes are assigned with the least privileged service accounts | **CIS for GKE 1.5**: 5.2.1
**PCI-DSS 4.0**: 2.2.4, 7.2
**NIST 800-53 R4**: AC-6, SC-7
**ISO-2700-1 v2013**: A.9.2.3 | +| `container.managed.enableBinaryAuthorization` | Enforce the enablement of Binary Authorization on GKE clusters. | **CIS for GKE 1.5**: 5.1.4
5.10.3
5.10.4
**PCI-DSS 4.0**: 6.2.1 | | `container.managed.enableCloudLogging` | Enforce that GKE clusters logging is enabled | **CIS for GKE 1.5**: 5.7.1
**PCI-DSS 4.0**: 10.2 | +| `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.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.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 | @@ -113,7 +121,7 @@ In that case, the controls placed in the `organization/scc-sha-custom-modules` f | `iam.workloadIdentityPoolProviders` | Prevent creation of any workload identity pools except if expliicitely allowed. | | | `run.allowedBinaryAuthorizationPolicies` | Restrict Cloud Run services and jobs to an authorized list of Binary Authorization policies. | | | `run.allowedIngress` | Ensure Cloud Run services only allow internal and load balancer traffic. | | -| `run.allowedVPCEgress` | Ensure all traffic from Cloud Run services and jobs is routed through a VPC connector. | | +| `run.allowedVPCEgress` | Ensure all egress traffic from Cloud Run services and jobs is routed through a VPC network. | | | `run.managed.requireInvokerIam` | Enforce an IAM invoker check for Cloud Run services. | | | `sql.restrictAuthorizedNetworks` | Prevent the ability to add Authorized Networks for unproxied database access to Cloud SQL instances. | | | `sql.restrictPublicIp` | Ensure That Cloud SQL Database Instances Do Not Have Public IPs | **CIS for GCP 3.0**: 6.6
**CIS Controls 8.0**: 3.3, 4.6
**PCI-DSS 4.0**: 1.3.1
**NIST 800-53 R5**: AC-3, AC-5, AC-6, MA-4, MP-2
**NIST Cybersecurity Framework 1.0**: PR-AC-4
**ISO-2700-1 v2022**: A.5.10, A.5.15, A.8.3, A.8.4
**SOC2 v2017**: CC5.2.2, CC5.2.3, CC6.1.3, CC6.1.7
**HIPAA**: 164.308(a)(3)(i), 164.308(a)(3)(ii), 164.312(a)(1)
**Cloud Controls Matrix 4**: DSP-17 | @@ -128,24 +136,50 @@ 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. | | +| `cloudkmsAllowedProtectionLevel` | Ensure Cloud KMS keys are configured with the correct protection level. | | | `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. | | +| `cloudrunServiceDisableDefaultServiceAccount` | Ensure all Cloud Run services use a non-default service account. | | +| `cloudrunServiceRequireBinaryAuthorization` | Enforce all Cloud Run services use binary authorization. | | | `cloudsqlDisablePublicAuthorizedNetworks` | Ensure That Cloud SQL Database Instances Do Not Implicitly Whitelist All Public IP Addresses | **CIS for GCP 3.0**: 6.5
**CIS Controls 8.0**: 3.3
**PCI-DSS 4.0**: 1.3.1
**NIST 800-53 R4**: CA-3, SC-7
**NIST 800-53 R5**: AC-3, AC-5, AC-6, MP-2
**NIST Cybersecurity Framework 1.0**: PR-AC-4
**ISO-2700-1 v2013**: A.13.1.3, A.14.1.3, A.8.2.3
**ISO-2700-1 v2022**: A.5.10, A.5.15, A.8.3, A.8.4
**SOC2 v2017**: CC5.2.3, CC6.1.3, CC6.1.7
**HIPAA**: 164.308(a)(3)(i), 164.308(a)(3)(ii), 164.312(a)(1)
**Cloud Controls Matrix 4**: DSP-17 | | `cloudsqlEnforcePasswordComplexity` | Enforce password complexity for Cloud SQL instance users. | | | `cloudsqlRequireAutomatedBackup` | Ensure That Cloud SQL Database Instances Are Configured With Automated Backups | **CIS for GCP 3.0**: 6.7
**CIS Controls 8.0**: 11.2
**NIST 800-53 R4**: CP-9
**NIST 800-53 R5**: CP-10, CP-9
**NIST Cybersecurity Framework 1.0**: PR-IP-4
**ISO-2700-1 v2013**: A.12.3.1
**ISO-2700-1 v2022**: A.8.13
**HIPAA**: 164.308(a)(7)(ii) | +| `cloudsqlRequireHighAvailability` | Ensure Cloud SQL instances are configured for high availability. | | | `cloudsqlRequireMySQLDatabaseFlags` | Ensure ‘Skip_show_database’ Database Flag for Cloud SQL MySQL Instance Is Set to ‘On’ | **CIS for GCP 3.0**: 6.1.2
**CIS Controls 8.0**: 3.3
**PCI-DSS 4.0**: 1.3.1
**NIST 800-53 R5**: AC-3, AC-5, AC-6, MP-2
**NIST Cybersecurity Framework 1.0**: PR-AC-4
**ISO-2700-1 v2022**: A.5.10, A.5.15, A.8.3, A.8.4
**SOC2 v2017**: CC5.2.3, CC6.1.3, CC6.1.7
**HIPAA**: 164.308(a)(3)(i), 164.308(a)(3)(ii), 164.312(a)(1)
**Cloud Controls Matrix 4**: DSP-17 | | `cloudsqlRequirePointInTimeRecovery` | Enforce point-in-time recovery for all Cloud SQL backup configurations. | | | `cloudsqlRequirePostgreSQLDatabaseFlags` | Ensure That the ‘Log_connections’ Database Flag for Cloud SQL PostgreSQL Instance Is Set to ‘On’ | **CIS for GCP 3.0**: 6.2.2
**CIS Controls 8.0**: 8.5
**PCI-DSS 4.0**: 10.2.1, 10.2.1.2, 10.2.1.5, 9.4.5
**NIST 800-53 R5**: AU-12, AU-3, AU-7
**NIST Cybersecurity Framework 1.0**: DE-AE-3, DE-CM-1
**ISO-2700-1 v2022**: A.5.28, A.8.15
**SOC2 v2017**: CC5.2.3, CC7.2.1, CC7.2.2, CC7.2.3
**Cloud Controls Matrix 4**: DSP-17 | | `cloudsqlRequireRootPassword` | Ensure That a MySQL Database Instance Does Not Allow Anyone To Connect With Administrative Privileges | **CIS for GCP 3.0**: 6.1.1
**NIST 800-53 R4**: AC-3
**ISO-2700-1 v2013**: A.8.2.3, A.9.4.2
**ISO-2700-1 v2022**: A.8.5 | | `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. | | +| `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 | | `dnsRequireManageZoneDNSSEC` | Enforce the enablement of DNSSEC for all Cloud DNS zones. | **CIS for GCP 3.0**: 3.3
**CIS Controls 8.0**: 4.2
**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 R5**: AC-18, CM-2, CM-6, CM-7, CM-9
**NIST Cybersecurity Framework 1.0**: PR-IP-1
**ISO-2700-1 v2013**: A.8.2.3
**ISO-2700-1 v2022**: A.8.9
**SOC2 v2017**: CC5.2.2
**Cloud Controls Matrix 4**: ISV-04 | | `dnsRequirePolicyLogging` | Enforce the enablement of Cloud DNS logging for all VPC networks. | **CIS for GCP 3.0**: 2.12
**PCI-DSS 4.0**: 10.4.1, 10.4.1.1, 10.4.2, 10.4.3
**NIST 800-53 R5**: AU-6, AU-7
**NIST Cybersecurity Framework 1.0**: DE-AE-2, PR-PT-1, RS-AN-1
**ISO-2700-1 v2022**: A.5.25
**SOC2 v2017**: CC4.1.1, CC4.1.2, CC4.1.3, CC4.1.4, CC4.1.5, CC4.1.6, CC4.1.7, CC4.1.8, CC7.3.1, CC7.3.2, CC7.3.3, CC7.3.4, CC7.3.5
**HIPAA**: 164.308(a)(1)(ii), 164.312(b)
**Cloud Controls Matrix 4**: LOG-05 | | `firewallEnforcePolicyRuleLogging` | Enforce logging for Firewall Policy rules | **NIST 800-53 R4**: SI-4
**ISO-2700-1 v2013**: A.13.1.1 | | `firewallEnforceRuleLogging` | Enforce logging for VPC firewall rules | **NIST 800-53 R4**: SI-4
**ISO-2700-1 v2013**: A.13.1.1 | -| `firewallRestrictOpenWorldRule` | Prevent the creation of VPC firewall rules with a source or destination of `0.0.0.0/0`. | | +| `firewallRequireDescription` | Enforce a description for VPC firewall rules. | | +| `firewallRestrictCacheSearchDatabasesPolicyRule` | Prevent Cassandra 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 | +| `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 | +| `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 | +| `firewallRestrictMailProtocolsRule` | Prevent POP3 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 | +| `firewallRestrictManagementPortsPolicyRule` | Prevent Cisco Secure WebSM 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 | +| `firewallRestrictManagementPortsRule` | Prevent Cisco Secure WebSM 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 | +| `firewallRestrictNetworkServicesPolicyRule` | Prevent DNS 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 | +| `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`. | | | `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 | +| `firewallRestrictSQLDatabasesRule` | Prevent MySQL 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 | | `firewallRestrictSshPolicyRule` | Prevent SSH access from the internet via firewall policies. | **CIS for GCP 3.0**: 3.6
**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 | | `firewallRestrictSshRule` | Prevent SSH access from the internet via VPC firewall rules. | **CIS for GCP 3.0**: 3.6
**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 | | `gkeAllowedNodePoolImages` | Enforce that GKE nodes are using authorized node images | **CIS for GKE 1.5**: 5.5.1
**PCI-DSS 4.0**: 2.2.6, 5.2, 6.2.1 | @@ -155,6 +189,7 @@ In that case, the controls placed in the `organization/scc-sha-custom-modules` f | `gkeDisableLegacyAbac` | Enforce that GKE clusters is configured with no legacy ABAC enabled | **CIS for GKE 1.5**: 5.8.3
**PCI-DSS 4.0**: 4.1 | | `gkeDisableLegacyMetadataEndpoints` | Enforce that GKE clusters are created with legacy metadata endpoints disabled | **CIS for GKE 1.5**: 5.4.1 | | `gkeRequireCOSImage` | Enforce the nodes pool are using Container-Optimized OS for running containers | **PCI-DSS 4.0**: 2.2.6 | +| `gkeRequireConfidentialNodes` | Enforce that the GKE clusters is using confidential nodes | | | `gkeRequireDataplaneV2` | Enforce that the GKE clusters is configured to use dataplane v2 | | | `gkeRequireGKEMetadataServer` | Enforce that GKE clusters are configured with GKE metadata server enabled | **CIS for GKE 1.5**: 5.4.2 | | `gkeRequireIntegrityMonitoring` | Enforce that GKE nodes are configured with integrity monitoring enabled | **CIS for GKE 1.5**: 5.5.6 | @@ -163,6 +198,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 | +| `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 | | | `gkeRequireSecureBoot` | Enforce that GKE nodes are configured with secure boot enabled | **CIS for GKE 1.5**: 5.5.7 | @@ -173,6 +209,7 @@ In that case, the controls placed in the `organization/scc-sha-custom-modules` f | `networkRequireBackendServiceLogging` | Enforce the enablement of logging for all HTTP(S) load balancers. | **CIS for GCP 3.0**: 2.16
**CIS Controls 8.0**: 8.2
**PCI-DSS 4.0**: 10.2.1, 10.2.1.1, 10.2.1.2, 10.2.1.3, 10.2.1.4, 10.2.1.5, 10.2.1.6, 10.2.1.7, 10.2.2, 5.3.4, 6.4.1, 6.4.2
**NIST 800-53 R5**: AU-12, AU-2, AU-7
**NIST Cybersecurity Framework 1.0**: DE-AE-3, PR-PT-1
**ISO-2700-1 v2022**: A.8.15, A.8.20
**HIPAA**: 164.312(b) | | `networkRequireCustomModeVpc` | Ensure That the Default Network Does Not Exist in a Project | **CIS for GCP 3.0**: 3.1
**CIS Controls 8.0**: 4.2
**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 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**: ISV-04 | | `networkRequireSubnetPrivateGoogleAccess` | Enforce Private Google Access for all VPC network subnets. | | +| `storageRequireBucketObjectVersionning` | Enforce the enablement of versioning to Cloud Storage buckets where sinks are configured. | **NIST 800-53 R4**: AU-11
**ISO-2700-1 v2022**: A.12.4.2, A.18.1.3 | ### Detective Controls @@ -184,25 +221,33 @@ Complete list of built-in SCC SHA detectors is available here for more information. +SCC Custom SHA Detectors are available only for organization have subscribed to SCC Premium or Enterprise. Refer to for more information. | Module | Description | Compliance Mapping | |---|---|---| | `cloudfunctionsV1RequireIngressInternalAndLoadBalancer` | Ensure Cloud Functions Gen1 only allows internal and load balancer traffic. | | -| `cloudfunctionsV1RequireVPCConnector` | Ensure Cloud Functions Gen1 are configured with a VPC connector. | | +| `cloudfunctionsV1RequireVPCConnector` | Ensure Cloud Functions v1 are configured with a VPC connector. | | +| `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. | | | `cloudrunRequireBinaryAuthorization` | Restrict Cloud Run services and jobs to an authorized list of Binary Authorization policies. | | -| `cloudrunRequireEgressAllTraffic` | Ensure all traffic from Cloud Run services and jobs is routed through a VPC connector. | | +| `cloudrunRequireEgressAllTraffic` | Ensure all egress traffic from Cloud Run services and jobs is routed through a VPC network. | | | `cloudrunRequireIngressInternalAndLoadBalancer` | Ensure Cloud Run services only allow internal and load balancer traffic. | | +| `cloudsqlRequireHighAvailability` | Ensure Cloud SQL instances are configured for high availability. | | | `cloudsqlRequirePointInTimeRecovery` | Enforce point-in-time recovery for all Cloud SQL backup configurations. | | | `computeDisableNestedVirtualization` | Prevent the creation of Compute Engine instances with nested virtualization enabled. | | | `gkeDisableClientCertificateAuth` | Prevent the use of legacy authentication methods for GKE API servers. | **CIS for GKE 1.5**: 2.1.1
5.8.1
**PCI-DSS 4.0**: 4.1 | +| `gkeRequireConfidentialNodes` | Enforce that the GKE clusters is using confidential nodes | | | `gkeRequireDataplaneV2` | Enforce that the GKE clusters is configured to use dataplane v2 | | | `gkeRequireRegionalCluster` | Enforce the creation of regional GKE clusters | | +| `secretmanagerAllowedRotationPeriod` | Ensure the rotation period for secrets is configured correctly. | | #### Observability + | Alert | Description | Compliance Mapping | |---|---|---| | `auditConfigChanges` | Ensure log metric filters and alerts exist for audit configuration changes. | **CIS for GCP 3.0**: 2.5
**PCI-DSS 4.0**: 10.2.1, 10.2.1.1, 10.2.1.2, 10.2.1.3, 10.2.1.4, 10.2.1.5, 10.2.1.6, 10.2.1.7, 10.2.2, 5.3.4, 6.4.1, 6.4.2 | +| `binaryAuthorizationPolicyChanges` | Prevent changes to Binary Authorization policies that could weaken enforcement or evaluation modes. | | | `cloudsqlInstanceChanges` | Ensure log metric filters and alerts exist for Cloud SQL instance configuration changes. | **CIS for GCP 3.0**: 2.11
**PCI-DSS 4.0**: 10.2.1, 10.2.1.1, 10.2.1.2, 10.2.1.3, 10.2.1.4, 10.2.1.5, 10.2.1.6, 10.2.1.7, 10.2.2, 5.3.4, 6.4.1, 6.4.2 | | `customRoleChanges` | Ensure log metric filters and alerts exist for custom role changes. | **CIS for GCP 3.0**: 2.6
**PCI-DSS 4.0**: 10.2.1, 10.2.1.1, 10.2.1.2, 10.2.1.3, 10.2.1.4, 10.2.1.5, 10.2.1.6, 10.2.1.7, 10.2.2, 5.3.4, 6.4.1, 6.4.2 | | `firewallPolicyRuleChanges` | Ensure log metric filters and alerts exist for firewall policy rule changes. | **CIS for GCP 3.0**: 2.7
**PCI-DSS 4.0**: 10.2.1, 10.2.1.1, 10.2.1.2, 10.2.1.3, 10.2.1.4, 10.2.1.5, 10.2.1.6, 10.2.1.7, 10.2.2, 5.3.4, 6.4.1, 6.4.2 | @@ -216,6 +261,8 @@ SCC Custom SHA Detectors are available only for organization have subscribed to * For organizations with strict requirements to ensure resources are created and stored within specific geographic regions (e.g., for data sovereignty or regulatory compliance), you can enforce this by enabling the `gcp.resourceLocations` Organization Policy, which is defined in the [gcp.yaml](organization/org-policies/gcp.yaml) file. +* The `compute.restrictNonConfidentialComputing` policy is disabled by default in the hardened datasets. However, for organizations that require strict assurance that only Confidential Computing resources are used, this policy can be enabled. You can enforce this restriction by updating the configuration in the [compute.yaml](organization/org-policies/compute.yaml) file. + * The `compute.requireVpcFlowLogs` policy is enabled by default in the hardened datasets. This requires to update the `2-networking` stage to configure all subnets with **VPC Flow Logs**. Here is an example of a subnet configuration with `flow_logs_config` enabled: ```yaml name: dev-default @@ -261,6 +308,8 @@ compute.restrictVpcPeering: - "projects//global/networks/servicenetworking" ``` +* The `compute.managed.disableSerialPortLogging` policy is enabled by default in the hardened datasets to prevent sensitive information leakage. However, this policy must be disabled (set to enforce: false) for projects hosting Google Kubernetes Engine (GKE) clusters. Indeed, GKE requires serial port logging to be enabled to successfully create clusters and manage low-level troubleshooting. + ## Troubleshooting ### Custom Organization Policy Concurrency Issue diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/.config.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/.config.yaml index 93fab0897..fd43bb757 100644 --- a/fast/stages/0-org-setup/datasets/hardened/organization/.config.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/organization/.config.yaml @@ -94,8 +94,10 @@ iam_by_principals: - roles/accesscontextmanager.policyReader - roles/cloudasset.viewer data_access_logs: - sts.googleapis.com: + allServices: ADMIN_READ: {} + # DATA_READ: {} + # DATA_WRITE: {} logging: # disable_default_log_sink: false storage_location: $locations:primary diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudkmsAllowedProtectionLevel.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudkmsAllowedProtectionLevel.yaml new file mode 100644 index 000000000..9e3665ef0 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudkmsAllowedProtectionLevel.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.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 + resource_types: + - cloudkms.googleapis.com/CryptoKey diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudrunJobDisableDefaultServiceAccount.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudrunJobDisableDefaultServiceAccount.yaml new file mode 100644 index 000000000..5a2def08b --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudrunJobDisableDefaultServiceAccount.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.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 + resource_types: + - run.googleapis.com/Job diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudrunServiceDisableDefaultServiceAccount.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudrunServiceDisableDefaultServiceAccount.yaml new file mode 100644 index 000000000..91f53439b --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudrunServiceDisableDefaultServiceAccount.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.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 + resource_types: + - run.googleapis.com/Service diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudsqlRequireHighAvailability.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudsqlRequireHighAvailability.yaml new file mode 100644 index 000000000..c74cb70c2 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.cloudsqlRequireHighAvailability.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.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 + resource_types: + - sqladmin.googleapis.com/Instance diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.dataprocDisableDefaultServiceAccount.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.dataprocDisableDefaultServiceAccount.yaml new file mode 100644 index 000000000..9b4b55387 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.dataprocDisableDefaultServiceAccount.yaml @@ -0,0 +1,27 @@ +# 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.dataprocDisableDefaultServiceAccount: + action_type: DENY + condition: |- + has(resource.config.gceClusterConfig.serviceAccount) == false || + 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 + resource_types: + - dataproc.googleapis.com/Cluster diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.dataprocRequireInternalIp.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.dataprocRequireInternalIp.yaml new file mode 100644 index 000000000..ec5fc02ef --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.dataprocRequireInternalIp.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.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 + resource_types: + - dataproc.googleapis.com/Cluster diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.dataprocRequireKerberos.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.dataprocRequireKerberos.yaml new file mode 100644 index 000000000..be2c75fc2 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.dataprocRequireKerberos.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.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 + resource_types: + - dataproc.googleapis.com/Cluster diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRequireDescription.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRequireDescription.yaml new file mode 100644 index 000000000..1229fa641 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRequireDescription.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.firewallRequireDescription: + action_type: DENY + condition: |- + ( + resource.description == "" && + !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 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 + resource_types: + - compute.googleapis.com/Firewall diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictCacheSearchDatabasesPolicyRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictCacheSearchDatabasesPolicyRule.yaml new file mode 100644 index 000000000..fa0b38052 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictCacheSearchDatabasesPolicyRule.yaml @@ -0,0 +1,43 @@ +# 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.firewallRestrictCacheSearchDatabasesPolicyRule: + action_type: DENY + condition: |- + resource.rules.exists(r, r.priority < 2147483644 && r.direction == 'INGRESS' && + r.match.srcIpRanges.exists(r, r == '0.0.0.0/0') && + ( + r.match.layer4Configs.containsIpProtocolAndPort('tcp', '6379') || + r.match.layer4Configs.containsIpProtocolAndPort('udp', '6379') || + r.match.layer4Configs.containsIpProtocolAndPort('tcp', '9200') || + r.match.layer4Configs.containsIpProtocolAndPort('udp', '9200') || + r.match.layer4Configs.containsIpProtocolAndPort('tcp', '9300') || + r.match.layer4Configs.containsIpProtocolAndPort('udp', '9300') || + r.match.layer4Configs.containsIpProtocolAndPort('tcp', '11211') || + r.match.layer4Configs.containsIpProtocolAndPort('udp', '11211') || + r.match.layer4Configs.containsIpProtocolAndPort('tcp', '11214') || + r.match.layer4Configs.containsIpProtocolAndPort('udp', '11214') || + r.match.layer4Configs.containsIpProtocolAndPort('tcp', '11215') || + r.match.layer4Configs.containsIpProtocolAndPort('udp', '11215') + ) + ) + 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 + resource_types: + - compute.googleapis.com/FirewallPolicy diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictCacheSearchDatabasesRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictCacheSearchDatabasesRule.yaml new file mode 100644 index 000000000..d4e24143e --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictCacheSearchDatabasesRule.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.firewallRestrictCacheSearchDatabasesRule: + action_type: DENY + condition: |- + resource.direction.matches('INGRESS') && + resource.sourceRanges.exists(range, range == '0.0.0.0/0') && + ( + resource.allowed.containsFirewallPort('tcp', '9200') || + resource.allowed.containsFirewallPort('tcp', '9300') || + resource.allowed.containsFirewallPort('tcp', '11211') || + resource.allowed.containsFirewallPort('tcp', '11214') || + resource.allowed.containsFirewallPort('tcp', '11215') || + resource.allowed.containsFirewallPort('tcp', '6379') || + resource.allowed.containsFirewallPort('udp', '11211') || + resource.allowed.containsFirewallPort('udp', '11214') || + resource.allowed.containsFirewallPort('udp', '11215') + ) + 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 + resource_types: + - compute.googleapis.com/Firewall diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictDirectoryServicesPolicyRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictDirectoryServicesPolicyRule.yaml new file mode 100644 index 000000000..116aed1ab --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictDirectoryServicesPolicyRule.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.firewallRestrictDirectoryServicesPolicyRule: + action_type: DENY + condition: |- + resource.rules.exists(rule, + rule.priority < 2147483644 && + rule.direction == 'INGRESS' && + rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0') && + ( + rule.match.layer4Configs.containsIpProtocolAndPort('udp', '445') || + rule.match.layer4Configs.containsIpProtocolAndPort('udp', '389') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '445') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '389') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '636') + ) + ) + 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 + resource_types: + - compute.googleapis.com/FirewallPolicy diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictDirectoryServicesRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictDirectoryServicesRule.yaml new file mode 100644 index 000000000..9c94b85c4 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictDirectoryServicesRule.yaml @@ -0,0 +1,35 @@ +# 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.firewallRestrictDirectoryServicesRule: + action_type: DENY + condition: |- + resource.direction.matches('INGRESS') && + resource.sourceRanges.exists(range, range == '0.0.0.0/0') && + ( + resource.allowed.containsFirewallPort('tcp', '445') || + resource.allowed.containsFirewallPort('tcp', '389') || + resource.allowed.containsFirewallPort('tcp', '636') || + resource.allowed.containsFirewallPort('udp', '445') || + resource.allowed.containsFirewallPort('udp', '389') + ) + 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 + resource_types: + - compute.googleapis.com/Firewall diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictInsecureProtocolsPolicyRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictInsecureProtocolsPolicyRule.yaml new file mode 100644 index 000000000..e6abf64ec --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictInsecureProtocolsPolicyRule.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.firewallRestrictInsecureProtocolsPolicyRule: + action_type: DENY + condition: |- + resource.rules.exists(rule, + rule.priority < 2147483644 && + rule.direction == 'INGRESS' && + rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0') && + ( + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '21') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '23') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '80') + ) + ) + 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 + resource_types: + - compute.googleapis.com/FirewallPolicy diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictInsecureProtocolsRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictInsecureProtocolsRule.yaml new file mode 100644 index 000000000..af163c13a --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictInsecureProtocolsRule.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.firewallRestrictInsecureProtocolsRule: + action_type: DENY + condition: |- + resource.direction.matches('INGRESS') && + resource.sourceRanges.exists(range, range == '0.0.0.0/0') && + ( + resource.allowed.containsFirewallPort('tcp', '21') || + resource.allowed.containsFirewallPort('tcp', '23') || + resource.allowed.containsFirewallPort('tcp', '80') + ) + 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 + resource_types: + - compute.googleapis.com/Firewall diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictMailProtocolsPolicyRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictMailProtocolsPolicyRule.yaml new file mode 100644 index 000000000..c68f87893 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictMailProtocolsPolicyRule.yaml @@ -0,0 +1,35 @@ +# 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.firewallRestrictMailProtocolsPolicyRule: + action_type: DENY + condition: |- + resource.rules.exists(rule, + rule.priority < 2147483644 && + rule.direction == 'INGRESS' && + rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0') && + ( + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '25') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '110') + ) + ) + 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 + resource_types: + - compute.googleapis.com/FirewallPolicy diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictMailProtocolsRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictMailProtocolsRule.yaml new file mode 100644 index 000000000..f35648a51 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictMailProtocolsRule.yaml @@ -0,0 +1,32 @@ +# 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.firewallRestrictMailProtocolsRule: + action_type: DENY + condition: |- + resource.direction.matches('INGRESS') && + resource.sourceRanges.exists(range, range == '0.0.0.0/0') && + ( + resource.allowed.containsFirewallPort('tcp', '25') || + resource.allowed.containsFirewallPort('tcp', '110') + ) + 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 + resource_types: + - compute.googleapis.com/Firewall diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictManagementPortsPolicyRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictManagementPortsPolicyRule.yaml new file mode 100644 index 000000000..5d9378d0f --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictManagementPortsPolicyRule.yaml @@ -0,0 +1,32 @@ +# 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.firewallRestrictManagementPortsPolicyRule: + action_type: DENY + condition: |- + resource.rules.exists(rule, + rule.priority < 2147483644 && + rule.direction == 'INGRESS' && + rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0') && + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '9090') + ) + 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 + resource_types: + - compute.googleapis.com/FirewallPolicy diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictManagementPortsRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictManagementPortsRule.yaml new file mode 100644 index 000000000..d958561f0 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictManagementPortsRule.yaml @@ -0,0 +1,29 @@ +# 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.firewallRestrictManagementPortsRule: + action_type: DENY + condition: |- + resource.direction.matches('INGRESS') && + resource.sourceRanges.exists(range, range == '0.0.0.0/0') && + 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 + resource_types: + - compute.googleapis.com/Firewall diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictNetworkServicesPolicyRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictNetworkServicesPolicyRule.yaml new file mode 100644 index 000000000..9a930d343 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictNetworkServicesPolicyRule.yaml @@ -0,0 +1,41 @@ +# 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.firewallRestrictNetworkServicesPolicyRule: + action_type: DENY + condition: |- + resource.rules.exists(rule, + rule.priority < 2147483644 && + rule.direction == 'INGRESS' && + rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0') && + ( + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '53') || + rule.match.layer4Configs.containsIpProtocolAndPort('udp', '53') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '137') || + rule.match.layer4Configs.containsIpProtocolAndPort('udp', '137') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '138') || + rule.match.layer4Configs.containsIpProtocolAndPort('udp', '138') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '139') || + rule.match.layer4Configs.containsIpProtocolAndPort('udp', '139') + ) + ) + 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 + resource_types: + - compute.googleapis.com/FirewallPolicy diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictNetworkServicesRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictNetworkServicesRule.yaml new file mode 100644 index 000000000..ed0f6892f --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictNetworkServicesRule.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.firewallRestrictNetworkServicesRule: + action_type: DENY + condition: |- + resource.direction.matches('INGRESS') && + resource.sourceRanges.exists(range, range == '0.0.0.0/0') && + ( + resource.allowed.containsFirewallPort('tcp', '53') || + resource.allowed.containsFirewallPort('udp', '53') || + resource.allowed.containsFirewallPort('tcp', '137') || + resource.allowed.containsFirewallPort('udp', '137') || + resource.allowed.containsFirewallPort('tcp', '138') || + resource.allowed.containsFirewallPort('udp', '138') || + resource.allowed.containsFirewallPort('tcp', '139') || + resource.allowed.containsFirewallPort('udp', '139') + ) + 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 + resource_types: + - compute.googleapis.com/Firewall diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictNoSQLDatabasesPolicyRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictNoSQLDatabasesPolicyRule.yaml new file mode 100644 index 000000000..a91402eb5 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictNoSQLDatabasesPolicyRule.yaml @@ -0,0 +1,44 @@ +# 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.firewallRestrictNoSQLDatabasesPolicyRule: + action_type: DENY + condition: |- + resource.rules.exists(rule, + rule.priority < 2147483644 && + rule.direction == 'INGRESS' && + rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0') && + ( + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '7000') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '7001') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '7199') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '8888') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '9042') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '9160') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '61620') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '61621') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '27017') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '27018') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '27019') + ) + ) + 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 + resource_types: + - compute.googleapis.com/FirewallPolicy diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictNoSQLDatabasesRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictNoSQLDatabasesRule.yaml new file mode 100644 index 000000000..14a57d11c --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictNoSQLDatabasesRule.yaml @@ -0,0 +1,41 @@ +# 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.firewallRestrictNoSQLDatabasesRule: + action_type: DENY + condition: |- + resource.direction.matches('INGRESS') && + resource.sourceRanges.exists(range, range == '0.0.0.0/0') && + ( + resource.allowed.containsFirewallPort('tcp', '7000') || + resource.allowed.containsFirewallPort('tcp', '7001') || + resource.allowed.containsFirewallPort('tcp', '7199') || + resource.allowed.containsFirewallPort('tcp', '8888') || + resource.allowed.containsFirewallPort('tcp', '9042') || + resource.allowed.containsFirewallPort('tcp', '9160') || + resource.allowed.containsFirewallPort('tcp', '61620') || + resource.allowed.containsFirewallPort('tcp', '61621') || + resource.allowed.containsFirewallPort('tcp', '27017') || + resource.allowed.containsFirewallPort('tcp', '27018') || + resource.allowed.containsFirewallPort('tcp', '27019') + ) + 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 + resource_types: + - compute.googleapis.com/Firewall diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictSQLDatabasesPolicyRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictSQLDatabasesPolicyRule.yaml new file mode 100644 index 000000000..cdad9f2eb --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictSQLDatabasesPolicyRule.yaml @@ -0,0 +1,41 @@ +# 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.firewallRestrictSQLDatabasesPolicyRule: + action_type: DENY + condition: |- + resource.rules.exists(rule, + rule.priority < 2147483644 && + rule.direction == 'INGRESS' && + rule.match.srcIpRanges.exists(range, range == '0.0.0.0/0') && + ( + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '3306') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '1521') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '2483') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '2484') || + rule.match.layer4Configs.containsIpProtocolAndPort('tcp', '5432') || + rule.match.layer4Configs.containsIpProtocolAndPort('udp', '2483') || + rule.match.layer4Configs.containsIpProtocolAndPort('udp', '2484') || + rule.match.layer4Configs.containsIpProtocolAndPort('udp', '5432') + ) + ) + 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 + resource_types: + - compute.googleapis.com/FirewallPolicy diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictSQLDatabasesRule.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictSQLDatabasesRule.yaml new file mode 100644 index 000000000..549e213b1 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.firewallRestrictSQLDatabasesRule.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.firewallRestrictSQLDatabasesRule: + action_type: DENY + condition: |- + resource.direction.matches('INGRESS') && + resource.sourceRanges.exists(range, range == '0.0.0.0/0') && + ( + resource.allowed.containsFirewallPort('tcp', '3306') || + resource.allowed.containsFirewallPort('tcp', '1521') || + resource.allowed.containsFirewallPort('tcp', '2483') || + resource.allowed.containsFirewallPort('tcp', '2484') || + resource.allowed.containsFirewallPort('tcp', '5432') || + resource.allowed.containsFirewallPort('udp', '2483') || + resource.allowed.containsFirewallPort('udp', '2484') || + resource.allowed.containsFirewallPort('udp', '5432') + ) + 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 + resource_types: + - compute.googleapis.com/Firewall diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireConfidentialNodes.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireConfidentialNodes.yaml new file mode 100644 index 000000000..3dd4fd157 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/custom-constraints/custom.gkeRequireConfidentialNodes.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.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 + resource_types: + - container.googleapis.com/Cluster diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/observability/binaryAuthorizationPolicyChanges.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/observability/binaryAuthorizationPolicyChanges.yaml new file mode 100644 index 000000000..61260d694 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/observability/binaryAuthorizationPolicyChanges.yaml @@ -0,0 +1,74 @@ +# 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. + +alerts: + binaryAuthorizationPolicyChanges: + combiner: OR + conditions: + - condition_threshold: + aggregations: + - alignment_period: 60s + cross_series_reducer: REDUCE_SUM + group_by_fields: + - metric.label.principal + - metric.label.method_name + - metric.label.project_id + per_series_aligner: ALIGN_SUM + comparison: COMPARISON_GT + duration: 0s + filter: + resource.type = "logging_bucket" AND metric.type = + "logging.googleapis.com/user/binaryAuthorizationPolicyChanges" + threshold_value: 0 + trigger: + count: 1 + display_name: "Log match condition: Binary Authorization policy configuration changes" + display_name: Binary Authorization Policy Changes + documentation: + content: |- + Log-based alerting policy in project ${project} detected for a change to Binary Authorization + project-singleton policy, weakening the enforcement or evaluation modes. + + This alert helps ensure security by monitoring configuration changes to Binary Authorization policies. + ``` + protoPayload.methodName="google.cloud.binaryauthorization.v1.BinauthzManagementServiceV1.UpdatePolicy" AND + protoPayload.serviceName="binaryauthorization.googleapis.com" AND + ("ALWAYS_ALLOW" OR "DRYRUN_AUDIT_LOG_ONLY") + ``` + mime_type: text/markdown +logging_metrics: + binaryAuthorizationPolicyChanges: + bucket_name: log-0/audit-logs + description: Binary Authorization Policy Changes + filter: + protoPayload.methodName="google.cloud.binaryauthorization.v1.BinauthzManagementServiceV1.UpdatePolicy" AND + protoPayload.serviceName="binaryauthorization.googleapis.com" AND ("ALWAYS_ALLOW" OR "DRYRUN_AUDIT_LOG_ONLY") + label_extractors: + method_name: EXTRACT(protoPayload.methodName) + principal: EXTRACT(protoPayload.authenticationInfo.principalEmail) + project_id: EXTRACT(labels.project_id) + metric_descriptor: + labels: + - description: principal + key: principal + value_type: STRING + - description: method_name + key: method_name + value_type: STRING + - description: project_id + key: project_id + value_type: STRING + metric_kind: DELTA + unit: "1" + value_type: INT64 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 new file mode 100644 index 000000000..48b8a7a13 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/cloudkms.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. + +--- +# 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 + +custom.cloudkmsAllowedProtectionLevel: + rules: + - enforce: true diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/compute.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/compute.yaml index cf0e2d1ae..41383b649 100644 --- a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/compute.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/compute.yaml @@ -42,6 +42,14 @@ compute.managed.blockPreviewFeatures: rules: - enforce: true +compute.managed.disableSerialPortLogging: + rules: + - enforce: true + +compute.managed.vmCanIpForward: + rules: + - enforce: true + compute.requireOsLogin: rules: - enforce: true @@ -62,6 +70,13 @@ compute.restrictLoadBalancerCreationForTypes: values: - "in:INTERNAL" +# compute.restrictNonConfidentialComputing: +# rules: +# - deny: +# values: +# - "compute.googleapis.com" +# - "container.googleapis.com" + compute.restrictProtocolForwardingCreationForTypes: rules: - allow: diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/dataproc.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/dataproc.yaml new file mode 100644 index 000000000..3e2f0ffe6 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/dataproc.yaml @@ -0,0 +1,31 @@ +# 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 + +custom.dataprocDisableDefaultServiceAccount: + rules: + - enforce: true + +custom.dataprocRequireInternalIp: + rules: + - enforce: true + +custom.dataprocRequireKerberos: + rules: + - enforce: true 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 046134ee7..9d15f7c24 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 @@ -26,6 +26,66 @@ custom.firewallEnforceRuleLogging: rules: - enforce: true +custom.firewallRequireDescription: + rules: + - enforce: true + +custom.firewallRestrictCacheSearchDatabasesPolicyRule: + rules: + - enforce: true + +custom.firewallRestrictCacheSearchDatabasesRule: + rules: + - enforce: true + +custom.firewallRestrictDirectoryServicesPolicyRule: + rules: + - enforce: true + +custom.firewallRestrictDirectoryServicesRule: + rules: + - enforce: true + +custom.firewallRestrictInsecureProtocolsPolicyRule: + rules: + - enforce: true + +custom.firewallRestrictInsecureProtocolsRule: + rules: + - enforce: true + +custom.firewallRestrictMailProtocolsPolicyRule: + rules: + - enforce: true + +custom.firewallRestrictMailProtocolsRule: + rules: + - enforce: true + +custom.firewallRestrictManagementPortsPolicyRule: + rules: + - enforce: true + +custom.firewallRestrictManagementPortsRule: + rules: + - enforce: true + +custom.firewallRestrictNetworkServicesPolicyRule: + rules: + - enforce: true + +custom.firewallRestrictNetworkServicesRule: + rules: + - enforce: true + +custom.firewallRestrictNoSQLDatabasesPolicyRule: + rules: + - enforce: true + +custom.firewallRestrictNoSQLDatabasesRule: + rules: + - enforce: true + custom.firewallRestrictPublicAccessRule: rules: - enforce: true @@ -38,6 +98,14 @@ custom.firewallRestrictRdpRule: rules: - enforce: true +custom.firewallRestrictSQLDatabasesPolicyRule: + rules: + - enforce: true + +custom.firewallRestrictSQLDatabasesRule: + rules: + - enforce: true + custom.firewallRestrictSshPolicyRule: rules: - enforce: true diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/gcp.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/gcp.yaml index c3e6f6626..dd4c16a99 100644 --- a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/gcp.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/gcp.yaml @@ -26,3 +26,4 @@ # - "in:eu-locations" # - "in:europe-west1-locations" # - "in:europe-west4-locations" + 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 c8ca2125f..8e0f40544 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 @@ -38,10 +38,18 @@ container.managed.disallowDefaultComputeServiceAccount: rules: - enforce: true +container.managed.enableBinaryAuthorization: + rules: + - enforce: true + container.managed.enableCloudLogging: rules: - enforce: true +container.managed.enableGoogleGroupsRBAC: + rules: + - enforce: true + container.managed.enableNetworkPolicy: rules: - enforce: true @@ -86,6 +94,10 @@ custom.gkeDisableLegacyMetadataEndpoints: rules: - enforce: true +# custom.gkeRequireConfidentialNodes: +# rules: +# - enforce: true + custom.gkeRequireCOSImage: rules: - enforce: true @@ -122,6 +134,10 @@ custom.gkeRequireNodePoolAutoUpgrade: rules: - enforce: true +custom.gkeRequireNodePoolSandbox: + rules: + - enforce: true + custom.gkeRequirePrivateEndpoint: 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 e6e5e7a3e..d1e5f7f57 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,10 @@ # yaml-language-server: $schema=../../../../schemas/org-policies.schema.json +custom.iamDisableRedisAdminRoles: + rules: + - enforce: false + iam.allowedPolicyMemberDomains: rules: - allow: diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/network.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/network.yaml index 2148e1460..a547be267 100644 --- a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/network.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/network.yaml @@ -56,6 +56,13 @@ compute.restrictVpcPeering: values: - "under:organizations/${organization.id}" +# compute.restrictVpnPeerIPs: +# rules: +# - allow: +# values: +# - "1.1.1.1" +# - "2.2.2.2" + custom.networkDisableTargetHTTPProxy: rules: - enforce: true diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/serverless.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/serverless.yaml index b8c3d5f51..9995cdd90 100644 --- a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/serverless.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/serverless.yaml @@ -18,6 +18,12 @@ # yaml-language-server: $schema=../../../../schemas/org-policies.schema.json +cloudfunctions.allowedIngressSettings: + rules: + - allow: + values: + - "ALLOW_INTERNAL_AND_GCLB" + cloudfunctions.allowedVpcConnectorEgressSettings: rules: - allow: @@ -32,6 +38,22 @@ custom.cloudrunDisableEnvironmentVariablePattern: rules: - enforce: true +custom.cloudrunJobDisableDefaultServiceAccount: + rules: + - enforce: true + +custom.cloudrunJobRequireBinaryAuthorization: + rules: + - enforce: true + +custom.cloudrunServiceDisableDefaultServiceAccount: + rules: + - enforce: true + +custom.cloudrunServiceRequireBinaryAuthorization: + rules: + - enforce: true + run.allowedBinaryAuthorizationPolicies: rules: - allow: diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/sql.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/sql.yaml index 2a6018d7e..789a4ede1 100644 --- a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/sql.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/sql.yaml @@ -30,6 +30,10 @@ custom.cloudsqlRequireAutomatedBackup: rules: - enforce: true +custom.cloudsqlRequireHighAvailability: + rules: + - enforce: true + custom.cloudsqlRequireMySQLDatabaseFlags: rules: - enforce: true @@ -38,6 +42,10 @@ custom.cloudsqlRequirePointInTimeRecovery: rules: - enforce: true +custom.cloudsqlRequirePostgreSQLDatabaseAdditionalFlags: + rules: + - enforce: false + custom.cloudsqlRequirePostgreSQLDatabaseFlags: rules: - enforce: true diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/storage.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/storage.yaml index 09243eb92..619b60e92 100644 --- a/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/storage.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/organization/org-policies/storage.yaml @@ -18,6 +18,10 @@ # yaml-language-server: $schema=../../../../schemas/org-policies.schema.json +# custom.storageRequireBucketObjectVersionning: +# rules: +# - enforce: true + storage.publicAccessPrevention: rules: - enforce: true diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudkmsAllowedProtectionLevel.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudkmsAllowedProtectionLevel.yaml new file mode 100644 index 000000000..b27e53631 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudkmsAllowedProtectionLevel.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. + +cloudkmsAllowedProtectionLevel: + description: Detect if the protection level for Cloud KMS keys is not configured correctly + predicate: + expression: resource.primary.protectionLevel in ["SOFTWARE"] == false + recommendation: Ensure the protection level for Cloud KMS keys is configured correctly + resource_selector: + resource_types: + - cloudkms.googleapis.com/CryptoKey + severity: MEDIUM diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudrunDisableJobDefaultServiceAccount.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudrunDisableJobDefaultServiceAccount.yaml new file mode 100644 index 000000000..2af3a60b8 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudrunDisableJobDefaultServiceAccount.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. + +cloudrunDisableJobDefaultServiceAccount: + description: Detect if default service accounts are used by Cloud Run jobs + predicate: + expression: resource.spec.template.spec.template.spec.serviceAccountName.endsWith("@developer.gserviceaccount.com") + recommendation: Ensure only authorized non-default service accounts are used by Cloud Run jobs + resource_selector: + resource_types: + - run.googleapis.com/Job + severity: HIGH diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudrunDisableServiceDefaultServiceAccount.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudrunDisableServiceDefaultServiceAccount.yaml new file mode 100644 index 000000000..d6d2086fd --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudrunDisableServiceDefaultServiceAccount.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. + +cloudrunDisableServiceDefaultServiceAccount: + description: Detect if default service accounts are used by Cloud Run services + predicate: + expression: resource.spec.template.spec.serviceAccountName.endsWith("@developer.gserviceaccount.com") + recommendation: Ensure only authorized non-default service accounts are used by Cloud Run services + resource_selector: + resource_types: + - run.googleapis.com/Service + severity: HIGH diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudrunRequireEgressAllTraffic.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudrunRequireEgressAllTraffic.yaml new file mode 100644 index 000000000..5676e28f8 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudrunRequireEgressAllTraffic.yaml @@ -0,0 +1,28 @@ +# 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. + +cloudrunRequireEgressAllTraffic: + description: + Detect if Cloud Run services and jobs are not configured to route all egress traffic through the VPC network + predicate: + expression: |- + ( + !resource.spec.template.metadata.annotations['run.googleapis.com/vpc-access-egress'].matches('all-traffic') + ) + recommendation: Ensure Cloud Run services and jobs are configured to route all egress traffic through the VPC network + resource_selector: + resource_types: + - run.googleapis.com/Service + - run.googleapis.com/Job + severity: HIGH diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudsqlRequireHighAvailability.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudsqlRequireHighAvailability.yaml new file mode 100644 index 000000000..3fb2f3339 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/cloudsqlRequireHighAvailability.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. + +cloudsqlRequireHighAvailability: + description: Detect if the high availability (HA) configuration for Cloud SQL instances is not set to regional + predicate: + expression: (resource.settings.availabilityType != "REGIONAL") + recommendation: Ensure if the HA configuration for all Cloud SQL instances is set regional + resource_selector: + resource_types: + - sqladmin.googleapis.com/Instance + severity: MEDIUM diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/gkeRequireConfidentialNodes.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/gkeRequireConfidentialNodes.yaml new file mode 100644 index 000000000..665e9ce98 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/gkeRequireConfidentialNodes.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. + +gkeRequireConfidentialNodes: + description: Detect if any GKE clusters are running without Confidential GKE nodes + predicate: + expression: (resource.confidentialNodes.enabled == false) + recommendation: Ensure GKE clusters are running with Confidential GKE nodes enabled + resource_selector: + resource_types: + - container.googleapis.com/Cluster + severity: MEDIUM diff --git a/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/secretmanagerAllowedRotationPeriod.yaml b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/secretmanagerAllowedRotationPeriod.yaml new file mode 100644 index 000000000..9089c4179 --- /dev/null +++ b/fast/stages/0-org-setup/datasets/hardened/organization/scc-sha-custom-modules/secretmanagerAllowedRotationPeriod.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. + +secretmanagerAllowedRotationPeriod: + description: Detect if the rotation period for secrets are not configured correctly + predicate: + expression: (!has(resource.rotation.rotationPeriod)) || (resource.rotation.rotationPeriod > duration("31536000s")) + recommendation: Ensure the rotation period for secrets are configured correctly + resource_selector: + resource_types: + - secretmanager.googleapis.com/Secret + severity: MEDIUM diff --git a/fast/stages/0-org-setup/datasets/hardened/projects/core/log-0.yaml b/fast/stages/0-org-setup/datasets/hardened/projects/core/log-0.yaml index 71088bf2d..2c8930638 100644 --- a/fast/stages/0-org-setup/datasets/hardened/projects/core/log-0.yaml +++ b/fast/stages/0-org-setup/datasets/hardened/projects/core/log-0.yaml @@ -33,3 +33,7 @@ log_buckets: retention: 31 factories_config: observability: datasets/hardened/organization/observability/ +org_policies: + custom.storageRequireBucketObjectVersionning: + rules: + - enforce: true diff --git a/fast/stages/3-gke-dev/README.md b/fast/stages/3-gke-dev/README.md index c81a03b27..830e5b4dd 100644 --- a/fast/stages/3-gke-dev/README.md +++ b/fast/stages/3-gke-dev/README.md @@ -116,6 +116,8 @@ clusters = { private_nodes = true } enable_features = { + binary_authorization = true + groups_for_rbac = "gke-security-groups@example.com" intranode_visibility = true rbac_binding_config = { enable_insecure_binding_system_unauthenticated: false @@ -140,6 +142,9 @@ nodepools = { test-00 = { 00 = { node_count = { initial = 1 } + node_config = { + sandbox_config_gvisor = true + } } } } diff --git a/fast/stages/3-gke-dev/main.tf b/fast/stages/3-gke-dev/main.tf index d34b5434e..348506d1c 100644 --- a/fast/stages/3-gke-dev/main.tf +++ b/fast/stages/3-gke-dev/main.tf @@ -49,6 +49,12 @@ module "gke-project-0" { labels = { environment = lower(var.environments[var.stage_config.environment].name) } + org_policies = { + // GKE cluster require serial port logging for low level troubleshooting + "compute.managed.disableSerialPortLogging" = { + rules = [{ enforce = false }] + } + } services = [ "anthos.googleapis.com", "anthosconfigmanagement.googleapis.com", @@ -62,6 +68,7 @@ module "gke-project-0" { "monitoring.googleapis.com", "multiclusteringress.googleapis.com", "multiclusterservicediscovery.googleapis.com", + "orgpolicy.googleapis.com", "trafficdirector.googleapis.com" ] shared_vpc_service_config = { diff --git a/tests/fast/stages/s0_org_setup/hardened.yaml b/tests/fast/stages/s0_org_setup/hardened.yaml index 4872c50f9..7c718c90e 100644 --- a/tests/fast/stages/s0_org_setup/hardened.yaml +++ b/tests/fast/stages/s0_org_setup/hardened.yaml @@ -5760,13 +5760,13 @@ counts: google_essential_contacts_contact: 1 google_folder: 8 google_folder_iam_binding: 44 - google_logging_metric: 9 + google_logging_metric: 10 google_logging_organization_settings: 1 google_logging_organization_sink: 3 google_logging_project_bucket_config: 3 - google_monitoring_alert_policy: 9 - google_org_policy_custom_constraint: 55 - google_org_policy_policy: 114 + google_monitoring_alert_policy: 10 + google_org_policy_custom_constraint: 80 + google_org_policy_policy: 149 google_organization_iam_binding: 37 google_organization_iam_custom_role: 9 google_project: 3 @@ -5774,7 +5774,7 @@ counts: google_project_iam_member: 15 google_project_service: 34 google_project_service_identity: 9 - google_scc_management_organization_security_health_analytics_custom_module: 9 + google_scc_management_organization_security_health_analytics_custom_module: 16 google_service_account: 14 google_service_account_iam_binding: 2 google_service_account_iam_member: 4 @@ -5790,5 +5790,5 @@ counts: google_tags_tag_value_iam_binding: 4 local_file: 9 modules: 48 - resources: 474 + resources: 543 terraform_data: 4 diff --git a/tests/fast/stages/s3_gke_dev/hardened.tfvars b/tests/fast/stages/s3_gke_dev/hardened.tfvars new file mode 100644 index 000000000..9e2bb560f --- /dev/null +++ b/tests/fast/stages/s3_gke_dev/hardened.tfvars @@ -0,0 +1,73 @@ +automation = { + outputs_bucket = "fast2-prod-iac-core-outputs" +} +billing_account = { + id = "012345-67890A-BCDEF0", +} +clusters = { + mycluster = { + cluster_autoscaling = null + description = "my cluster" + dns_domain = null + location = "europe-west1" + labels = {} + private_cluster_config = { + enable_private_endpoint = true + master_global_access = true + } + access_config = { + dns_access = true + ip_access = { + disable_public_endpoint = true + } + private_nodes = true + } + enable_features = { + binary_authorization = true + groups_for_rbac = "gke-security-groups@google.com" + intranode_visibility = true + rbac_binding_config = { + enable_insecure_binding_system_unauthenticated : false + enable_insecure_binding_system_authenticated : false + } + shielded_nodes = true + upgrade_notifications = { + event_types = ["SECURITY_BULLETIN_EVENT", "UPGRADE_AVAILABLE_EVENT", "UPGRADE_INFO_EVENT", "UPGRADE_EVENT"] + } + workload_identity = true + } + vpc_config = { + subnetwork = "projects/prj-host/regions/europe-west1/subnetworks/gke-0" + master_ipv4_cidr_block = "172.16.20.0/28" + master_ipv4_cidr_block = "172.16.20.0/28" + master_authorized_ranges = { + private = "10.0.0.0/24" + } + } + } +} +environments = { + dev = { + name = "Development" + } +} +nodepools = { + mycluster = { + mynodepool = { + node_count = { initial = 1 } + node_config = { + sandbox_config_gvisor = true + } + } + } +} +folder_ids = { + gke-dev = "folders/12345678" +} +host_project_ids = { + dev-spoke-0 = "fast-dev-net-spoke-0" +} +prefix = "fast" +vpc_self_links = { + dev-spoke-0 = "projects/fast-dev-net-spoke-0/global/networks/dev-spoke-0" +} diff --git a/tests/fast/stages/s3_gke_dev/hardened.yaml b/tests/fast/stages/s3_gke_dev/hardened.yaml new file mode 100644 index 000000000..e060c7f02 --- /dev/null +++ b/tests/fast/stages/s3_gke_dev/hardened.yaml @@ -0,0 +1,29 @@ +# Copyright 2024 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. + +counts: + google_bigquery_dataset: 1 + google_compute_shared_vpc_service_project: 1 + google_container_cluster: 1 + google_container_node_pool: 1 + google_project: 1 + google_project_iam_binding: 1 + google_project_iam_member: 17 + google_project_service: 14 + google_project_service_identity: 8 + google_pubsub_topic: 1 + google_service_account: 1 + google_storage_bucket_object: 1 + modules: 5 + resources: 49 diff --git a/tests/fast/stages/s3_gke_dev/simple.yaml b/tests/fast/stages/s3_gke_dev/simple.yaml index 83ba9cb8a..d7fbffb8b 100644 --- a/tests/fast/stages/s3_gke_dev/simple.yaml +++ b/tests/fast/stages/s3_gke_dev/simple.yaml @@ -20,9 +20,9 @@ counts: google_project: 1 google_project_iam_binding: 1 google_project_iam_member: 17 - google_project_service: 13 + google_project_service: 14 google_project_service_identity: 8 google_service_account: 1 google_storage_bucket_object: 1 modules: 5 - resources: 46 + resources: 48 diff --git a/tests/fast/stages/s3_gke_dev/tftest.yaml b/tests/fast/stages/s3_gke_dev/tftest.yaml index 925dc10d4..0ec9d9c07 100644 --- a/tests/fast/stages/s3_gke_dev/tftest.yaml +++ b/tests/fast/stages/s3_gke_dev/tftest.yaml @@ -15,4 +15,5 @@ module: fast/stages/3-gke-dev/ tests: - simple: + simple: {} + hardened: {}