CLASSROOM // HOMELAB ACADEMY M15 READING
M15 READINGreading

Homelab Academy / Modules

Instruction 03-image-version-pinning-and-controlled-updates: Reading

Learn: instruction, vocabulary, worked example.

Overview

Module: Compose Operations & IaC
Activity type: Reading (Learn)
Objective: Explain why a mutable tag is unsuitable as the final deployment identity.

Words

Vocabulary

Term Meaning
tag A human-friendly and generally mutable image reference such as stable or 1.4. A registry operator can move a tag to a different object.
channel An operational release stream, such as stable, that this lab maps to an image index. A channel is mutable and is not itself an immutable deployment identity.
image index A multi-platform object containing descriptors for one or more platform-specific image manifests. A client selects a descriptor matching its requested operating system and architecture.
platform manifest The manifest selected from an image index for one exact platform, such as linux/amd64. Its digest, rather than the channel name, becomes the deployment pin in this lab.
descriptor Metadata pointing to content by digest and, when applicable, identifying the operating system and architecture for which that content was built.
digest pin An immutable reference of the form repository@sha256:hexadecimal-value. The pin used here is the digest of the selected platform manifest.
out-of-band approval An expected channel, platform, and digest supplied independently of the registry catalog being evaluated. In production this may come from a reviewed release record, deployment controller, or signed policy system.
fail closed Refusing promotion when required input is missing, malformed, ambiguous, inconsistent, unapproved, or unverifiable.
audit linkage A record that explicitly connects the digest deployed before an operation to the digest deployed after it.
Instruction

Instruction

Container tags are convenient names, but they are usually mutable pointers. If a deployment records only academy/demo:stable, the bytes selected tomorrow may differ from the bytes selected today even though the text of the deployment reference has not changed. Digest pinning changes the final identity to a content-addressed reference such as academy/demo@sha256:ba7816bf..., making an unnoticed tag move insufficient to alter the deployed identity.

Multi-platform images add an important distinction. A channel or tag commonly resolves to an OCI image index. The index is not the same object as the image manifest used by a linux/amd64 node. The index contains descriptors for multiple platforms, and the client selects one matching the requested operating system and architecture. A policy intended to approve the runnable linux/amd64 artifact must therefore compare the digest of the selected linux/amd64 manifest, not merely a tag and not an unrelated platform descriptor. The lab registry models this explicitly: stable points to index-v2, index-v2 points to linux/amd64 and linux/arm64 manifests, and the deployment pin uses the selected linux/amd64 manifest digest.

Content hashing and authorization answer different questions. Recomputing a catalog-provided digest can detect accidental corruption when the declared digest and bytes no longer agree, but a party able to replace both the content and the digest can create a new self-consistent pair. A local policy file stored beside the catalog also does not solve that boundary if the same party can edit both files. For that reason, update.py requires an expected channel, platform, and digest supplied independently at invocation time. It checks the requested tuple, resolves the catalog index, selects exactly one matching platform descriptor, verifies the selected blob against the descriptor, compares the selected digest with the out-of-band expected digest, and then confirms local policy approval. Any mismatch is rejected before deployment, backup, or audit state is written.

The lab uses the published SHA-256 test vectors for the exact bytes abc, hello, and the empty byte string. Their literal golden values are included in the lesson and verification commands. This avoids relying solely on values generated by the setup code or by update.py. The dry-run and rejection tests also compare complete deployment and audit files before and after each attempt. A successful promotion creates a retained backup, atomically replaces deployment.json, and appends an audit event linking the previous digest to the new digest. Rollback copies the failed deployment aside, validates the retained backup against both an out-of-band rollback digest and local approval, copies rather than moves the backup into place, verifies the restored state, and only then appends the rollback event.

Map

Architecture

scope

All generated and mutated files are confined to /opt/lab-classroom/class81/.

flow

The stable channel resolves to index-v2 in registry.json.
index-v2 contains separate linux/amd64 and linux/arm64 descriptors.
The requested linux/amd64 platform selects the descriptor whose manifest blob is the exact byte sequence abc.
The selected descriptor digest is compared with the independently supplied expected digest.
The selected tuple is checked against policy.json.
The deployment is written as registry.lab/academy/demo@sha256:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad.
A successful update retains deployment.backup.json and appends an audit record with from_digest and to_digest.

trust_boundaries

registry.json and its blobs represent registry-controlled data and are not trusted merely because they agree with one another.
policy.json represents local authorization but is deliberately tested as mutable within the same lab boundary.
The command-line expected channel, platform, and digest model independently reviewed release approval.
The lesson's literal golden digest values are independently published expectations and are not generated by setup.py or update.py.

golden_digests

previous_manifest_exact_bytes

hello

previous_manifest_sha256

sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

candidate_amd64_manifest_exact_bytes

abc

candidate_amd64_manifest_sha256

sha256:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad

candidate_arm64_manifest_exact_bytes

candidate_arm64_manifest_sha256

sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

tampered_manifest_exact_bytes

test

tampered_manifest_sha256

sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

Learn

Required reading

  • OCI Image Specification, Image Index: https://github.com/opencontainers/image-spec/blob/main/image-index.md
  • OCI Image Specification, Manifest: https://github.com/opencontainers/image-spec/blob/main/manifest.md
  • OCI Image Specification, Descriptor: https://github.com/opencontainers/image-spec/blob/main/descriptor.md
  • Docker documentation, image digests: https://docs.docker.com/dhi/core-concepts/digests/
  • NIST Secure Software Development Framework SP 800-218: https://csrc.nist.gov/publications/detail/sp/800-218/final
Learn

References

  • Open Container Initiative Image Index specification: https://github.com/opencontainers/image-spec/blob/main/image-index.md
  • Open Container Initiative Image Manifest specification: https://github.com/opencontainers/image-spec/blob/main/manifest.md
  • Open Container Initiative Descriptor specification: https://github.com/opencontainers/image-spec/blob/main/descriptor.md
  • Open Container Initiative Image Layout specification: https://github.com/opencontainers/image-spec/blob/main/image-layout.md
  • Docker documentation on image digests: https://docs.docker.com/dhi/core-concepts/digests/
  • NIST FIPS 180-4, Secure Hash Standard: https://csrc.nist.gov/pubs/fips/180-4/upd1/final
  • NIST SP 800-218, Secure Software Development Framework: https://csrc.nist.gov/publications/detail/sp/800-218/final
  • SLSA supply-chain security framework: https://slsa.dev/spec/
← Module hubLesson →