gcp-cloudsql-iam-auth-read-data

When a Cloud SQL instance has IAM database authentication enabled (cloudsql.iam_authentication=on), a principal with cloudsql.instances.login can authenticate to the DB using its IAM token via Cloud SQL Auth Proxy - no DB password needed.

derived gcp emits CanReadData

match (effective permission)

{ "action": "cloudsql.instances.login", "resource_type": "google.sql.Instance" }

where

instance.settings.databaseFlags contains cloudsql.iam_authentication=on an IAM DB user of type CLOUD_IAM_USER or CLOUD_IAM_SERVICE_ACCOUNT exists for this principal

emit

source typeIdentity
target typeData
source<principal>
target<Cloud SQL Instance node>
permissionscloudsql.instances.login cloudsql.instances.connect
conditionsiam_permission service_state network_reachability
state logicACTIVE when: (1) the instance has database_flags cloudsql.iam_authentication=on, (2) the principal holds cloudsql.instances.login (in roles/cloudsql.instanceUser), (3) a corresponding IAM DB user record (CLOUD_IAM_USER or CLOUD_IAM_SERVICE_ACCOUNT) exists in the instance for this principal, AND (4) a network path exists to the instance (public IP with authorizedNetworks allowing the principal's source IP, OR Cloud SQL Auth Proxy path via cloudsql.instances.connect on a private IP instance). CONDITIONAL(service_state) when the IAM auth flag cannot be confirmed. CONDITIONAL(iam_permission) when the IAM DB user record is absent (flag alone does not auto-create DB user — must be explicitly created). CONDITIONAL(network_reachability) when the instance is private-IP-only and no Auth Proxy path is confirmed. BLOCKED when VPC-SC perimeter blocks sqladmin API.

Narrative

{principal.name} holds cloudsql.instances.login (roles/cloudsql.instanceUser) on {instance.name}, which has IAM database authentication enabled (cloudsql.iam_authentication=on) and an IAM DB user record for {principal.name}; it can authenticate to the DB using its short-lived IAM token via Cloud SQL Auth Proxy (requires cloudsql.instances.connect and a network path to the instance) without a DB password.

Raw rule rules/derived/gcp/cloudsql.yaml

id: gcp-cloudsql-iam-auth-read-data
emits: CanReadData
description: "When a Cloud SQL instance has IAM database authentication enabled (cloudsql.iam_authentication=on),\
  \ a principal with cloudsql.instances.login can authenticate to the DB using its IAM token via Cloud\
  \ SQL Auth Proxy \u2014 no DB password needed."
match_effective_permission:
  action: cloudsql.instances.login
  resource_type: google.sql.Instance
where:
- instance.settings.databaseFlags contains cloudsql.iam_authentication=on
- an IAM DB user of type CLOUD_IAM_USER or CLOUD_IAM_SERVICE_ACCOUNT exists for this principal
emit:
  source_type: Identity
  target_type: Data
  source: <principal>
  target: <Cloud SQL Instance node>
  permissions:
  - cloudsql.instances.login
  - cloudsql.instances.connect
  conditions:
  - iam_permission
  - service_state
  - network_reachability
  state_logic: "ACTIVE when: (1) the instance has database_flags cloudsql.iam_authentication=on, (2) the\
    \ principal holds cloudsql.instances.login (in roles/cloudsql.instanceUser), (3) a corresponding IAM\
    \ DB user record (CLOUD_IAM_USER or CLOUD_IAM_SERVICE_ACCOUNT) exists in the instance for this principal,\
    \ AND (4) a network path exists to the instance (public IP with authorizedNetworks allowing the principal's\
    \ source IP, OR Cloud SQL Auth Proxy path via cloudsql.instances.connect on a private IP instance).\
    \ CONDITIONAL(service_state) when the IAM auth flag cannot be confirmed. CONDITIONAL(iam_permission)\
    \ when the IAM DB user record is absent (flag alone does not auto-create DB user \u2014 must be explicitly\
    \ created). CONDITIONAL(network_reachability) when the instance is private-IP-only and no Auth Proxy\
    \ path is confirmed. BLOCKED when VPC-SC perimeter blocks sqladmin API."
  false_positive_note: "Three separate conditions must ALL be true: (A) the INSTANCE-LEVEL flag database_flags.cloudsql.iam_authentication=on,\
    \ (B) an IAM DB user record for this principal exists in the instance (visible via cloudsql.users.list\
    \ as type CLOUD_IAM_USER or CLOUD_IAM_SERVICE_ACCOUNT), AND (C) a network path to reach the DB port\
    \ (public IP reachable from principal's source, OR Cloud SQL Auth Proxy via cloudsql.instances.connect).\
    \ Holding roles/cloudsql.instanceUser at project level does NOT auto-create an IAM DB user \u2014\
    \ admin must explicitly add it. Do NOT emit ACTIVE for instances where flag is absent, no IAM DB user\
    \ exists, or the instance is not network-reachable. cloudsql.instances.connect (in roles/cloudsql.client)\
    \ is required for Auth Proxy tunnel; without it, the principal cannot reach the DB port even with\
    \ IAM auth enabled. For PostgreSQL, the IAM DB username is the email with @domain stripped (for SAs);\
    \ for MySQL, it is the full email."
  narrative: '{principal.name} holds cloudsql.instances.login (roles/cloudsql.instanceUser) on {instance.name},
    which has IAM database authentication enabled (cloudsql.iam_authentication=on) and an IAM DB user
    record for {principal.name}; it can authenticate to the DB using its short-lived IAM token via Cloud
    SQL Auth Proxy (requires cloudsql.instances.connect and a network path to the instance) without a
    DB password.'
  derived_from:
  - cloudsql.instances.login effective permission on google.sql.Instance
  - google.sql.Instance.settings.databaseFlags[cloudsql.iam_authentication]=on
  - google.sql.User type=CLOUD_IAM_USER|CLOUD_IAM_SERVICE_ACCOUNT for principal
  - network_reachability to instance (public IP or Auth Proxy path)
move · open · esc close