Release and respond
Verify before deployment
Check artifact digest, provenance, signer, source revision, policy, and environment before promoting exactly the reviewed build.
Do not rebuild between approval and production. Promote the same verified artifact.
The failure looks harmless in a pipeline diagram. Staging passes, but production rebuilds the source an hour later. A dependency or tool has changed, so production receives bytes that never passed staging. Everything you validated — tests, scans, manual checks — validated a different artifact.
Promote by digest, not by tag
The fix is to build once and move the immutable artifact through environments. For containers, that means deploying by digest:
image: ghcr.io/acme/api@sha256:7d3e2c1f9a8b4e6d0c5f2a1b8e9d4c3f6a7b0e1d2c9f8a7b6e5d4c3b2a1f0e9d
A tag like :1.4.2 can be repointed to different bytes. The digest cannot. Staging and production referencing the same digest are provably running the same release.
Make the gate verify, not trust
Before promotion, the deployment system should verify that the artifact came from the approved project and workflow, references the expected source, and matches its digest. If the build workflow attests its artifacts (with actions/attest-build-provenance or cosign), the check is one command:
gh attestation verify oci://ghcr.io/acme/api:1.4.2 --repo acme/api
# ✓ Verification succeeded!
# sourceRepositoryURI: https://github.com/acme/api
# workflow: .github/workflows/release.yml@refs/tags/v1.4.2
Read that output as a policy check, not decoration: right repository, right workflow, right ref. A valid signature from an unapproved builder must fail this gate — run the verification in the deploy job and stop on non-zero exit.
Keep configuration outside the artifact
Promoting one immutable artifact keeps the reviewed bytes stable. Environment-specific configuration — URLs, feature flags, credentials — should remain separate, injected at deploy time, so promotion does not require rebuilding the release.
Finally, record what entered production: the digest, the source revision, the provenance identity, and the configuration version. During an incident, that record is the difference between “we know exactly what is running” and guessing.
Record the artifact digest, source revision, provenance identity, and configuration version for one staging deployment. Promote that same digest and save production evidence. Then substitute an artifact with a valid signature from an unapproved builder and prove the deployment gate refuses it.
Lesson completed