gcp-gcs-cross-project-trust
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 type | Project |
|---|---|
| target type | Project |
| 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."