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).

derived aws emits CanModifyConfiguration

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} HasPermission {'repository': None}

where

node_type(?repository) == ContainerRegistry ?repository.provider_type in ['AWS::ECR::Repository'] ?repository.imageTagMutability == 'IMMUTABLE' effective_permission(?principal, 'ecr:PutImageTagMutability', ?repository) == true

emit

source typeIdentity
target typeContainerRegistry
source?principal
target?repository
permissionsecr:PutImageTagMutability
conditionsiam_permission
state logicACTIVE 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.'
move · open · esc close