gcp-sr-policy-self-grant-write
A principal that can set the repo IAM policy can self-grant roles/source.writer and then push commits - policy manipulation yields the same CanModifyCode as a direct writer binding.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
?repo_policy is the
ResourcePolicy of a CSR repository ?repo
node_type(?repo) == ArtifactRepository
emit
| source type | Identity |
|---|---|
| target type | ArtifactRepository |
| source | ?principal |
| target | <CSR repository whose ResourcePolicy is ?repo_policy> |
| permissions | source.repos.setIamPolicy source.repos.update |
| conditions | iam_permission |
| state logic | CONDITIONAL(iam_permission): the self-grant step requires a successful setIamPolicy call (ACTIVE setIamPolicy permission, no IAM deny overriding it) followed by the push. If the CanModifyPolicy contributor is ACTIVE (setIamPolicy not denied) the combined capability is effectively ACTIVE (the self-grant is an in-band step). BLOCKED if setIamPolicy is BLOCKED (IAM deny, VPC-SC). Inherit weakest from the contributing CanModifyPolicy. |
Narrative
{principal.name} can set the IAM policy of {repo.name} (source.repos.setIamPolicy), granting itself roles/source.writer, and then push a modified cloudbuild.yaml or build-spec commit. Policy manipulation yields the same CanModifyCode supply-chain write as a direct writer grant.
Raw rule rules/derived/gcp/sourcerepos.yaml
id: gcp-sr-policy-self-grant-write
emits: CanModifyCode
description: "A principal that can set the repo IAM policy can self-grant roles/source.writer and then\
\ push commits \u2014 policy manipulation yields the same CanModifyCode as a direct writer binding."
match:
- - principal: null
- CanModifyPolicy
- repo_policy: null
where:
- ?repo_policy is the ResourcePolicy of a CSR repository ?repo
- node_type(?repo) == ArtifactRepository
emit:
source_type: Identity
target_type: ArtifactRepository
source: ?principal
target: <CSR repository whose ResourcePolicy is ?repo_policy>
permissions:
- source.repos.setIamPolicy
- source.repos.update
conditions:
- iam_permission
state_logic: 'CONDITIONAL(iam_permission): the self-grant step requires a successful setIamPolicy call
(ACTIVE setIamPolicy permission, no IAM deny overriding it) followed by the push. If the CanModifyPolicy
contributor is ACTIVE (setIamPolicy not denied) the combined capability is effectively ACTIVE (the
self-grant is an in-band step). BLOCKED if setIamPolicy is BLOCKED (IAM deny, VPC-SC). Inherit weakest
from the contributing CanModifyPolicy.'
confidence: 0.9
derived_from:
- ?principal CanModifyPolicy ?repo_policy (gcp-sr-set-iam-policy)
false_positive_note: "The self-grant is a two-step action (setIamPolicy then push); both steps must\
\ succeed under the effective IAM policy. An IAM deny blocking setIamPolicy (e.g. an org-wide deny\
\ on source.repos.setIamPolicy) keeps this BLOCKED regardless of the push permission. The CanModifyCode\
\ emitted here is the same capability as gcp-sr-push-is-code-modify but reached via policy manipulation;\
\ graph deduplication should treat them as the same (CanModifyCode, ?principal, ?repo) edge \u2014\
\ pick higher confidence, do not double-count weight. cicd-chains fan-out applies equally."
narrative: '{principal.name} can set the IAM policy of {repo.name} (source.repos.setIamPolicy), granting
itself roles/source.writer, and then push a modified cloudbuild.yaml or build-spec commit. Policy
manipulation yields the same CanModifyCode supply-chain write as a direct writer grant.'