azure-arm-deployment-write-trigger
Principal with deployments/write can submit or re-run a deployment, triggering the current template (including any deploymentScript resources) to execute.
match (effective permission)
{
"action": "Microsoft.Resources/deployments/write",
"scope_type": "resource|resourceGroup|subscription|managementGroup"
}
emit
| source type | Identity |
|---|---|
| target type | Compute |
| source | <principal> |
| target | <ARM deployment (BuildWorker)> |
| permissions | Microsoft.Resources/deployments/write |
| conditions | iam_permission |
| state logic | ACTIVE when the principal holds deployments/write at scope and no deny assignment blocks it (the principal can submit a new deployment or re-deploy an existing one at will). cicd-chains rule 2 (cicd-trigger-runner-executes-as) consumes this CanTrigger + the deployment's ExecutesAs(UAMI) to emit CanExecuteAs CONDITIONAL(attacker_influenced_definition) — ACTIVE only if the current template already contains attacker-controlled code. When the principal also holds CanModifyCode on the deployment (rules 1–2 above), cicd-chains rule 1 fires with ACTIVE state (modify + trigger). BLOCKED if a deny assignment covers deployments/write. |
Narrative
{principal.name} can submit or re-run ARM deployment {target.name} (deployments/write), triggering the current template to execute; if the template contains a deploymentScript with attacker-influenced code (from a prior poisoning), re-triggering the deployment runs that code as the UAMI (cicd-chains cicd-trigger-runner-executes-as, CONDITIONAL unless attacker influence over the current template is confirmed).
Raw rule rules/derived/azure/arm-deployments.yaml
id: azure-arm-deployment-write-trigger
emits: CanTrigger
description: Principal with deployments/write can submit or re-run a deployment, triggering the current
template (including any deploymentScript resources) to execute.
match_effective_permission:
action: Microsoft.Resources/deployments/write
scope_type: resource|resourceGroup|subscription|managementGroup
emit:
source_type: Identity
target_type: Compute
source: <principal>
target: <ARM deployment (BuildWorker)>
permissions:
- Microsoft.Resources/deployments/write
conditions:
- iam_permission
state_logic: "ACTIVE when the principal holds deployments/write at scope and no deny assignment blocks\
\ it (the principal can submit a new deployment or re-deploy an existing one at will). cicd-chains\
\ rule 2 (cicd-trigger-runner-executes-as) consumes this CanTrigger + the deployment's ExecutesAs(UAMI)\
\ to emit CanExecuteAs CONDITIONAL(attacker_influenced_definition) \u2014 ACTIVE only if the current\
\ template already contains attacker-controlled code. When the principal also holds CanModifyCode\
\ on the deployment (rules 1\u20132 above), cicd-chains rule 1 fires with ACTIVE state (modify + trigger).\
\ BLOCKED if a deny assignment covers deployments/write."
false_positive_note: Triggering a deployment runs the CURRENT template as-is; this path only yields
CanExecuteAs(UAMI) if the current template ALREADY contains a deploymentScript with attacker-influenced
content (an existing script the attacker previously modified, or a template spec version the attacker
already poisoned). A clean, unmodified template with no deploymentScript does not result in CanExecuteAs
from triggering alone. cicd-chains rule 2 keeps this CONDITIONAL by default; do not emit ACTIVE execute-as
from trigger alone unless attacker influence over the current template is established.
narrative: '{principal.name} can submit or re-run ARM deployment {target.name} (deployments/write),
triggering the current template to execute; if the template contains a deploymentScript with attacker-influenced
code (from a prior poisoning), re-triggering the deployment runs that code as the UAMI (cicd-chains
cicd-trigger-runner-executes-as, CONDITIONAL unless attacker influence over the current template is
confirmed).'
derived_from:
- <deployments/write effective permission>
- "cicd-chains: cicd-trigger-runner-executes-as (roll-up, CONDITIONAL \u2014 cited)"