aws-ecr-set-policy-can-modify-policy

A principal with ecr:SetRepositoryPolicy can rewrite the repository resource policy to grant itself or any other principal push or pull access - policy-mutation escalation prerequisite.

derived aws emits CanModifyPolicy

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'] effective_permission(?principal, 'ecr:SetRepositoryPolicy', ?repository) == true

emit

source typeIdentity
target typeResourcePolicy
source?principal
target<repository policy of ?repository>
permissionsecr:SetRepositoryPolicy
conditionsiam_permission
state logicACTIVE when the principal has effective ecr:SetRepositoryPolicy on the repository (not denied by SCP or permission boundary). The downstream CanModifyCode (push path) is a SECOND step after the policy is rewritten; emit this edge to capture the policy-mutation capability; the engine will derive CanModifyCode once the self-granted push permission is realized. BLOCKED when an SCP or permission boundary denies ecr:SetRepositoryPolicy.

Narrative

{principal.name} can rewrite the resource policy of {repository.name} (ecr:SetRepositoryPolicy) to grant itself or any principal push or pull access, enabling self-grant of the supply-chain push path.

Raw rule rules/derived/aws/ecr.yaml

id: aws-ecr-set-policy-can-modify-policy
emits: CanModifyPolicy
description: "A principal with ecr:SetRepositoryPolicy can rewrite the repository resource policy to grant\
  \ itself or any other principal push or pull access \u2014 policy-mutation escalation prerequisite."
match:
- - principal: null
  - HasPermission
  - repository: null
where:
- node_type(?repository) == ContainerRegistry
- ?repository.provider_type in ['AWS::ECR::Repository']
- effective_permission(?principal, 'ecr:SetRepositoryPolicy', ?repository) == true
emit:
  source_type: Identity
  target_type: ResourcePolicy
  source: ?principal
  target: <repository policy of ?repository>
  permissions:
  - ecr:SetRepositoryPolicy
  conditions:
  - iam_permission
  state_logic: ACTIVE when the principal has effective ecr:SetRepositoryPolicy on the repository (not
    denied by SCP or permission boundary). The downstream CanModifyCode (push path) is a SECOND step after
    the policy is rewritten; emit this edge to capture the policy-mutation capability; the engine will
    derive CanModifyCode once the self-granted push permission is realized. BLOCKED when an SCP or permission
    boundary denies ecr:SetRepositoryPolicy.
  confidence: 0.92
  derived_from:
  - effective_permission(?principal, ecr:SetRepositoryPolicy, ?repository)
  false_positive_note: "SetRepositoryPolicy alone is not CanModifyCode \u2014 it is the precursor that\
    \ enables push by rewriting the policy. The escalation chain requires the additional push permissions\
    \ after the policy change. The engine will re-evaluate effective permissions after the policy mutation\
    \ is modeled; if the new policy grants PutImage, aws-ecr-push-can-modify-code will fire. Do not pre-collapse\
    \ this into CanModifyCode here."
  narrative: '{principal.name} can rewrite the resource policy of {repository.name} (ecr:SetRepositoryPolicy)
    to grant itself or any principal push or pull access, enabling self-grant of the supply-chain push
    path.'
move · open · esc close