Write rules for custom cloud controls

Preview

This feature is subject to the "Pre-GA Offerings Terms" in the General Service Terms section of the Service Specific Terms . Pre-GA features are available "as is" and might have limited support. For more information, see the launch stage descriptions .

When you create a custom cloud control , you use Common Expression Language (CEL) expressions to create the rules that evaluate the properties of the scanned resource.

Your expressions can be checks of a single value or more complex compound expressions that check multiple values or conditions. Either way, the expression must resolve to a boolean false to trigger a finding.

CEL expressions that evaluate resource properties must conform to the following rules:

  • The properties that you specify in a CEL expression must be properties of the scanned resource, as defined in the API definition of the resource type.

  • All enums in a CEL expression must be represented as strings. For example, the following is a valid expression for the cloudkms.googleapis.com/CryptoKeyVersion resource type:

    resource.data.state = "PENDING_GENERATION"
  • The result of the CEL expressions that you define in the condition property must be a Boolean. A finding is triggered only if the result is false .

For more information about CEL, see the following:

Example CEL expressions

The following table lists some CEL expressions that you can use to evaluate resource properties.

Resource type Description CEL expression
cloudkms.googleapis.com/CryptoKey
Check the Cloud KMS key rotation period has(resource.data.rotationPeriod) && resource.data.rotationPeriod < duration('60h')
compute.googleapis.com/Network
Match Virtual Private Cloud peering rule to network peers resource.data.selfLink.matches('https://www.googleapis.com/compute/v1/projects/ PROJECT_ID /global/networks/default') || resource.data.peerings.exists(p, p.network.matches('https://www.googleapis.com/compute/v1/projects/ PROJECT_ID /global/networks/shared$'))
cloudfunctions.googleapis.com/CloudFunction
Only allow internal ingress traffic for a Cloud Run function has(resource.data.ingressSettings) && resource.data.ingressSettings.matches('ALLOW_INTERNAL_ONLY')
compute.googleapis.com/Instance
Resource name matches pattern resource.data.name.matches('^gcp-vm-(linux|windows)-v\\\\d+$')
serviceusage.googleapis.com/Service
Only allow storage-related APIs to be enabled resource.data.state == 'ENABLED' && !( resource.data.name.matches('storage-api.googleapis.com') || resource.data.name.matches('bigquery-json.googleapis.com') || resource.data.name.matches('bigquery.googleapis.com') || resource.data.name.matches('sql-component.googleapis.com') || resource.data.name.matches('spanner.googleapis.com'))
sqladmin.googleapis.com/Instance
Only permit public IP addresses that are on the allowlist (resource.data.instanceType == 'CLOUD_SQL_INSTANCE' && resource.data.backendType == 'SECOND_GEN' && resource.data.settings.ipConfiguration.ipv4Enabled ) && (resource.data.ipAddresses.all(ip, ip.type != 'PRIMARY' || ip.ipAddress.matches(' IP_ADDRESS ')))
dataproc.googleapis.com/Cluster
Check if project IDs in a Dataproc cluster contain the substrings testing or development has(resource.data.projectId) && !resource.data.projectId.contains('testing') || !resource.data.projectId.contains('development')
Create a Mobile Website
View Site in Mobile | Classic
Share by: