skip to content

How do you make an approved-base-image rule match when each tool names the image differently?

level: seniorimportance: should knowfreq 44%

answer

  1. one canonical key, not three
  2. tags move, digests do not
  3. resolve when the evidence is made
  4. an index digest is not a manifest digest
  5. unresolvable reference means unknown

basics

~20 s

Join on the image digest. A tag is a mutable pointer and a package URL is a naming convention, so resolve every report's reference to a digest when the evidence is produced, and treat an unresolvable reference as unknown rather than approved.

solid answer

~50 s

The rule sounds trivial — is this workload's base image in the approved inventory — and it fails on identity, not on logic. The registry scan report may name the image by tag, the inventory may key it by digest, and an inventory or SBOM record may carry a package URL string with a name, a version and qualifiers. Compared as strings, those either match nothing or match the wrong thing. Pick one canonical key and make it the digest, because a digest is content-addressed and immutable while a tag is a pointer that can be moved tomorrow — approving a tag approves whatever it points at next week. So identity is resolved to a digest at the moment the evidence is produced, when the pipeline still knows exactly what it pushed, and the rule compares digests only. A reference that cannot be resolved is unknown, and unknown is not approved.

go deeper

for a junior

Know that one container image can be referred to by a tag, by a digest, or by a package-URL string, and that only the digest names a specific set of bytes.

for a middle

Explain why a join across two tools' records needs one canonical key, and what goes wrong when that key is present in some records and absent in others.

for a senior

Show where you resolve identity — when the evidence is produced, not at the gate — and handle the multi-platform case where the index digest and the per-platform manifest digest are both correct and differ.

for a principal

Own the decision that the approved inventory is keyed on digests with tags as aliases, and be able to explain what that costs teams who think, deploy and talk in tags.

## Three names for one image The same container image legitimately appears in your evidence under at least three forms: - a **tag** — a registry host, a repository path and a human label, resolved to an image by the registry at the moment of use; - a **digest** — a content hash over the image manifest, which names exactly one set of bytes; - a **package URL string** — a structured identifier carrying the name and a version or digest plus qualifiers such as the repository, produced by inventory and SBOM tooling. They are all correct. They are not comparable. A rule that string-compares whatever field it happens to find will either match nothing or match by accident. ## Why the digest is the join key A tag is a pointer, and pointers move. An approval recorded against a tag is an approval of whatever that tag names today, which silently transfers to every image published under it afterwards — the review happened on bytes that may no longer be there. A digest is derived from content, so an approval recorded against a digest means exactly what it meant when it was granted. Key the inventory on digests; keep tags as human-facing aliases, ideally with the window in which each tag pointed at each digest. This is a question about how the *join* is keyed. Whether deployments must themselves reference images immutably is a separate rule with a separate owner. ## Resolve at production time, not at gate time The tempting shortcut is to let the gate resolve the tag when it evaluates. That answers *what does this tag mean now*, which is not the question. Between the scan and the gate the tag can be moved, so you would be comparing a freshly resolved digest against a report describing a different image, and the comparison would succeed. Resolve once, at the moment the evidence is produced, by the component that knows the answer with certainty: the pipeline knows the digest it pushed, the runtime knows the digest it pulled. Carry that digest through every downstream record. ## Two traps that look like bugs and are not **Default host and namespace expansion.** The same image can be written with or without a default registry host and a default namespace. Two spellings, one image, and byte-for-byte they differ. Whatever canonical form you choose, apply it in the normaliser, not in each rule. **An index digest is not a manifest digest.** A multi-platform image is published as an index that references one manifest per platform, each with its own digest. A tool that scanned the index records the index digest; a node that pulled the linux/amd64 variant records that manifest's digest. Both records are accurate and they will never compare equal. Decide which one your inventory is keyed on, normalise to it consistently, or store both and match on either. ## Base image versus the artifact under test The artifact being admitted is your built image; the thing the rule cares about is what it was built *from*. That relationship is not recoverable from the artifact's own name — it comes from build metadata or an inventory record that captured it at build time. A rule that infers a base image from a tag naming convention is reading a comment, not a fact. ## What happens when the key is missing This is the failure worth rehearsing, because it is silent. If the rule keys on a digest field and half your reports carry only tags, then for those artifacts the comparison has nothing to work with: the rule produces no result, no denial is emitted, and the artifact is admitted unexamined. The gate looks like it is running and blocking nothing because everything is compliant. The defence is the same discipline as any other missing evidence — assert that the identity resolved before comparing it, and route unresolvable identity to unknown with a message naming the reference that could not be resolved. The opposite failure is worse: a normaliser that helpfully fills a missing digest by resolving the tag itself. Now the record is confident, wrong, and indistinguishable from a good one. ## What the inventory should hold Keyed by digest. Tags recorded as aliases with the period they were valid. Enough provenance that a human can see which image was reviewed. And a clear answer to what happens to a workload already running an image whose approval was later withdrawn — because that is a different decision from admitting a new one, and the inventory record is what makes it answerable.

  • Why not just resolve the tag to a digest at gate time?
    Because that answers what the tag points at now, not what the scanner examined. Between scan and gate the tag can be moved, so you would compare a freshly resolved digest against a report about a different image and get a confident match. Resolve once, where the answer is certain, and carry the digest downstream.
  • A scanner reports one digest and the cluster pulled another, and both are correct — how?
    A multi-platform image is published as an index that references one manifest per platform, each with its own digest. A tool that scanned the index records the index digest; a node that pulled the amd64 variant records that manifest's digest. Normalise consistently to one of them, or store both and match on either.
  • What does an inventory keyed by tag actually approve?
    Whatever that tag names today. Tags are mutable pointers, so the approval silently extends to every image later published under the same tag, none of which was reviewed. Key on digests and keep tags as aliases, with a record of when each tag pointed where.

A tag is the name plate on an office door; a digest is a fingerprint of the person inside. Approving the name plate approves whoever moves in next.

saying these in an interview costs you the question

  • Compares image reference strings without canonicalising them
  • Treats a tag as a stable identifier for an image
  • Re-resolves the tag at gate time and compares that
  • Fills a missing digest with a value resolved later
  • Assumes one image has exactly one digest
  • Infers the base image from a tag naming convention

context