When to run this
Once per release, against the exact digest that is about to be deployed. Not against the tag, not against last night’s build, and not against the branch. If the digest changes after this checklist runs, the checklist has to run again — that is the whole point of pinning.
Its companion, docker-checklist-registry-pull-readiness, checks
that the deploy host can reach and pull the artefact. This one
checks what the artefact contains and where it came from.
Setting up
IMAGE='registry.example.com/platform/api@sha256:REPLACE_ME'
BASE_IMAGE='docker.io/library/debian:12-slim'
EXPECTED_IDENTITY='https://github.com/example-org/api/.github/workflows/release.yml@refs/heads/main'
EXPECTED_ISSUER='https://token.actions.githubusercontent.com'
Run from a checkout at the commit the release was built from, so the Dockerfile items examine the same source the image came from.
The three items that are usually theatre
Three of the controls on this list are commonly implemented in a way that produces artefacts without producing security. They are worth separating out because each looks green in a pipeline dashboard.
A scan is not coverage. A scanner reports the packages it can
identify: entries in the distro package database, and dependencies
declared in a lockfile it recognises. A Go binary with its
dependencies compiled in, a JAR with a shaded library inside it, a
library vendored into third_party/, an npm tree installed and
then flattened, anything pulled in by a curl in a RUN step —
none of that is in the report, and none of it is reported as
missing either. scan-blind-spots-named exists because a clean
report on an image that is mostly one static binary is
approximately no information, and the honest response is to write
down what the tool cannot see and cover it another way.
A signature is not enforcement. Signing produces a signature.
Security comes from something refusing to run an artefact that
does not verify. Between those two there is usually a gap that
nobody notices, because signing succeeds visibly and verification
fails silently by not existing. signature-negative-test is the
only item that closes it.
An SBOM is not an inventory. An SBOM attached to an image is a document. The control is the ability to answer, in under an hour, which of your running images contain a given package at a given version. If that query has no answer today, the SBOM will not help on the day it is asked.
Evidence and sign-off
Attach to the release record: the scan output, the verification output for the exact digest, the SBOM diff, and the written list of components the scanner could not see. That last one is the document that ages best — it is the only place your actual coverage gap is recorded, and it is what the next person needs when a static dependency turns out to matter.
- Release: _________________ Digest: ___________
- Operator: _________________ Date: ___________
- Reviewer: ________________ Date: ___________