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.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
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) — 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}.