Filter concepts by levelShowing all levels.

AWS · ECR and Supply Chain

ECR and Container Supply Chain

Repositories, tags and authentication; lifecycle and promotion; provenance, scanning, and non-root

  • A 12-hour token, not a passwordscoped to the IAM principal that asked
  • Tags are mutable, digests are notdeploy by digest, enable tag immutability
  • Repositories grow without a policyexpire untagged images first
  • Scan on push, then keep rescanninga clean scan has a shelf life

1.ECR Repositories, Tags, and Authentication

ECR is a managed private container registry. Images live in repositories, and access is controlled with IAM — both identity policies and a resource-based repository policy. The Docker CLI does not speak IAM, so authentication works by exchanging your IAM credentials for a registry authorization token and passing it to `docker login`.

Key features

  • ECR supports private repositories with resource-based permissions using IAM, and handles Docker images, OCI images, and OCI-compatible artifacts
  • An authorization token's permission scope matches the IAM principal that retrieved it, and the token is valid for 12 hours
  • `aws ecr get-login-password | docker login --username AWS --password-stdin <account>.dkr.ecr.<region>.amazonaws.com` is the standard authentication step
  • A tag is a mutable pointer to an image; a digest (`@sha256:…`) names specific bytes and never changes
  • Tag immutability is a repository setting that prevents an existing tag from being overwritten by a new push
  • Cross-Region and cross-account replication is a registry-level setting configured per Region, and pull-through cache rules mirror an upstream public registry into your private one, keeping the cached copy refreshed

Tag or digest?

Tag or digest?
ReferenceResolves toUse it for
`api:latest`Whatever was pushed lastLocal development only
`api:v2.4.1`That tag, unless someone repushes itHuman-readable release naming
`api:<git-sha>`One commit's build, if tags are immutableTraceability from running task to source
`api@sha256:9f2c…`Exactly those bytes, alwaysAnything a deployment or task definition references
From IAM identity to a pushed image
GetAuthorizationTokenget-login-passwordpush / pullstores as

IAM principal

role or user

Authorization token

valid 12 hours, same scope as the principal

docker login

username AWS, token as password

ECR repository

IAM + repository policy

Image + digest

sha256:… — immutable

  • IAM principal — role or user
    • leads to Authorization token (GetAuthorizationToken)
  • Authorization token — valid 12 hours, same scope as the principal
    • leads to docker login (get-login-password)
  • docker login — username AWS, token as password
    • leads to ECR repository (push / pull)
  • ECR repository — IAM + repository policy
    • leads to Image + digest (stores as)
  • Image + digest — sha256:… — immutable

Signature

IAM principal → GetAuthorizationToken (12h) → docker login → repository (tag: mutable · digest: not)

ECR = private registry with IAM in front. `get-login-password` mints a 12-hour token scoped to your principal. Tags are mutable pointers; digests are not. Turn on tag immutability, and reference images by digest everywhere a deployment does.

2.Lifecycle Policies and Promotion Between Environments

A repository accumulates an image per build forever unless you tell it not to. A lifecycle policy is a set of rules that expire images automatically — keep the last N, expire untagged images after N days. Promotion is the other half: moving one already-built image through environments rather than building a separate image for each.

Key features

  • Lifecycle policies let you define rules that clean up unused images, and AWS provides a way to test a rule before applying it to the repository
  • Untagged images are the usual bulk — each repush of a mutable tag orphans the image it replaced
  • ECR pricing is driven by stored data plus transfer, so an unbounded repository is a slowly growing bill with no visible owner
  • Promotion means deploying the same digest to each environment in turn, which is what makes a staging test a statement about production
  • Where environments are separate accounts, promotion is either cross-account pull (a repository policy granting the other account) or replication into that account's registry
  • A "promotion tag" (`api:prod`) alongside the digest is a convenient human label, but the deployment must still reference the digest

Lifecycle rules worth having

Lifecycle rules worth having
RuleSelectionEffect
Expire untaggedUntagged images older than 7 daysRemoves the orphans left by repushes
Keep recent buildsTag prefix `sha-`, keep the most recent 30Bounds the day-to-day build churn
Keep releases longerTag prefix `v`, keep the most recent 100Old releases stay redeployable for rollback
Expire feature branchesTag prefix `pr-`, older than 14 daysBranch builds do not need to outlive the branch

Command

text
# Promotion is a deploy target change, not a build
build  -> api@sha256:9f2c...
staging: deploy api@sha256:9f2c...
prod   : deploy api@sha256:9f2c...   # the same image, promoted

Lifecycle policies are the only thing that bounds a repository's growth — start with expiring untagged images, then scope retention by tag prefix so releases outlive build churn. Promotion means deploying the same digest onward, never rebuilding per environment.

3.Provenance, Minimal Base Images, Scanning, and Non-Root

A container image is code you did not write, shipped alongside code you did. Provenance is knowing where each layer came from. A minimal base image reduces how much of that unwritten code exists at all. Scanning tells you which of it has known vulnerabilities. Running as a non-root user limits what an exploit can do once it is inside.

Key features

  • ECR image scanning identifies software vulnerabilities in images, and a repository can be configured to scan on push so every new image is scanned automatically
  • A pull-through cache rule mirrors an upstream public registry into your private registry, so your builds do not depend on a public registry being available or unchanged
  • ECR managed signing generates cryptographic signatures when images are pushed, which is the provenance half of the supply chain story
  • A smaller base image has fewer packages, so fewer CVEs, a smaller download, and a smaller attack surface — a distroless or slim base often removes hundreds of packages
  • A container runs as root unless the image says otherwise; `USER app` in the Dockerfile is the change, and it must come after the steps needing root
  • Build secrets passed as `ARG` remain in the image layers even if a later layer deletes them — a multi-stage build or a secret mount is what keeps them out — and scan results age, so scheduled rebuilds matter as much as scan-on-push

What each control actually prevents

What each control actually prevents
ControlPreventsDoes not help with
Pull-through cacheA public base image disappearing or being repointedVulnerabilities already in that image
Minimal base imageHundreds of CVEs in packages you never useVulnerabilities in your own dependencies
Scan on pushShipping a known-vulnerable image todayCVEs published after the scan
Non-root userAn exploited process modifying the filesystem or escalatingThe exploit itself
Multi-stage buildBuild secrets and toolchains surviving into the runtime imageSecrets injected at runtime
Four controls, four points in the chain

Provenance

Pull-through cache + signing — you know where each layer came from

Minimal base

Fewer packages means fewer CVEs and less attack surface

Scanning

Scan on push, and rescan as new CVEs are published

Non-root runtime

Limits what an exploited process can reach

  1. Provenance — Pull-through cache + signing — you know where each layer came from
  2. Minimal base — Fewer packages means fewer CVEs and less attack surface
  3. Scanning — Scan on push, and rescan as new CVEs are published
  4. Non-root runtime — Limits what an exploited process can reach

Signature

provenance (cache + signing) · minimal base · scan on push + rescan · USER non-root · multi-stage for secrets

Know where the base image came from (pull-through cache, signing), keep it small, scan on push and keep rescanning as CVEs are published, and run as a non-root user. Build secrets survive in layers unless a multi-stage build or a secret mount keeps them out.

Remember

  • Two tasks can run different code under the same tag — tag immutability is what stops it.
  • A lifecycle rule can expire the image you need to roll back to; scope aggressive rules to build tags only.
  • Containers run as root unless the image sets `USER`.
  • A build secret passed as `ARG` stays in the layers even after it is deleted.

Pro tip

  • A pull-through cache rule makes your builds independent of a public registry being available or unchanged — and gives every layer a known origin.
  • Rebuild on a schedule, not only on code change: base image updates are how most published CVEs actually get fixed.

Next up

  • ECS Deployment Architecture
  • CI/CD on AWS
  • AWS Security Services

Sources

  • What is Amazon ECR? — docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html
  • Private registry authentication in Amazon ECR — docs.aws.amazon.com/AmazonECR/latest/userguide/registry_auth.html
  • Checked against official AWS documentation 2026-08-29

Spotted a mistake on this page? Tell us.