gcp-deploy-release-create-executes-as
Create a Cloud Deploy release with attacker-controlled Skaffold config + actAs(render SA) → execute arbitrary code as the render SA inside the Cloud Build worker.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'principal': None}
CanModifyCode {'render_worker': None}
{'render_worker': None} ExecutesAs {'render_sa': None}
where
node_type(?render_worker) ==
BuildWorker
?render_worker is a Cloud Deploy render-phase job run
?principal holds clouddeploy.releases.create AND CanPassIdentity(?principal, ?render_sa)
emit
| source type | Identity |
|---|---|
| target type | ServiceAccount |
| source | ?principal |
| target | ?render_sa |
| permissions | clouddeploy.releases.create iam.serviceAccounts.actAs |
| conditions | iam_permission |
| state logic | ACTIVE when CanModifyCode and ExecutesAs contributors are both ACTIVE (releases.create confirmed, CanPassIdentity on render SA confirmed, no blocking deny policy). Inherits CONDITIONAL or BLOCKED from contributing edges per RULE-FORMAT.md. A deploy policy that restricts releases.create => CONDITIONAL(time_window) unless principal holds deployPolicies.override. cicd-chains dedupes on (CanExecuteAs, ?principal, ?render_sa). |
Narrative
{principal.name} can create a Cloud Deploy release (clouddeploy.releases.create) with attacker-controlled Skaffold configuration and actAs on render SA {render_sa.name} (iam.serviceAccounts.actAs). The render Cloud Build worker executes as {render_sa.name}, running the attacker-injected skaffold.yaml hooks. Cite cicd-chains cicd-modify-buildspec-executes-as for the canonical CanModifyCode+ExecutesAs collapse.
Raw rule rules/derived/gcp/clouddeploy.yaml
id: gcp-deploy-release-create-executes-as
emits: CanExecuteAs
description: "Create a Cloud Deploy release with attacker-controlled Skaffold config + actAs(render SA)\
\ \u2192 execute arbitrary code as the render SA inside the Cloud Build worker."
applies_to:
- gcp
match:
- - principal: null
- CanModifyCode
- render_worker: null
- - render_worker: null
- ExecutesAs
- render_sa: null
where:
- node_type(?render_worker) == BuildWorker
- ?render_worker is a Cloud Deploy render-phase job run
- ?principal holds clouddeploy.releases.create AND CanPassIdentity(?principal, ?render_sa)
emit:
source_type: Identity
target_type: ServiceAccount
source: ?principal
target: ?render_sa
permissions:
- clouddeploy.releases.create
- iam.serviceAccounts.actAs
conditions:
- iam_permission
state_logic: ACTIVE when CanModifyCode and ExecutesAs contributors are both ACTIVE (releases.create
confirmed, CanPassIdentity on render SA confirmed, no blocking deny policy). Inherits CONDITIONAL
or BLOCKED from contributing edges per RULE-FORMAT.md. A deploy policy that restricts releases.create
=> CONDITIONAL(time_window) unless principal holds deployPolicies.override. cicd-chains dedupes on
(CanExecuteAs, ?principal, ?render_sa).
confidence: 0.92
derived_from:
- ?principal CanModifyCode ?render_worker (gcp-deploy-release-create-modifies-code)
- ?render_worker ExecutesAs ?render_sa (gcp-deploy-executes-as)
- cicd-chains cicd-modify-buildspec-executes-as
false_positive_note: "actAs on the RENDER SA is the mandatory gate. This rule only fires when both gcp-deploy-release-create-modifies-code\
\ (CanModifyCode) and gcp-deploy-executes-as (ExecutesAs) are already in the graph with ACTIVE or\
\ CONDITIONAL state. The render SA may be scoped with minimal permissions (storage access, logging)\
\ if the deployment organization follows least privilege \u2014 validate the SA's bound roles before\
\ treating it as a high-value escalation target. Render SA \u2260 deploy SA."
narrative: '{principal.name} can create a Cloud Deploy release (clouddeploy.releases.create) with attacker-controlled
Skaffold configuration and actAs on render SA {render_sa.name} (iam.serviceAccounts.actAs). The render
Cloud Build worker executes as {render_sa.name}, running the attacker-injected skaffold.yaml hooks.
Cite cicd-chains cicd-modify-buildspec-executes-as for the canonical CanModifyCode+ExecutesAs collapse.'