gcp-cloudbuild-builds-create-with-sa
cloudbuild.builds.create + iam.serviceAccounts.actAs on a user SA: submit arbitrary build steps as that SA.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
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. |
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.'