Olympus Docs
ADRs

0014, Image pinning by digest in production

Why production compose files must reference images by sha256 digest, not tag

Status: Accepted Date: 2026-02 Stakeholders: Bobby Nannier

Context

A compose file can reference images by:

FormExampleStability
Tagoryd/kratos:v1.xMutable, tag can be reassigned
Tag + digestoryd/kratos:v1.x@sha256:abc...Immutable; tag is informational
Digest onlyoryd/kratos@sha256:abc...Immutable

A tag-only reference is vulnerable to:

  • Supply-chain attack via tag reassignment.
  • "Latest" surprises, :latest resolves differently over time.
  • Inconsistency between deploys.

Decision

Production compose.prod.yml must reference every image by digest. Tags can be included for human readability but are not authoritative.

The verify-image-pins.yml CI workflow fails the build if any image in prod/compose.prod.yml is referenced without @sha256:....

Consequences

  • Deploys are reproducible. Re-running deploy.yml against the same compose ref produces the same images.
  • Image updates are deliberate. Bumping requires editing the digest, which means consciously evaluating the new image's changelog.
  • Slightly verbose. Compose files get ~70-char digest strings on every image: line.
  • Dependabot helps. Configured to bump digests on new Ory and other dependency releases (see .github/dependabot.yml).

Dev exception

compose.dev.yml allows tag-only references for ergonomics (oryd/kratos:v1.x is fine in dev). The dev workflow doesn't run verify-image-pins.yml.

On this page