Skip to content

[Supply chain] Pin Dockerfile base images to immutable digests #215

Description

@seonghobae

Buyer / reproducibility gap

Protected develop@622e5e6c3d534f230c390f10e3832efadfc01825 builds and runs mightyETL containers from tag-only Dockerfile inputs:

FROM maven:3.9.13-eclipse-temurin-25 AS build
...
FROM eclipse-temurin:25-jre

Both tags are mutable registry references. The same protected source can therefore resolve to different build/runtime bytes at different times, weakening reproducibility, incident reconstruction, SBOM/provenance identity, and acquisition supply-chain evidence even before the dedicated release workflow in #165 exists.

Status: known_gap; bounded direct-develop implementation is path-disjoint from active .dockerignore PR #214 and Compose/Replit work. Recheck exact open-PR changed paths and live develop immediately before mutation.

RCA

  • Immediate cause: both external FROM instructions use tags without @sha256:.
  • Technical root cause: human-readable version selection and immutable image identity are conflated; tags select an update channel but do not bind one exact image index.
  • Control failure: repository tests do not fail when a new tag-only base image enters the production Dockerfile.
  • Risk: an upstream tag move can change compilers, OS packages, runtime libraries and vulnerability posture without a mightyETL commit or review, making exact-source rebuilds non-deterministic.

Docker's maintained build guidance explicitly states that tags are mutable and recommends digest pinning when reproducibility/auditability is required. Dockerfile FROM supports image:tag@digest, allowing the readable tag to remain while the digest binds immutable content. Docker's image-digest guidance describes digests as SHA-256 content identifiers and Docker build-policy guidance provides a fail-closed isCanonical digest-reference pattern.

Current registry evidence — reverify immediately before GREEN

At issue creation, Docker Hub reports the following multi-platform index digests for the exact tags in protected Dockerfile:

  • maven:3.9.13-eclipse-temurin-25sha256:ade3c87e3cdfbe04932afa16b31814cbf60b0122d21d78a76530684a1eeb7cc2;
  • eclipse-temurin:25-jresha256:f19dbf0a22d0b3658fda48ce7d7181df05ad14bda151dd5ad12cc09d1451c70e.

These are dated external-input evidence, not timeless architecture. Before writing the production Dockerfile, re-fetch the tag pages and verify the selected digest corresponds to the intended tag; do not invent, truncate, or reuse a platform-layer digest in place of the multi-platform index digest.

Bounded remediation

  1. RED first with a repository-level test that parses every external FROM in the production Dockerfile and requires a full lowercase SHA-256 digest while retaining an explicit non-latest tag for reviewability.
  2. Observe hosted RED against exact test-only head; setup/import/fixture failure does not qualify.
  3. Reverify current Docker Hub index digests for the two exact tags.
  4. Change only the two FROM references to tag@sha256:<64-hex>.
  5. Keep multi-stage behavior, Maven/JDK/JRE versions, non-root runtime user, service build selection and application entrypoint unchanged.
  6. Add source-backed supply-chain doctoring / CHANGELOG only after behavior GREEN and only if needed by a fail-first documentation contract; do not race canonical docs: establish canonical commercial architecture baseline #149.

Acceptance

  • every external production Dockerfile FROM is digest-pinned and no latest/tag-only base remains;
  • the human-readable tags remain present so dependency-update review can explain semantic version intent;
  • the selected digests are current verified Docker Hub index digests for the declared tags at implementation time;
  • malformed/truncated/non-SHA256 digest references fail the repository contract;
  • a newly added tag-only external FROM makes CI fail;
  • full reactor tests and current dependency/SBOM/SAST/security checks regenerate on the exact source candidate;
  • image pinning is recorded as an input-reproducibility control without claiming the final container is byte-for-byte reproducible or release-ready;
  • [Release/Supply chain] Establish reproducible exact-head artifacts and provenance #165 release/provenance later binds exact Dockerfile inputs, build platform, artifact digest, SBOM and attestation together;
  • literal-source, non-vacuous coverage, scanner completeness and independent review remain separate merge/release gates.

Primary references — APA 7

Docker. (2026). Building best practices: Pin base image versions. https://docs.docker.com/build/building/best-practices/

Docker. (2026). Dockerfile reference: FROM. https://docs.docker.com/reference/dockerfile

Docker. (2026). Image digests. https://docs.docker.com/dhi/core-concepts/digests/

Relationships: #165 release/reproducibility/provenance; #213/#214 Docker build-context secret exclusion; #168/#169 runtime supply-chain cleanup; #159 canonical documentation.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions