gcp-secretmanager-cross-project-cred
A cross-project principal reading a secret whose payload is a credential privileged in the secret's project enters that project.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'principal': None}
CanReadSecret {'secret': None}
{'secret': None} CredentialsFor {'identity': None}
where
?principal.project != ?secret.project
?identity has bindings granting privilege in ?secret.project
emit
| source type | Identity |
|---|---|
| target type | Project |
| source | <principal> |
| target | <secret.project> |
| permissions | secretmanager.versions.access |
| conditions | iam_permission resource_policy key_permission |
| state logic | Inherits CanReadSecret state. ACTIVE when the cross-project read resolves and the credentialed identity is privileged in the target project. |
Narrative
{principal.name} can read secret {secret.name} in project {project.name}, obtaining credentials for {identity.name} which is privileged there - entering project {project.name}.
Raw rule rules/derived/gcp/secretmanager.yaml
id: gcp-secretmanager-cross-project-cred
emits: CanEnterProject
description: A cross-project principal reading a secret whose payload is a credential privileged in the
secret's project enters that project.
match:
- - principal: null
- CanReadSecret
- secret: null
- - secret: null
- CredentialsFor
- identity: null
where:
- ?principal.project != ?secret.project
- ?identity has bindings granting privilege in ?secret.project
emit:
source_type: Identity
target_type: Project
source: <principal>
target: <secret.project>
permissions:
- secretmanager.versions.access
conditions:
- iam_permission
- resource_policy
- key_permission
state_logic: Inherits CanReadSecret state. ACTIVE when the cross-project read resolves and the credentialed
identity is privileged in the target project.
confidence: min(contributing_confidences) * 0.9
derived_from:
- <CanReadSecret edge_id>
- <CredentialsFor edge_id>
false_positive_note: Only cross-boundary when principal and secret live in different projects AND the
payload credential is privileged in the secret's project. A cross-project binding granting secretAccessor
is the common enabler; honor its condition expressions.
narrative: "{principal.name} can read secret {secret.name} in project {project.name}, obtaining credentials\
\ for {identity.name} which is privileged there \u2014 entering project {project.name}."