Prompt and context
An artifact repository uses hash digests as object addresses. Explain the benefits and boundaries of content addressing, then migrate to a new hash algorithm without breaking clients, caches, or signatures.
OCI content descriptors use a digest as a content identifier and recommend verifying untrusted content before consumption. Git’s hash transition documentation shows a repository-by-repository migration pattern. The interview tests integrity, identity, availability, and compatibility separately; “the digest matches” is not an absolute security proof.
What the interviewer is testing
The interviewer wants to see whether you understand a hash as an address, deduplication key, and verification value, can distinguish collision, second-preimage, preimage, and downgrade boundaries, and can design aliases, indexes, caches, signatures, garbage collection, and rollback. You should know when signatures or trusted distribution are required instead of relying on a digest alone.
Questions to clarify first
- Is the object a container layer, build artifact, backup, or arbitrary user file?
- Does the digest appear in APIs, URLs, databases, logs, signatures, or customer scripts?
- What are the algorithm, encoding, canonicalization, object-size, and collision rules?
- Can clients parse an algorithm prefix, and are there offline, old, or third-party mirrors?
- Is the goal to add an algorithm, replace the default, or retire a discouraged one?
- How long must old digests remain verifiable, and how will audit and signatures stay traceable?
A 30-second answer
“Content addressing uses a digest of canonical bytes as a stable ID, which helps deduplication, caching, and integrity checks, but it does not prove source, permission, or availability. I would put the algorithm and encoding into the digest format, keep an old-to-new index and readable aliases, and let new clients prefer the new algorithm while old clients keep reading old addresses. During migration I would dual-write or lazily compute new digests, sign the algorithm, digest, and context, and have every consumer verify size and digest again. Exit gates would cover hit rate, recomputation cost, client errors, signature validation, and rollback drills.”
Step-by-step deep answer
Step 1: Define stable content bytes
State whether the digest covers raw bytes or a canonical representation. Compression, line endings, JSON field order, and metadata changes produce different digests. If semantically equal but byte-different objects are needed, use a semantic version instead of hidden canonicalization that can distort signatures and audit.
Step 2: Separate digest, tag, and signature
A digest asks whether received bytes match an identifier; a tag asks which version a user wants; a signature asks who approved it in which context. Tags can move while digests should be immutable. A signature should cover algorithm, digest, media type, purpose, and time, not only a mutable tag.
Step 3: State the security boundaries
Collision, second-preimage, and preimage risks differ, and algorithm strength changes over time. Digest verification does not replace authentication, authorization, malware scanning, or availability. For untrusted content, check size and format before hashing to avoid expensive work on huge or malicious input.
Step 4: Design a dual-algorithm object model
Include an algorithm prefix and encoding in the digest and let the internal index map one object to multiple digests. Keep a primary object ID, old digest, new digest, size, media type, and creation time. Capability negotiation may choose the default digest, but a client must not silently treat an unknown algorithm as the old one.
Step 5: Plan the migration path
Teach readers the new format before writers emit new digests; an old digest can resolve to the same object through the index. Precompute hot objects and lazily compute cold ones, recording failures and queue state. New clients prefer the new digest; old clients use aliases or content negotiation. One address must not return different bytes.
Step 6: Handle caches, signatures, and supply chain
Cache keys, CDNs, image manifests, SBOMs, signatures, and audit events must carry the algorithm prefix. Signature validation checks digest, algorithm, context, and certificate trust. Dual signatures may be kept temporarily, but the release gate must name the required one. Pullers verify the digest before unpacking or executing an artifact.
Step 7: Control garbage collection and rollback
Collect an object only after old and new digests and all aliases have no references. Migration indexes, recomputation queues, and signature state must be recoverable. If the new implementation is faulty, pause new writes and return to the old default while keeping generated mappings. Rollback must not delete historical signatures still needed for verification.
Step 8: Prove completion with metrics
Monitor dual-digest coverage, read hit rate, recomputation throughput, size mismatches, unknown-algorithm errors, signature failures, cache hit rate, and rollbacks. Segment by client version and object type and set stop lines. Stop producing the old algorithm only after old traffic is below threshold and audit, signature, and third-party validation are complete.
Trade-offs and boundaries
Multiple digests per object
Multiple digests improve migration compatibility but add index, signature, and cache complexity. Treat digests as enumerable attributes, define the display default, and define the verification digest rather than overwriting one with another.
Precompute versus lazy computation
Precomputation reduces first-read latency but consumes CPU and storage bandwidth; lazy computation saves cold-data cost but can create tail latency. Tier by heat, size, and client deadlines and allow the queue to pause.
Digest verification versus source authentication
A digest verifies that bytes did not change; it does not prove publisher identity. A supply chain needs signatures, transparency logs, or trusted distribution, while authorization still controls who can read, push, or delete an object.
Failure drills and evolution plan
A client rejects the algorithm-prefixed digest
Provide a versioned API, alias, and compatibility field and measure rejection. Never truncate the new digest into an old format or make clients guess the algorithm.
Bytes change during recomputation
Freeze the input version and compare size, media type, and checksums to locate compression or canonicalization drift. The new digest must identify deterministic bytes; if semantics match but bytes differ, create a new object version.
A new digest signature fails validation
Check signature context, certificate chain, algorithm policy, and clock, then fall back by version. Keep old signature verification and never skip it to restore a release.
Common mistakes and follow-ups
Mistake 1: Treating a digest as access control
Follow-up: Can someone who knows the digest read the object? Distinguish unguessability, authentication, authorization, and encryption.
Mistake 2: Treating a tag as an immutable ID
Follow-up: What happens to caches and signatures when a tag moves or rolls back? Lock content with a digest and sign the context.
Mistake 3: Changing only a database field
Follow-up: How do APIs, manifests, CDNs, clients, signatures, logs, and garbage collection change together?
Mistake 4: Measuring only hash speed
Follow-up: How do you test size mismatch, unknown algorithms, tail latency, signature failure, and third-party compatibility?
Follow-up questions and responses
Why does OCI record object size as well?
Size lets a client reject obviously abnormal input before hashing and estimate download and resource use. It is not an integrity proof; the final bytes still need an independently calculated digest.
Can one URL represent two digests during migration?
One URL should stably return the same bytes and semantics. Use a logical alias that resolves to an immutable digest or return multiple explicit digest fields; do not randomly vary content by client.
When can you stop the old algorithm?
After new-client coverage, dual-digest mapping, signature validation, caches, third-party pulls, and audit metrics pass, and old-digest traffic is below the exit threshold, stop producing old digests first. After a verification window, revoke old writes while preserving historical reads and signature validation for their retention period.