ADR 0026: Digest-first runtime image certification and fail-closed GHCR promotion¶
Status¶
Accepted.
Context¶
The runtime-image workflow currently pushes version, SHA, and latest aliases
before digest-pinned smoke, SBOM generation, and attestation verification are
complete. A failed post-push check can leave an uncertified public alias.
Manifest lookup also collapses absence, authorization failure, throttling, and
registry outage into one result.
GHCR and the OCI Distribution API do not provide a portable atomic create-if-absent operation, permanent immutable-tag policy, or multi-tag transaction. Workflow ordering can reduce risk but cannot honestly claim those registry guarantees.
Decision¶
Use two explicit commit boundaries:
- Certification: build and push only a digest-addressed candidate, test
IMAGE@DIGEST, generate and verify provenance and SBOM attestations, then writedpone.runtime-image-certification.v1with PASS last. - Promotion: a separately permissioned, globally serialized job consumes
that exact certification and reconciles version, SHA, and
latestaliases.
Registry lookup has three results:
- authenticated HTTP 200 with a canonical digest is
PRESENT; - authenticated HTTP 404 is
ABSENT; - every other response or transport/parsing failure is
ERROR.
Fixed aliases use create-or-compare semantics. The expected digest is a no-op;
another digest blocks. latest advances only to a greater certified stable
SemVer, remains on the same digest, or preserves a newer version. It never
regresses.
Every alias write is followed by an authenticated digest postcondition. Promotion evidence records each non-atomic transition. A partial alias state is workflow failure and can be repaired idempotently with the same certification. No automated workflow overwrites a conflicting fixed alias or deletes a failed candidate.
Build and promotion permissions remain separate. Public deployment contracts continue to require image digests.
Consequences¶
- Smoke or attestation failure cannot publish release aliases.
- Registry/authentication failures fail closed rather than masquerading as absence.
- Same-digest reruns repair interrupted promotion safely.
- Different-digest fixed aliases become incident blockers.
latestis monotonic by certified SemVer, not completion time.- Version and SHA aliases are workflow-governed create-or-compare references, not registry-enforced immutable objects.
- Promotion is not atomic across aliases; evidence and recovery expose this limitation.
- External writers can still mutate GHCR tags. Stronger immutability requires external registry policy and drift monitoring.
- Replacing the wall-clock image label removes guaranteed rerun drift, but full reproducible builds remain out of scope until all build inputs are pinned.
Related¶
docs/feature-design-runtime-image-digest-first-promotion-v0732.mddocs/runtime-image.mddocs/release.md.github/workflows/runtime-image.ymltools/agent_policy/runtime_image_promotion.py