gcp-deploy-exec-sa-can-deploy-cloudrun

The Cloud Deploy execution SA's Cloud Run deployment permissions (run.developer) give it CanDeploy to a Cloud Run service.

derived gcp emits CanDeploy

match

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

{'exec_sa': None} HasPermission {'cloudrun_service': None}

where

?exec_sa is the Cloud Deploy execution SA for a delivery pipeline target ?cloudrun_service is a Cloud Run service (ContainerService) the target deploys to ?exec_sa has effective run.services.update / run.jobs.run on ?cloudrun_service

emit

source typeServiceAccount
target typeContainerService
source?exec_sa
target?cloudrun_service
permissionsrun.services.update run.jobs.run
conditionsiam_permission
state logicACTIVE when the SA's effective run.developer (or equivalent) permissions on the Cloud Run service are confirmed. CONDITIONAL(iam_permission) when permissions are unconfirmed. For Cloud Run, CanDeploy is also CanModifyCode (run.services.update swaps the image) — see cloudrun.yaml for the Cloud Run escalation rules that fire once the SA acts on those services.

Narrative

Cloud Deploy execution SA {exec_sa.name} holds Cloud Run deployment permissions on service {cloudrun_service.name} (run.developer or equivalent), giving it CanDeploy to that service. An attacker who executes as {exec_sa.name} (via release/rollout creation) can deploy arbitrary code to {cloudrun_service.name}.

Raw rule rules/derived/gcp/clouddeploy.yaml

id: gcp-deploy-exec-sa-can-deploy-cloudrun
emits: CanDeploy
description: The Cloud Deploy execution SA's Cloud Run deployment permissions (run.developer) give it
  CanDeploy to a Cloud Run service.
applies_to:
- gcp
match:
- - exec_sa: null
  - HasPermission
  - cloudrun_service: null
where:
- ?exec_sa is the Cloud Deploy execution SA for a delivery pipeline target
- ?cloudrun_service is a Cloud Run service (ContainerService) the target deploys to
- ?exec_sa has effective run.services.update / run.jobs.run on ?cloudrun_service
emit:
  source_type: ServiceAccount
  target_type: ContainerService
  source: ?exec_sa
  target: ?cloudrun_service
  permissions:
  - run.services.update
  - run.jobs.run
  conditions:
  - iam_permission
  state_logic: "ACTIVE when the SA's effective run.developer (or equivalent) permissions on the Cloud\
    \ Run service are confirmed. CONDITIONAL(iam_permission) when permissions are unconfirmed. For Cloud\
    \ Run, CanDeploy is also CanModifyCode (run.services.update swaps the image) \u2014 see cloudrun.yaml\
    \ for the Cloud Run escalation rules that fire once the SA acts on those services."
  confidence: 0.9
  derived_from:
  - ?exec_sa HasPermission ?cloudrun_service (GCP IAM effective permission)
  - gcp-deploy-executes-as
  false_positive_note: "Validate the SA's effective permissions on the SPECIFIC service, not just project\
    \ level. A SA with run.developer project-wide can deploy to ALL Cloud Run services \u2014 record the\
    \ widest reachable scope. An attacker who executes as {exec_sa.name} (via release/rollout creation)\
    \ can then update/redeploy this service with arbitrary code."
  narrative: Cloud Deploy execution SA {exec_sa.name} holds Cloud Run deployment permissions on service
    {cloudrun_service.name} (run.developer or equivalent), giving it CanDeploy to that service. An attacker
    who executes as {exec_sa.name} (via release/rollout creation) can deploy arbitrary code to {cloudrun_service.name}.
move · open · esc close