gcp-firestore-set-iam-self-grant

datastore.databases.setIamPolicy lets a principal grant itself roles/datastore.owner or roles/datastore.viewer on the database, then read or administer all documents.

derived gcp emits CanGrantPermission

match (effective permission)

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

emit

source typeIdentity
target typeIdentity
source<principal>
target<principal (self)>
permissionsdatastore.databases.setIamPolicy
conditionsiam_permission
state logicACTIVE when setIamPolicy resolves on the database or project scope and no IAM deny or org policy blocks it; BLOCKED when denied. Chains to CanReadData via self-bound roles/datastore.viewer, then to ContainsSecret/CanExfiltrate if the database holds sensitive data or the caller obtains export rights.

Narrative

{principal.name} can set the IAM policy of Firestore database {database.name} (datastore.databases.setIamPolicy) and grant itself roles/datastore.viewer or roles/datastore.owner, then read all documents in the database.

Raw rule rules/derived/gcp/firestore.yaml

id: gcp-firestore-set-iam-self-grant
emits: CanGrantPermission
description: datastore.databases.setIamPolicy lets a principal grant itself roles/datastore.owner or roles/datastore.viewer
  on the database, then read or administer all documents.
match_effective_permission:
  action: datastore.databases.setIamPolicy
  resource_type: google.firestore.Database
emit:
  source_type: Identity
  target_type: Identity
  source: <principal>
  target: <principal (self)>
  permissions:
  - datastore.databases.setIamPolicy
  conditions:
  - iam_permission
  state_logic: ACTIVE when setIamPolicy resolves on the database or project scope and no IAM deny or org
    policy blocks it; BLOCKED when denied. Chains to CanReadData via self-bound roles/datastore.viewer,
    then to ContainsSecret/CanExfiltrate if the database holds sensitive data or the caller obtains export
    rights.
  confidence: min(contributing_confidences) * 0.95
  derived_from:
  - datastore.databases.setIamPolicy effective permission on Firestore Database
  false_positive_note: 'Escalation primitive: a principal that can setIamPolicy on the Firestore database
    can grant itself roles/datastore.viewer (read all documents) or roles/datastore.owner (full control
    including export). The self-grant produces a CanReadData edge via the derived CanGrantPermission ->
    can-control linchpin. For CMEK databases, the service-agent key_permission gate still applies to the
    resulting read. Confirm setIamPolicy scope: a project-level grant covers all databases; a database-level
    grant covers only that database. Org policy denying IAM mutations at the project level -> BLOCKED.'
  narrative: '{principal.name} can set the IAM policy of Firestore database {database.name} (datastore.databases.setIamPolicy)
    and grant itself roles/datastore.viewer or roles/datastore.owner, then read all documents in the database.'
move · open · esc close