Skip to main content

Artifacts, registries & supply-chain security

The pipeline's artifact stage (lesson 5.1) produces the one thing that actually travels to every environment — so what it is, how it's named, and how you trust it determine whether your deploys are reproducible and safe. This lesson covers two tightly linked ideas: artifact immutability (build once, identify precisely) and supply-chain security (prove what's inside the artifact and that you built it). The second used to be optional; it is now an enterprise and regulatory requirement.

What an artifact is, and why "build once" is law

An artifact is the built, versioned output of a pipeline — the deployable thing. For a containerized app it's a container image; it could also be a .jar, a compiled binary, or an npm package. You met images and registries in Chapter 4; here we add the discipline around them.

The single most important rule, foreshadowed twice already: build the artifact once, then promote that exact artifact through every environment. If you rebuild for staging and rebuild again for production, you have never deployed the thing you tested — different build times, dependency versions, or base images can sneak in differences. One build, one artifact, promoted unchanged from dev to staging to prod. This is the build-vs-deploy distinction: building happens once in CI; deploying is just moving that artifact, never remaking it.

How the image actually gets built: BuildKit and Buildpacks

Before an artifact can be versioned and promoted, it has to be built — and how you build a container image has matured well beyond the old docker build of a hand-written Dockerfile. Two ideas dominate modern image builds:

  • BuildKit is the modern build engine underneath today's docker build (and used standalone via buildx). It builds images that are efficient, cache-aware, and more reproducible: it understands the dependency graph between build steps so independent steps run in parallel, it caches layers intelligently (and can share that cache across machines in CI — the pipeline build cache from lesson 5.1, applied to images), and it handles secrets and multi-platform builds cleanly. If your pipeline builds container images, BuildKit is what makes those builds fast and repeatable; it's a drop-in upgrade from the legacy builder.
  • Cloud Native Buildpacks go one step further and build an image without a Dockerfile at all. You point a buildpack at your source code; it detects the language and framework, pulls in the right runtime and dependencies, and produces a well-formed, secure-by-default image — no Dockerfile to write or maintain. The big operational win is rebase: when a base-image security patch lands, buildpacks can swap the OS layer underneath thousands of app images without rebuilding the app, so org-wide CVE patching becomes a fast, uniform operation instead of N separate rebuilds. Heroku and Paketo are common implementations; the durable idea is the platform owns image-building as a golden path, so developers ship source and get a consistent, patchable image.

:::note Which to reach for BuildKit is for teams that want to keep writing Dockerfiles but build them fast, cached, and reproducibly — it's the default build engine. Buildpacks are for platforms that want to remove the Dockerfile from the developer's plate entirely and own image standards centrally (a Chapter 7 golden-path move). Both produce ordinary OCI images that flow through the rest of this lesson — versioned, signed, and promoted — unchanged. :::

Mutable tags vs immutable digests

Images are named name:tag (Chapter 4), and the tag is usually a version. But there's a sharper, more reliable way to refer to an exact image: its digest.

  • A tag (like :1.4.0 or :latest) is a human-friendly label that is mutable — someone can re-push and make the same tag point at a different image. :latest is the worst offender; it moves to whatever was pushed last.
  • A digest is a content-addressable identifier: a cryptographic hash (e.g. sha256:9b2f…) computed from the image's exact bytes. Change one byte and the digest changes. A digest therefore refers to one specific, unchangeable image, forever — it's immutable by construction.
Tag my-app:1.4.0\n(mutable label —\ncan beDigest my-app@sha256:9b2f…\n(hash of the bytesImgA

The durable rule: tag for humans, but deploy by digest. Use :1.4.0 for readability, but have your deploy pin the digest (my-app@sha256:9b2f…) so what runs is byte-for-byte the audited artifact. Deploying mutable tags causes two classic failures: non-reproducible deploys (two clusters pulling :latest get different images) and cache poisoning (a re-pushed tag silently changes what's cached on nodes). Digests eliminate both.

:::note Semantic versioning, briefly Human-readable versions usually follow semantic versioning (SemVer): MAJOR.MINOR.PATCH (e.g. 2.4.1). Bump PATCH for backward-compatible fixes, MINOR for backward-compatible features, MAJOR for breaking changes. SemVer communicates intent to consumers; the digest guarantees identity. You want both: a SemVer tag people can reason about, pinned to a digest a machine can verify. :::

Registries

A registry is where artifacts live and travel between machines (Chapter 4). For containers you'll meet cloud-native ones (ECR, Artifact Registry, ACR) and platform-neutral ones like Harbor (a popular open-source registry that adds scanning and signing). For other artifact types — Java libraries, npm packages, OS packages — general-purpose artifact repositories like JFrog Artifactory and Sonatype Nexus play the same role: a trusted, versioned store you push to once and pull from everywhere.

The software supply chain: prove what's inside and who built it

A modern app is mostly other people's code — dozens or hundreds of open-source dependencies, pulled transitively. That dependency tree is your software supply chain, and it's a prime attack target: compromise one popular library and you compromise everyone who depends on it. After several high-profile incidents, proving the integrity of the supply chain became a hard requirement in enterprise and government (e.g. US executive orders mandating it). Skipping it is no longer acceptable. Four pieces close the gap:

Build artifactSBOM\nlisteverything insideSign\nprove it'sauthenticProvenance\nattesthow/where built
  • SBOM (Software Bill of Materials). A complete, machine-readable inventory of everything in the artifact — every library and version. When the next critical vulnerability drops, an SBOM lets you instantly answer "are we affected?" Tools: Syft generates SBOMs; Grype and Trivy scan them (and images) for known vulnerabilities. (Trivy also scans directly in the pipeline's scan stage.)
  • Signing. Cryptographically sign the artifact so anyone can verify it's authentic and untampered — that it really came from your pipeline. Sigstore/Cosign is the standard, with keyless signing tied to your CI identity so there's no long-lived signing key to steal.
  • Provenance / attestation. A signed statement of how and where the artifact was built — which source commit, which builder, which steps. An attestation is that signed metadata; the in-toto framework and the SLSA GitHub generator produce it, and GitHub artifact attestations offer it natively. Provenance lets a deploy gate refuse anything not built by your trusted pipeline.
  • Verify at deploy. None of the above helps unless you check it. The deploy step (or an admission policy in the cluster) verifies the signature and provenance before allowing the artifact to run.

:::tip SLSA: a ladder of supply-chain assurance SLSA ("salsa," Supply-chain Levels for Software Artifacts) is a framework that grades how trustworthy your build process is, as levels:

  • L1 — provenance exists: the build documents how it was made.
  • L2 — provenance is signed and the build runs on a hosted, tamper-resistant service (not someone's laptop).
  • L3 — the build is hardened and isolated, with strong guarantees that provenance can't be forged. Higher levels = stronger guarantees that the artifact is what it claims to be. You don't need L3 on day one; the point is a ladder you climb deliberately, and knowing which rung you're on. :::

:::tip Durable vs dated Immutability, content-addressable digests, SBOMs, signing, provenance, and the SLSA ladder are durable — they're principles of trust and reproducibility. The specific tools (Cosign, Syft, Grype, Trivy, Harbor, Artifactory, Nexus) are dated and will be replaced; map each onto its principle (sign / inventory / scan / store) and swapping tools is trivial. :::

Common pitfalls

  • Deploying mutable tags (especially :latest). Causes non-reproducible deploys and cache poisoning. Tag for humans; deploy by digest.
  • Rebuilding per environment. Breaks the "you deployed what you tested" guarantee. Build once, promote the same artifact.
  • No SBOM, signing, or provenance. The single biggest gap in most pipelines — and now a regulatory/enterprise requirement, not a nice-to-have. Treat supply-chain security as a first-class pipeline stage.
  • Generating attestations but never verifying them. Provenance you don't check at deploy protects no one. Add the verification gate.
  • Confusing SemVer with identity. A SemVer tag communicates intent but can be re-pointed; only the digest guarantees byte-for-byte identity.

Why it matters

The pipeline's artifact is the one thing that travels everywhere, so it must be built once and promoted unchanged (the build-vs-deploy distinction) and identified immutably: tag :1.4.0 for humans, but deploy by content-addressable digest (@sha256:…) so what runs is byte-for-byte what you tested — defeating non-reproducible deploys and cache poisoning. Around the artifact sits the now-mandatory supply chain: an SBOM inventories what's inside (Syft/Grype/Trivy), signing proves it's authentic (Sigstore/Cosign), provenance/attestation proves how and where it was built (in-toto, SLSA, GitHub attestations), and the SLSA levels (L1–L3) grade how much you can trust the build — all verified at deploy. Get the artifact immutable and trustworthy, and promoting it across environments — next — becomes safe and boring.

Next: Environments & promotion (build once, promote) →