aws-ecr-mutability-unblock
A principal with ecr:PutImageTagMutability can change an IMMUTABLE repository to MUTABLE, unblocking push overwrites on protected tags (prerequisite removal for CanModifyCode).
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?repository) ==
ContainerRegistry
?repository.provider_type in ['AWS::ECR::Repository']
?repository.imageTagMutability == 'IMMUTABLE'
effective_permission(?principal, 'ecr:PutImageTagMutability', ?repository) == true
emit
| source type | Identity |
|---|---|
| target type | ContainerRegistry |
| source | ?principal |
| target | ?repository |
| permissions | ecr:PutImageTagMutability |
| conditions | iam_permission |
| state logic | ACTIVE when the principal has effective ecr:PutImageTagMutability on the repository (not denied by SCP or boundary). This edge expresses the CAPABILITY to change mutability; the downstream CanModifyCode (aws-ecr-push-can-modify-code) becomes CONDITIONAL(image_tag_mutability) — it is not yet ACTIVE until the mutability change is actually made and a push follows. An SCP requiring ecr:PutImageTagMutability to always return IMMUTABLE (enforcement via config rule / SCP condition) would BLOCK this edge. |
Narrative
{principal.name} can change {repository.name} from IMMUTABLE to MUTABLE (ecr:PutImageTagMutability), removing the tag-immutability guard that blocks image push overwrites and enabling the supply-chain push attack path.
Raw rule rules/derived/aws/ecr.yaml
id: aws-ecr-mutability-unblock
emits: CanModifyConfiguration
description: A principal with ecr:PutImageTagMutability can change an IMMUTABLE repository to MUTABLE,
unblocking push overwrites on protected tags (prerequisite removal for CanModifyCode).
match:
- - principal: null
- HasPermission
- repository: null
where:
- node_type(?repository) == ContainerRegistry
- ?repository.provider_type in ['AWS::ECR::Repository']
- ?repository.imageTagMutability == 'IMMUTABLE'
- effective_permission(?principal, 'ecr:PutImageTagMutability', ?repository) == true
emit:
source_type: Identity
target_type: ContainerRegistry
source: ?principal
target: ?repository
permissions:
- ecr:PutImageTagMutability
conditions:
- iam_permission
state_logic: "ACTIVE when the principal has effective ecr:PutImageTagMutability on the repository (not\
\ denied by SCP or boundary). This edge expresses the CAPABILITY to change mutability; the downstream\
\ CanModifyCode (aws-ecr-push-can-modify-code) becomes CONDITIONAL(image_tag_mutability) \u2014 it\
\ is not yet ACTIVE until the mutability change is actually made and a push follows. An SCP requiring\
\ ecr:PutImageTagMutability to always return IMMUTABLE (enforcement via config rule / SCP condition)\
\ would BLOCK this edge."
confidence: 0.9
derived_from:
- effective_permission(?principal, ecr:PutImageTagMutability, ?repository)
- ?repository.imageTagMutability == IMMUTABLE
false_positive_note: "This edge does not by itself yield code execution \u2014 it is a configuration\
\ change that enables the push path. Emit it as a precursor to CanModifyCode, not as a terminal escalation\
\ edge. The escalation consequence requires chaining: this CanModifyConfiguration + aws-ecr-push-can-modify-code\
\ (CONDITIONAL) -> ACTIVE after the mutability change -> container-chains fan-out."
narrative: '{principal.name} can change {repository.name} from IMMUTABLE to MUTABLE (ecr:PutImageTagMutability),
removing the tag-immutability guard that blocks image push overwrites and enabling the supply-chain
push attack path.'