azure-acr-push
AcrPush (registries/push/write) over the registry - supply-chain primitive consumed by container-chains.
match (effective permission)
{
"action": "Microsoft.ContainerRegistry/registries/push/write",
"scope_type": "resource|resourceGroup|subscription"
}
where
principal effectively holds AcrPush, Contributor, Owner, or a custom role including Microsoft.
ContainerRegistry/registries/push/write
emit
| source type | Identity |
|---|---|
| target type | ContainerRegistry |
| source | <principal> |
| target | <registry> |
| permissions | Microsoft.ContainerRegistry/registries/push/write |
| state logic | ACTIVE when the principal can push to the registry and the push write action is not blocked by a deny assignment or scope-map restriction. CONDITIONAL(resource_policy) when a repository-scoped token scope map limits push to specific repositories — in that case emit only for the in-scope repositories. BLOCKED when a deny assignment covers push/write or the registry is in a locked state. |
Narrative
{principal.name} can push images to registry {target.name} (Microsoft.ContainerRegistry/registries/push/write / AcrPush); every workload that pulls a mutable tag from this registry will execute the attacker-injected layers on its next pull or restart (container-chains rolls the supply-chain fan-out to each consumer and their execution identities).
Raw rule rules/derived/azure/acr.yaml
id: azure-acr-push
emits: CanModifyCode
description: "AcrPush (registries/push/write) over the registry \u2014 supply-chain primitive consumed\
\ by container-chains."
match_effective_permission:
action: Microsoft.ContainerRegistry/registries/push/write
scope_type: resource|resourceGroup|subscription
where:
- principal effectively holds AcrPush, Contributor, Owner, or a custom role including Microsoft.ContainerRegistry/registries/push/write
emit:
source_type: Identity
target_type: ContainerRegistry
source: <principal>
target: <registry>
permissions:
- Microsoft.ContainerRegistry/registries/push/write
state_logic: "ACTIVE when the principal can push to the registry and the push write action is not blocked\
\ by a deny assignment or scope-map restriction. CONDITIONAL(resource_policy) when a repository-scoped\
\ token scope map limits push to specific repositories \u2014 in that case emit only for the in-scope\
\ repositories. BLOCKED when a deny assignment covers push/write or the registry is in a locked state."
confidence: 0.97
derived_from:
- "container-chains image-push-poisons-consumers (CITED \u2014 rolls CanModifyCode(registry) + ContainsResourceReference(consumer)\
\ into CanModifyCode(consumer))"
- "container-chains poisoned-image-executes-as (CITED \u2014 rolls CanModifyCode(consumer) + ExecutesAs\
\ into CanExecuteAs)"
false_positive_note: "This edge targets the ContainerRegistry node. container-chains `image-push-poisons-consumers`\
\ fans this out to each consuming workload \u2014 do NOT duplicate that derivation here. Digest-pinned\
\ consumers (ContainsResourceReference.image_mutable == false) are guarded in container-chains (those\
\ fan-outs are BLOCKED). If the principal holds only a repository-scoped token with push limited to\
\ specific repos, scope this emit to those repository nodes rather than the entire registry. Trust-policy\
\ gate: if trustPolicy.status==enabled and consumers verify signatures, the push may not reach consumers\
\ without a valid signature \u2014 emit as CONDITIONAL(resource_policy) rather than ACTIVE."
narrative: '{principal.name} can push images to registry {target.name} (Microsoft.ContainerRegistry/registries/push/write
/ AcrPush); every workload that pulls a mutable tag from this registry will execute the attacker-injected
layers on its next pull or restart (container-chains rolls the supply-chain fan-out to each consumer
and their execution identities).'