gcp-firestore-explicit-cross-project-trust

A Firestore database IAM binding granting any role to a principal in a different GCP project is a cross-project trust on the database's data.

explicit gcp emits CrossProjectTrust

match (record)

{ "api": "firestore.projects.databases.getIamPolicy", "field": "iamPolicy.bindings[].members", "resource_type": "google.firestore.Database" }

where

a member (serviceAccount / user / group) belongs to a different GCP project than the database

emit

source typeProject
target typeProject
source<database's project>
target<foreign project the member belongs to>
conditionsresource_policy
state logicACTIVE when the cross-project binding is present in the effective IAM policy at the project or database scope; CONDITIONAL(resource_policy) when the foreign principal's own IAM cannot be confirmed.

Narrative

Firestore database {database.name} (project {projectA.name}) grants data access to a principal in project {projectB.name} via an IAM binding; {projectB.name} can read/write Firestore documents without holding IAM bindings independently in project {projectA.name}.

Raw rule rules/explicit/gcp-firestore.yaml

id: gcp-firestore-explicit-cross-project-trust
emits: CrossProjectTrust
description: A Firestore database IAM binding granting any role to a principal in a different GCP project
  is a cross-project trust on the database's data.
match_record:
  api: firestore.projects.databases.getIamPolicy
  resource_type: google.firestore.Database
  field: iamPolicy.bindings[].members
where:
- a member (serviceAccount / user / group) belongs to a different GCP project than the database
emit:
  source_type: Project
  target_type: Project
  source: <database's project>
  target: <foreign project the member belongs to>
  permissions: []
  conditions:
  - resource_policy
  state_logic: ACTIVE when the cross-project binding is present in the effective IAM policy at the project
    or database scope; CONDITIONAL(resource_policy) when the foreign principal's own IAM cannot be confirmed.
  confidence: '0.94'
  derived_from:
  - google.firestore.Database iamPolicy.bindings[].members (cross-project principal)
  false_positive_note: "A cross-project SA bound to roles/datastore.viewer means a principal from project\
    \ B can read documents in project A's Firestore database \u2014 a deliberate but potentially over-broad\
    \ trust. The SA must also be usable by an attacker (hold iam.serviceAccounts.actAs or be compromised\
    \ independently). GCP-managed service agents (service-PROJECT_NUMBER@gcp-sa-*.iam) are expected and\
    \ should be de-prioritized. Flag only when the member is a non-service-agent SA, human user, or external\
    \ domain in a different project. Firestore project-level IAM bindings cover ALL databases in the project;\
    \ database-level bindings are scoped to a single database. Note whether the binding is project-level\
    \ or database-level."
  narrative: Firestore database {database.name} (project {projectA.name}) grants data access to a principal
    in project {projectB.name} via an IAM binding; {projectB.name} can read/write Firestore documents
    without holding IAM bindings independently in project {projectA.name}.
move · open · esc close