azure-acr-task-run-write
registries/taskRuns/write queues a manual run of an existing ACR Task - triggers execution of whatever the current task definition specifies as the task's MI.
match (effective permission)
{
"action": "Microsoft.ContainerRegistry/registries/taskRuns/write",
"scope_type": "resource|resourceGroup|subscription"
}
where
principal effectively holds Contributor, Owner, or a custom role including Microsoft.
ContainerRegistry/registries/taskRuns/write
target task exists and has an ExecutesAs managed identity
emit
| source type | Identity |
|---|---|
| target type | BuildWorker |
| source | <principal> |
| target | <task (BuildWorker)> |
| permissions | Microsoft.ContainerRegistry/registries/taskRuns/write |
| conditions | trigger_exists |
| state logic | CONDITIONAL(trigger_exists) — triggering a run with an unmodified definition only becomes a meaningful attack step if the definition already contains attacker- influenced code (a poisoned dependency, a tampered base image, an attacker-authored branch). Without that precondition, triggering the current definition yields at most legitimate task output and does not give the attacker code execution. Upgrade to ACTIVE only if the contributing CanModifyCode(principal → task) edge is also ACTIVE (definition is already under attacker control). cicd-chains cicd-trigger-runner-executes-as handles the conditional derivation. |
Narrative
{principal.name} can trigger a manual run of ACR Task {target.name} (registries/taskRuns/write); if the task definition is already under attacker control (poisoned step, tampered base image), triggering it executes attacker code as the task's managed identity (cicd-chains derives CanExecuteAs CONDITIONAL).
Raw rule rules/derived/azure/acr.yaml
id: azure-acr-task-run-write
emits: CanTrigger
description: "registries/taskRuns/write queues a manual run of an existing ACR Task \u2014 triggers execution\
\ of whatever the current task definition specifies as the task's MI."
match_effective_permission:
action: Microsoft.ContainerRegistry/registries/taskRuns/write
scope_type: resource|resourceGroup|subscription
where:
- principal effectively holds Contributor, Owner, or a custom role including Microsoft.ContainerRegistry/registries/taskRuns/write
- target task exists and has an ExecutesAs managed identity
emit:
source_type: Identity
target_type: BuildWorker
source: <principal>
target: <task (BuildWorker)>
permissions:
- Microsoft.ContainerRegistry/registries/taskRuns/write
conditions:
- trigger_exists
state_logic: "CONDITIONAL(trigger_exists) \u2014 triggering a run with an unmodified definition only\
\ becomes a meaningful attack step if the definition already contains attacker- influenced code (a\
\ poisoned dependency, a tampered base image, an attacker-authored branch). Without that precondition,\
\ triggering the current definition yields at most legitimate task output and does not give the attacker\
\ code execution. Upgrade to ACTIVE only if the contributing CanModifyCode(principal \u2192 task)\
\ edge is also ACTIVE (definition is already under attacker control). cicd-chains cicd-trigger-runner-executes-as\
\ handles the conditional derivation."
confidence: 0.75
derived_from:
- "cicd-chains cicd-trigger-runner-executes-as (CITED \u2014 rolls CanTrigger(task) + ExecutesAs(task\u2192\
MI) into conditional CanExecuteAs)"
false_positive_note: "Do NOT emit ACTIVE for trigger-only (no CanModifyCode). Triggering a legitimate,\
\ unmodified task definition does not give the attacker code execution \u2014 it runs authorized build\
\ steps as the MI. The edge is CONDITIONAL because it only matters when combined with another path\
\ that compromised the definition. The confidence penalty (0.75) reflects the precondition on the\
\ definition state. The canonical ARM operation is Microsoft.ContainerRegistry/registries/taskRuns/write.\
\ There is no registries/tasks/runs/write operation \u2014 verify the effective action name."
narrative: '{principal.name} can trigger a manual run of ACR Task {target.name} (registries/taskRuns/write);
if the task definition is already under attacker control (poisoned step, tampered base image), triggering
it executes attacker code as the task''s managed identity (cicd-chains derives CanExecuteAs CONDITIONAL).'