gcp-cloudsql-escalate-via-password-reset

A principal who can reset the root DB user password and then read all data in a Cloud SQL instance has escalated to full DBA-level database privilege.

derived gcp emits CanEscalateTo

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} CanResetCredential {'db_user': None} {'principal': None} CanReadData {'instance': None}

where

node_type(?db_user) == GenericIdentity # Cloud SQL root/admin DB user (internal engine identity) node_type(?instance) == RelationalDatabase ?db_user is the root user of ?instance ?principal.privilege_level < elevated

emit

source typeIdentity
target typeGenericIdentity
source?principal
target?db_user
permissionscloudsql.users.update
conditionsiam_permission
state logicinherit_weakest(CanResetCredential, CanReadData): ACTIVE when both contributing edges are ACTIVE; inherits CONDITIONAL/BLOCKED from whichever contributor is weakest. Only emit when the CanReadData is derived from the password-reset chain (gcp-cloudsql-reset-password-read-data), not from independent IAM auth (which is a legitimate access path, not escalation from credential reset).

Narrative

{principal.name} can escalate to full DBA-level access on {instance.name} by resetting the root DB user password (cloudsql.users.update) and connecting as root - gaining read/write/admin access to all databases in the instance.

Raw rule rules/derived/gcp/cloudsql.yaml

id: gcp-cloudsql-escalate-via-password-reset
emits: CanEscalateTo
description: A principal who can reset the root DB user password and then read all data in a Cloud SQL
  instance has escalated to full DBA-level database privilege.
match:
- - principal: null
  - CanResetCredential
  - db_user: null
- - principal: null
  - CanReadData
  - instance: null
where:
- 'node_type(?db_user) == GenericIdentity   # Cloud SQL root/admin DB user (internal engine identity)'
- node_type(?instance) == RelationalDatabase
- ?db_user is the root user of ?instance
- ?principal.privilege_level < elevated
emit:
  source_type: Identity
  target_type: GenericIdentity
  source: ?principal
  target: ?db_user
  permissions:
  - cloudsql.users.update
  conditions:
  - iam_permission
  state_logic: 'inherit_weakest(CanResetCredential, CanReadData): ACTIVE when both contributing edges
    are ACTIVE; inherits CONDITIONAL/BLOCKED from whichever contributor is weakest. Only emit when the
    CanReadData is derived from the password-reset chain (gcp-cloudsql-reset-password-read-data), not
    from independent IAM auth (which is a legitimate access path, not escalation from credential reset).'
  false_positive_note: "This is a DATA-PLANE escalation: the principal gains DBA-level SQL access over\
    \ all databases in the instance, which is above its prior privilege level. It is NOT a GCP IAM management-plane\
    \ escalation (no new IAM role is gained). can-control.yaml escalate-via-execute-as handles CanExecuteAs\
    \ paths \u2014 do not re-derive that here. Only emit when the principal's effective DB privilege before\
    \ the reset is less than DBA (e.g., it had no DB credentials at all or was a read-only DB user). Target\
    \ is the root DB user (GenericIdentity, internal engine identity not HumanIdentity), not the principal\
    \ itself \u2014 the escalation is to that identity. See gcp-cloudsql-explicit-can-reset-credential\
    \ for context."
  narrative: "{principal.name} can escalate to full DBA-level access on {instance.name} by resetting the\
    \ root DB user password (cloudsql.users.update) and connecting as root \u2014 gaining read/write/admin\
    \ access to all databases in the instance."
  derived_from:
  - ?principal CanResetCredential ?db_user
  - ?principal CanReadData ?instance (via gcp-cloudsql-reset-password-read-data)
move · open · esc close