gcp-firestore-modify-configuration

datastore.databases.update allows changing cmekConfig.kmsKeyName on a Firestore database, swapping to an attacker-controlled KMS key. Future writes are then encrypted under the attacker's key, enabling offline decryption of all subsequently written data. This is a configuration mutation on a data resource, not code execution.

derived gcp emits CanWrite

match (effective permission)

{ "action": "datastore.databases.update", "resource_type": "google.firestore.Database" }

emit

source typeIdentity
target typeData
source<principal>
target<Firestore Database / NoSQLDatabase node>
permissionsdatastore.databases.update
conditionsiam_permission resource_policy
state logicACTIVE when datastore.databases.update is confirmed effective on the Firestore Database and no VPC-SC perimeter or IAM deny policy blocks the action; CONDITIONAL(iam_permission) when the permission scope is uncertain; BLOCKED when denied. The attacker can use this edge to modify cmekConfig.kmsKeyName to a key they control; only NEW/rewritten document blocks are encrypted under the attacker's key. Existing blocks continue to use the old key (and service-agent decryption) until data is re-written.

Narrative

{principal.name} holds datastore.databases.update on {database.name} and can modify the database configuration, including cmekConfig.kmsKeyName. By swapping to an attacker-controlled KMS key, the attacker ensures all future writes are encrypted under their key, enabling offline decryption of subsequently written data (risk: data exfiltration + offline decryption without key access).

Raw rule rules/derived/gcp/firestore.yaml

id: gcp-firestore-modify-configuration
emits: CanWrite
description: datastore.databases.update allows changing cmekConfig.kmsKeyName on a Firestore database,
  swapping to an attacker-controlled KMS key. Future writes are then encrypted under the attacker's key,
  enabling offline decryption of all subsequently written data. This is a configuration mutation on a
  data resource, not code execution.
match_effective_permission:
  action: datastore.databases.update
  resource_type: google.firestore.Database
emit:
  source_type: Identity
  target_type: Data
  source: <principal>
  target: <Firestore Database / NoSQLDatabase node>
  permissions:
  - datastore.databases.update
  conditions:
  - iam_permission
  - resource_policy
  state_logic: ACTIVE when datastore.databases.update is confirmed effective on the Firestore Database
    and no VPC-SC perimeter or IAM deny policy blocks the action; CONDITIONAL(iam_permission) when the
    permission scope is uncertain; BLOCKED when denied. The attacker can use this edge to modify cmekConfig.kmsKeyName
    to a key they control; only NEW/rewritten document blocks are encrypted under the attacker's key.
    Existing blocks continue to use the old key (and service-agent decryption) until data is re-written.
  confidence: '0.90'
  derived_from:
  - datastore.databases.update effective permission on Firestore Database
  - CMEK key-swap escalation primitive
  false_positive_note: 'datastore.databases.update grants broad configuration changes including region,
    backup policy, and CMEK key. The CMEK key-swap sub-attack is only realized if the attacker both (1)
    holds CanWrite and (2) controls a KMS key in the same project. Downstream: new writes encrypted under
    the attacker''s key allow offline decryption if the attacker exfiltrates the database (export to GCS).
    Existing data remains readable by the Firestore Service Agent (no immediate impact). Org policy constraints/gcp.resourceTypes/locations
    may restrict database mutations. This edge uses CanWrite (resource-control category) not CanModifyConfiguration
    (execution category) because the target is a Data resource (NoSQLDatabase) with no downstream ExecutesAs
    edges. can-execute-as.yaml chains MUST NOT traverse this edge to derive CanExecuteAs. Note: datastore.databases.update
    is included in roles/datastore.owner and roles/datastore.editor.'
  narrative: '{principal.name} holds datastore.databases.update on {database.name} and can modify the
    database configuration, including cmekConfig.kmsKeyName. By swapping to an attacker-controlled KMS
    key, the attacker ensures all future writes are encrypted under their key, enabling offline decryption
    of subsequently written data (risk: data exfiltration + offline decryption without key access).'
move · open · esc close