gcp-gcs-cross-project-trust

explicit gcp emits CrossProjectTrust

match (record)

{ "api": "storage.buckets.getIamPolicy", "field": "iamPolicy.bindings[].members", "resource_type": "google.storage.Bucket" }

where

a member (serviceAccount email or user email) belongs to a different GCP project than the bucket (e.g. SA email project component != bucket project, or user is a cross-project guest) exclude well-known GCP service agents (service-NUMBER@gcp-sa-*.iam, service-NUMBER@gs-project-accounts.iam, etc.) — these are expected managed-service bindings

emit

source typeProject
target typeProject
source<bucket.project>
target<foreign project the member belongs to>

Narrative

{bucket.name} in {projectA.name} grants access to a principal from {projectB.name} - cross-project data trust.

Raw rule rules/explicit/gcp-gcs.yaml

id: gcp-gcs-cross-project-trust
emits: CrossProjectTrust
applies_to:
- gcp
match_record:
  api: storage.buckets.getIamPolicy
  resource_type: google.storage.Bucket
  field: iamPolicy.bindings[].members
where:
- a member (serviceAccount email or user email) belongs to a different GCP project than the bucket (e.g.
  SA email project component != bucket project, or user is a cross-project guest)
- "exclude well-known GCP service agents (service-NUMBER@gcp-sa-*.iam, service-NUMBER@gs-project-accounts.iam,\
  \ etc.) \u2014 these are expected managed-service bindings"
emit:
  source_type: Project
  target_type: Project
  source: <bucket.project>
  target: <foreign project the member belongs to>
  api_source: storage.buckets.getIamPolicy
  evidence_field: iamPolicy.bindings[].members (cross-project SA or user email)
  permissions: []
  narrative: "{bucket.name} in {projectA.name} grants access to a principal from {projectB.name} \u2014\
    \ cross-project data trust."
move · open · esc close