gcp-sr-cross-project-writer

A CSR repo IAM binding that grants source.repos.update to a service account from a different GCP project establishes cross-project trust - that SA can push to this project's repository and arm Cloud Build triggers.

derived gcp emits CrossProjectTrust

match

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

{'repo': None} HasPolicy {'repo_policy': None}

where

?repo is a CSR ArtifactRepository ?repo_policy is a ResourcePolicy of the CSR repository ?repo_policy has an IAM binding for a ServiceAccount from a DIFFERENT GCP project (member is serviceAccount:*@<other-project>.iam.gserviceaccount.com) the binding role or permissions include source.repos.update

emit

source typeResourcePolicy
target typeProject
source?repo_policy
target<GCP project of the external ServiceAccount>
permissionssource.repos.update
conditionsresource_policy
state logicACTIVE when the IAM binding is present, the role includes source.repos.update, and no IAM deny policy overrides it. CONDITIONAL (resource_policy) if the binding has an IAM condition expression that may not be satisfied. BLOCKED if a VPC-SC perimeter rejects the cross- project API call or an org policy restricts cross-project resource sharing. Inherit weakest from the binding's effective state.

Narrative

Repository {repo.name} (project {repo.project}) grants source.repos.update to service account {sa.name} from project {sa.project}. A principal that can act as {sa.name} can push commits to {repo.name}, arming any Cloud Build push trigger watching a target branch in {repo.project}.

Raw rule rules/derived/gcp/sourcerepos.yaml

id: gcp-sr-cross-project-writer
emits: CrossProjectTrust
description: "A CSR repo IAM binding that grants source.repos.update to a service account from a different\
  \ GCP project establishes cross-project trust \u2014 that SA can push to this project's repository and\
  \ arm Cloud Build triggers."
match:
- - repo: null
  - HasPolicy
  - repo_policy: null
where:
- ?repo is a CSR ArtifactRepository
- ?repo_policy is a ResourcePolicy of the CSR repository
- ?repo_policy has an IAM binding for a ServiceAccount from a DIFFERENT GCP project (member is serviceAccount:*@<other-project>.iam.gserviceaccount.com)
- the binding role or permissions include source.repos.update
emit:
  source_type: ResourcePolicy
  target_type: Project
  source: ?repo_policy
  target: <GCP project of the external ServiceAccount>
  permissions:
  - source.repos.update
  conditions:
  - resource_policy
  state_logic: ACTIVE when the IAM binding is present, the role includes source.repos.update, and no IAM
    deny policy overrides it. CONDITIONAL (resource_policy) if the binding has an IAM condition expression
    that may not be satisfied. BLOCKED if a VPC-SC perimeter rejects the cross- project API call or an
    org policy restricts cross-project resource sharing. Inherit weakest from the binding's effective
    state.
  confidence: 0.9
  derived_from:
  - 'IAM binding on ?repo_policy: <external SA> has source.repos.update'
  false_positive_note: "The cross-project SA must be usable by a principal the attacker controls \u2014\
    \ this trust edge models the repo's posture, not that the SA is compromised. Path-finding chains this\
    \ CrossProjectTrust to the SA's home project; only if a principal there can act as the SA (actAs or\
    \ direct key) does the push materialize. Verify the SA is not a Google-managed service agent (those\
    \ have restricted actAs surfaces)."
  narrative: Repository {repo.name} (project {repo.project}) grants source.repos.update to service account
    {sa.name} from project {sa.project}. A principal that can act as {sa.name} can push commits to {repo.name},
    arming any Cloud Build push trigger watching a target branch in {repo.project}.
move · open · esc close