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.

derived gcp emits CanModifyCode

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} CanModifyPolicy {'repo_policy': None}

where

?repo_policy is the ResourcePolicy of a CSR repository ?repo node_type(?repo) == ArtifactRepository

emit

source typeIdentity
target typeArtifactRepository
source?principal
target<CSR repository whose ResourcePolicy is ?repo_policy>
permissionssource.repos.setIamPolicy source.repos.update
conditionsiam_permission
state logicCONDITIONAL(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.'
move · open · esc close