gcp-dm-execute-as-via-create
A principal with deploymentmanager.deployments.create submits an attacker-controlled config; DM actuates it as the Google APIs service agent, executing code (resource creation, setIamPolicy) as that SA's identity.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?deployment) ==
BuildWorker # DM Deployment node
?deployment is a google.deploymentmanager.Deployment
the CanModifyCode edge originates from gcp-dm-deployments-create (deployments.create)
emit
| source type | Identity |
|---|---|
| target type | ServiceAccount |
| source | ?principal |
| target | ?sa |
| permissions | deploymentmanager.deployments.create |
| conditions | api_enabled |
| state logic | ACTIVE(api_enabled) — unlike a build system where a trigger may be needed to run the job, a DM deployment.create is synchronous: submitting the deployment IS the trigger. The config is actuated immediately (or on preview confirmation). No separate trigger_exists condition. BLOCKED if the DM API is disabled, the principal's permission is denied by an IAM deny policy, or a VPC Service Controls perimeter blocks the cloudresourcemanager / target-service API calls the config makes. |
Narrative
{principal.name} can create a Deployment Manager deployment (deploymentmanager.deployments.create), submitting a config that DM immediately actuates as the Google APIs service agent {sa.name} ({sa.email}, roles/{editor|owner}). The config can call setIamPolicy on any resource the SA manages, grant the attacker elevated roles, create new compute resources, or exfiltrate secrets - all AS {sa.name}.
Raw rule rules/derived/gcp/deploymentmanager.yaml
id: gcp-dm-execute-as-via-create
emits: CanExecuteAs
description: A principal with deploymentmanager.deployments.create submits an attacker-controlled config;
DM actuates it as the Google APIs service agent, executing code (resource creation, setIamPolicy) as
that SA's identity.
match:
- - principal: null
- CanModifyCode
- deployment: null
- - deployment: null
- ExecutesAs
- sa: null
where:
- 'node_type(?deployment) == BuildWorker # DM Deployment node'
- ?deployment is a google.deploymentmanager.Deployment
- the CanModifyCode edge originates from gcp-dm-deployments-create (deployments.create)
emit:
source_type: Identity
target_type: ServiceAccount
source: ?principal
target: ?sa
permissions:
- deploymentmanager.deployments.create
conditions:
- api_enabled
state_logic: "ACTIVE(api_enabled) \u2014 unlike a build system where a trigger may be needed to run\
\ the job, a DM deployment.create is synchronous: submitting the deployment IS the trigger. The config\
\ is actuated immediately (or on preview confirmation). No separate trigger_exists condition. BLOCKED\
\ if the DM API is disabled, the principal's permission is denied by an IAM deny policy, or a VPC\
\ Service Controls perimeter blocks the cloudresourcemanager / target-service API calls the config\
\ makes."
confidence: min(contributing_confidences) * 0.95
derived_from:
- gcp-dm-deployments-create (CanModifyCode edge)
- gcp-dm-executes-as (ExecutesAs edge)
- cicd-chains.yaml cicd-modify-buildspec-executes-as (linchpin, deduped)
- can-execute-as.yaml execute-as-via-code-modify (linchpin, deduped)
false_positive_note: "ACTIVE assumes the DM API is enabled and the service agent holds its default roles/editor\
\ (or higher). If the service agent's Editor binding was removed by org policy (iam.automaticIamGrantsForDefaultServiceAccounts)\
\ or manually, the CanExecuteAs target SA has lower privilege \u2014 still emit the edge but score\
\ escalation from the SA's actual roles. The DM API being disabled (apis.googleapis.com status) blocks\
\ this entirely. Deduplicate: cicd-chains rule 1 fires on the same (CanModifyCode, ExecutesAs) pair\
\ \u2014 emit once, using the higher-confidence score."
narrative: "{principal.name} can create a Deployment Manager deployment (deploymentmanager.deployments.create),\
\ submitting a config that DM immediately actuates as the Google APIs service agent {sa.name} ({sa.email},\
\ roles/{editor|owner}). The config can call setIamPolicy on any resource the SA manages, grant the\
\ attacker elevated roles, create new compute resources, or exfiltrate secrets \u2014 all AS {sa.name}."