skip to content

A change board approved an image by sha256 digest but the deployment names a mutable tag - what is the risk?

level: juniorimportance: must knowfreq 70%

answer

  1. approval and pull are separate moments
  2. a tag is a pointer, not the bytes
  3. push rights outlive the review
  4. no manifest diff shows the swap
  5. digest belongs in the deployed reference

basics

~20 s

The approval is not attached to what runs. Anyone able to push to that repository can re-aim the tag at different bytes, so the next pull fetches an image nobody reviewed, with no change to the deployment.

solid answer

~40 s

A digest names one exact set of bytes; a tag is only a name pointing at a digest, and whoever holds push rights to the repository can move it. If the approved digest lives in the ticket while the deployment references `payments:release-2026.04`, nothing joins the two. A release engineer with legitimate push rights - or anyone holding a stolen push credential - can repoint that tag after the review, and the next pull, restart or scale-out runs the new bytes. The deployment file never changes, so diffing manifests, watching pull requests or replaying the change log detects nothing. The fix is to make the reference that is actually pulled carry the digest, so the approved bytes and the deployed bytes are literally the same string and can be reviewed in one place.

go deeper

for a junior

Be ready to say plainly that a digest names bytes while a tag names a pointer someone can move, and that an approval recorded against a digest protects nothing if the deployment names a tag.

for a middle

Explain where the resolution actually happens and why no diff, commit or change record appears when a tag is repointed - and that a restart or scale-out is enough to pick up the new bytes.

for a senior

Show the production instinct: enumerate every identity with push rights to the repository, put the digest in the configuration under review, and add registry-side controls so an overwrite is refused rather than merely noticed.

for a principal

Own the framing that an approval is worthless unless it is bound to the artifact identity the runtime resolves, and be able to say which claims about the estate you can actually defend to an auditor.

## Two different kinds of name A container image can be named two ways. A **digest** reference (`payments@sha256:1a2b...`) is a cryptographic hash of the image manifest: it names one specific set of bytes, and a client that pulls it recomputes the hash and rejects anything that does not match. Nobody can change what a digest points at, because the digest *is* the content. A **tag** reference (`payments:release-2026.04`) is a mutable pointer stored in the registry: a row that says "this name currently maps to that digest". Whoever can push to the repository can rewrite that row. That difference is the whole question. Pinning to a digest is an integrity control - it makes the identity of the artifact non-negotiable. Naming a tag is a lookup that happens later, under conditions you do not control. ## Where the gap opens Review and execution are two separate moments, and they can be hours or weeks apart. The change board looks at an artifact identified by digest: the scan results, the test evidence and the sign-off are all about those bytes. The deployment, meanwhile, says `:release-2026.04`. At the moment somebody actually pulls, the registry is asked what that name means *now* - not what it meant at review time. So the approval covers a digest, the runtime resolves a tag, and no mechanism compares them. An insider on the release team, or an attacker who has taken over a release account, pushes a modified build and repoints the tag. In a payment-settlement service that means the code moving money is provably not the code the board approved - and the damage is not only the malicious behaviour, it is that the audit trail now says something false. ## Who can actually move the tag The honest blast radius is the union of every identity holding push rights to that repository: release engineers, other teams sharing the repo, every CI job holding a push token, service accounts nobody has rotated, and registry administrators. That set is nearly always much wider than the set of people who reviewed the change, and it is rarely enumerated until an incident forces it. ## Why nothing detects it The usual change-detection tooling watches *your* files. A tag repoint touches nothing you own: no commit, no pull request, no deployment diff, no configuration change. From the outside the system looks completely stable. Worse, the swap does not need a deployment to take effect - a pod restart, a scale-out event, a node replacement or an eviction is enough, because each of those triggers a pull. The change can therefore land at an arbitrary time long after the push, which also makes it hard to correlate with anything. ## What the fix looks like The rule is simple: **the reference that is actually pulled must carry the digest**. Practically that means: - The deployment configuration in source control names `payments@sha256:...`, not a tag. The approved digest and the deployed digest are then the same string, diffable in review. - A tag may still exist for humans, for release notes and for tooling - it just must not be the thing the runtime resolves. - Anything that resolves a tag on the way to deployment must persist the digest it resolved, not throw it away. Two supporting controls make this durable rather than a convention. First, restrict who can push to release repositories so the set of identities able to move a tag is small and audited. Second, where the registry supports it, forbid re-aiming existing tags, so an overwrite is rejected at the source. ## What the pin still does not give you Be precise about the scope of the guarantee, because overclaiming here is a common interview failure. A digest pin says *these exact bytes*. It says nothing about whether those bytes are good: a reviewed-and-approved image can still be vulnerable, backdoored by whoever built it, or built from source nobody looked at. A digest is an integrity claim about identity, not a quality claim and not a statement about origin. It closes exactly one hole - substitution after approval - and that is the hole this question is about.

  • Does recording the digest in the change ticket give you any protection?
    It is evidence, not a control. Nothing reads that ticket at pull time, so it prevents nothing. It becomes useful only after the fact, and only if you also capture the digest that actually ran - then you can prove approved and running differ. Treat it as detective input, never as the pin.
  • Who realistically has the ability to move that tag?
    Everyone holding push rights to the repository: release engineers, other teams sharing it, every CI job with a push token, unrotated service accounts and registry admins. That set is usually far wider than the reviewer list, and enumerating it is normally the first uncomfortable step in fixing this.
  • Does the swap need a redeploy to take effect?
    No, and that is what makes it quiet. Any pull is enough - a restart, an eviction, a scale-out, a replaced node. The change can therefore surface hours after the push, on a subset of instances, with no human action in between and nothing in your change log to correlate against.

saying these in an interview costs you the question

  • Says the tag is safe because only CI can push
  • Thinks a digest in the ticket prevents the swap
  • Believes a redeploy is required for the swap to take effect
  • Confuses the tag with the content it points at
  • Claims a build-time scan covers what runs later

context