gcp-cloudbuild-builds-create-with-sa

cloudbuild.builds.create + iam.serviceAccounts.actAs on a user SA: submit arbitrary build steps as that SA.

derived gcp emits CanModifyCode

match

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

?principal CanPassIdentity ?sa

where

?principal has effective cloudbuild.builds.create on the project node_type(?sa) in [ServiceAccount, MachineIdentity] # user-managed SA ?sa is NOT the legacy Cloud Build SA (PROJECT_NUMBER@cloudbuild.gserviceaccount.com)

emit

source typeIdentity
target typeCompute
source<principal>
target<Cloud Build build node / BuildWorker for ?sa>
permissionscloudbuild.builds.create iam.serviceAccounts.actAs
conditionsiam_permission role_compatibility
state logicACTIVE if both cloudbuild.builds.create and iam.serviceAccounts.actAs on ?sa are confirmed in the effective permission set. CONDITIONAL(iam_permission) if actAs is unresolved. BLOCKED if a deny policy denies either permission at scope.

Narrative

{principal.name} can submit a Cloud Build build (cloudbuild.builds.create) with arbitrary steps running as user-specified service account {sa.name} (iam.serviceAccounts.actAs required and confirmed), yielding code execution as that SA.

Raw rule rules/derived/gcp/cloudbuild.yaml

id: gcp-cloudbuild-builds-create-with-sa
emits: CanModifyCode
description: 'cloudbuild.builds.create + iam.serviceAccounts.actAs on a user SA: submit arbitrary build
  steps as that SA.'
match:
- - ?principal
  - CanPassIdentity
  - ?sa
where:
- ?principal has effective cloudbuild.builds.create on the project
- 'node_type(?sa) in [ServiceAccount, MachineIdentity]  # user-managed SA'
- ?sa is NOT the legacy Cloud Build SA (PROJECT_NUMBER@cloudbuild.gserviceaccount.com)
emit:
  source_type: Identity
  target_type: Compute
  source: <principal>
  target: <Cloud Build build node / BuildWorker for ?sa>
  permissions:
  - cloudbuild.builds.create
  - iam.serviceAccounts.actAs
  conditions:
  - iam_permission
  - role_compatibility
  state_logic: ACTIVE if both cloudbuild.builds.create and iam.serviceAccounts.actAs on ?sa are confirmed
    in the effective permission set. CONDITIONAL(iam_permission) if actAs is unresolved. BLOCKED if a
    deny policy denies either permission at scope.
  confidence: 0.95
  derived_from:
  - <CanPassIdentity edge_id for ?principal -> ?sa>
  - <cloudbuild.builds.create effective permission>
  false_positive_note: "actAs on the SA is the guard rail \u2014 without it Cloud Build rejects the build\
    \ submission at API time. Confirm both permissions are in the effective grant (not just identity policy;\
    \ also check project IAM + org policies/deny). Do not emit for the legacy SA (no actAs required for\
    \ that SA)."
  narrative: '{principal.name} can submit a Cloud Build build (cloudbuild.builds.create) with arbitrary
    steps running as user-specified service account {sa.name} (iam.serviceAccounts.actAs required and
    confirmed), yielding code execution as that SA.'
move · open · esc close