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.
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 — 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)