gcp-dm-executes-as

Every Deployment Manager deployment runs as the Google APIs service agent (PROJECT_NUMBER@cloudservices.gserviceaccount.com), which by default holds roles/editor at the project.

derived gcp emits ExecutesAs

match (record)

{ "resource_type": "google.deploymentmanager.Deployment" }

where

?sa = PROJECT_NUMBER@cloudservices.gserviceaccount.com (derived from deployment.projectNumber, not operation.user) ?sa.privilege_level is elevated (roles/editor) or admin (roles/owner) at project scope

emit

source typeBuildWorker
target typeServiceAccount
source<Deployment node>
target<cloudservices ServiceAccount>
conditionsservice_state
state logicACTIVE when the deployment object exists and is not in a terminal-failure state; CONDITIONAL(service_state) if the deployment is in preview mode (actuation has not occurred) or is stopped/cancelled before resource creation. The service agent identity binding is structural — it cannot be changed per-deployment.

Narrative

Deployment {deployment.name} executes as the Google APIs service agent {sa.name} ({sa.email}), which holds {sa.effective_roles} at the project. Code injected into the deployment config runs with those privileges.

Raw rule rules/derived/gcp/deploymentmanager.yaml

id: gcp-dm-executes-as
emits: ExecutesAs
description: Every Deployment Manager deployment runs as the Google APIs service agent (PROJECT_NUMBER@cloudservices.gserviceaccount.com),
  which by default holds roles/editor at the project.
match_record:
  resource_type: google.deploymentmanager.Deployment
where:
- ?sa = PROJECT_NUMBER@cloudservices.gserviceaccount.com (derived from deployment.projectNumber, not operation.user)
- ?sa.privilege_level is elevated (roles/editor) or admin (roles/owner) at project scope
emit:
  target_type: ServiceAccount
  source_type: BuildWorker
  source: <Deployment node>
  target: <cloudservices ServiceAccount>
  permissions: []
  conditions:
  - service_state
  state_logic: "ACTIVE when the deployment object exists and is not in a terminal-failure state; CONDITIONAL(service_state)\
    \ if the deployment is in preview mode (actuation has not occurred) or is stopped/cancelled before\
    \ resource creation. The service agent identity binding is structural \u2014 it cannot be changed\
    \ per-deployment."
  confidence: 1.0
  derived_from: []
  false_positive_note: "This is a structural fact, not an attack. The edge becomes attack-relevant only\
    \ when combined with CanModifyCode (deployer can inject a malicious config). The service agent's roles\
    \ must be resolved from the project IAM policy \u2014 do not assume roles/editor is still bound; org\
    \ policy iam.automaticIamGrantsForDefaultServiceAccounts may have removed it, or the SA may have been\
    \ restricted by an administrator."
  narrative: Deployment {deployment.name} executes as the Google APIs service agent {sa.name} ({sa.email}),
    which holds {sa.effective_roles} at the project. Code injected into the deployment config runs with
    those privileges.
move · open · esc close