← Back

Container Image Pinning and Provenance That Matter

Use image digests and provenance to identify what you deploy, review where it came from, and keep security updates moving through an auditable release process.

Container image pinning answers which artifact you selected. Provenance provides evidence about how an artifact was built. Neither choice makes an image safe by itself, and combining them without an update policy can leave you confidently deploying an obsolete image.

A useful production policy connects three decisions: artifact identity, acceptable build origin, and how an approved replacement reaches production. If one is missing, the other two carry more meaning than they can support.

Give releases an identity you can inspect

Docker documents that image tags can be moved and that digest references select a specific image version. It also notes the trade-off: pinning opts you out of automatically picking up a changed tag, including security fixes. Docker build best practices.

I would record both the readable release name and the resolved digest. Humans benefit from a version such as release-2026-11; deployment machinery benefits from an immutable identifier. The readable name should help explain the digest, not silently replace it as the actual selection mechanism.

A release record might look like this:

Application: invoice-worker
Source revision: reviewed repository commit
Image reference: registry.example/invoice-worker@sha256:<verified-digest>
Target platforms: documented deployment architectures
Build run: immutable CI run reference
Approval: reviewer and time
Previous approved image: separately recorded digest

This is an illustrative record with placeholders. Do not paste the placeholder digest into deployment configuration. Resolve it from your registry and preserve the exact value tested by your release process.

Decide what provenance must prove

Docker's BuildKit provenance attestations describe build information, with min and max modes offering different detail. The documentation warns that max mode exposes build argument values; secrets should use dedicated secret mechanisms instead. Docker provenance documentation.

The presence of a provenance file should begin a review, not finish it. Write down which source repository, builder, workflow, and revision your policy accepts. Ask how the evidence is authenticated and tied to the digest you plan to deploy. A document stating “built from the right source” is weak evidence if any uploader can replace that document.

Separate inspection from verification in tooling and in language. “The metadata contains our repository URL” is an inspection result. “Our verifier accepted the expected builder identity and artifact binding” is a stronger, different result. Record which one your pipeline actually performs.

An unsigned attestation may still help debugging. It should not be described as equivalent to verified evidence from a trusted build service. Likewise, an authenticated build can faithfully produce vulnerable code. Build origin and application safety are separate questions.

Promote the tested artifact

My preferred release design builds once, tests the resulting image, then promotes that identity through environments. Rebuilding for production makes the release harder to reason about unless the rebuild itself is part of a carefully verified process.

Consider a hypothetical staging pass on Monday followed by a production rebuild on Tuesday. If the build resolves a different dependency, the tested and deployed artifacts may differ despite sharing source code. Recording only the Git commit hides that distinction.

Environment configuration belongs in the deployment contract. If the artifact genuinely needs environment-specific compilation, make that explicit: record separate artifact identities and test the production-targeted output. Do not describe it as the same binary merely because both builds came from one commit.

Promotion also needs a retention policy. A rollback plan pointing at an image the registry has garbage-collected is a document, not a recovery path. Decide how long approved and previous releases must remain available, and test retrieval under the credentials responders will actually use.

Keep pin updates boring and reviewable

The update process should open an understandable change: old digest, new digest, upstream release information, provenance result, and relevant tests. Assign an owner to blocked updates rather than leaving a growing pile of automated pull requests.

I would divide updates by consequence. A base-image refresh may warrant a focused runtime smoke test; a language-runtime change may require broader compatibility testing. The test scope should reflect what changed in the executable environment, not just whether a bot labeled the update “patch.”

Define a path for urgent security updates without inventing a universal deadline. Teams have different exposure, rollback capacity, and contractual obligations. The useful policy names who evaluates risk, who can authorize an exception, and what evidence must follow an expedited release.

A frozen digest is an intentional state only when someone owns its review date. Otherwise, immutability has quietly become abandonment.

Verify the deployment record during incidents

Run a simple exercise: choose a deployed service and ask another engineer to identify its image digest, producing build, source revision, and previous approved artifact. If they need the original author's laptop, improve the release record before adding more attestations.

Then simulate an unacceptable build origin in a test environment. Confirm whether deployment is rejected or merely annotated. Both behaviors can be legitimate during a rollout of policy, but dashboards should not imply enforcement while the gate is informational.

Artifact evidence depends on the build job authority boundary and the deployment identity trust policy. A release record should connect those identities to the exact artifact tested, with a working process to replace it.