Cyber Security • Cloud and Modern Infrastructure Security

Image Provenance & Dependencies — Explain image provenance and dependency risk conceptually

Understanding where container images originate and why every dependency layer is an attack surface.

A protected digital shield with binary code and a secure lock for cyber security
Inside this lesson 10 sections 5 questions 8 figures

SECTION 1

Historical Context & Motivation

The rise of containerization fundamentally transformed how software is packaged and deployed. Before containers, server provisioning was a manual, imperative process—operators installed libraries, configured runtimes, and hoped that what ran in staging would behave identically in production. When Docker popularized the concept of immutable, layered container images in 2013, it solved the 'works on my machine' problem but simultaneously introduced a new class of security challenges: how do you trust the provenance of an image you did not build yourself, and how do you reason about the transitive risk carried by every dependency layer baked into it?

The concept of software provenance—tracing the origin and chain of custody of a software artifact—has roots in traditional supply-chain management and digital forensics. In the physical world, provenance tracking ensures a pharmaceutical tablet can be traced back through every warehouse and manufacturer to its raw chemical suppliers. In software, the same principle requires that every binary, library, and configuration file within a container image can be traced back to its source code, build system, and signing authority. As organizations began pulling millions of images from public registries like Docker Hub, the absence of robust provenance guarantees became a critical vulnerability.

2013 • Docker Goes Public

Docker open-sources its container runtime, popularizing image-based deployments and the concept of layered, immutable filesystem snapshots pulled from centralized registries.

2017 • Typosquatting Hits Registries

Researchers demonstrate widespread typosquatting on npm, PyPI, and Docker Hub—malicious packages mimicking popular names. The attack surface of dependency confusion becomes a mainstream security concern.

2020 • SolarWinds Supply-Chain Attack

A nation-state actor compromises the SolarWinds Orion build pipeline, injecting a backdoor into signed updates distributed to ~18,000 organizations. The attack crystallizes awareness of build-provenance risks.

2021 • Executive Order 14028 & SBOMs

The U.S. Executive Order on Improving the Nation's Cybersecurity mandates Software Bills of Materials (SBOMs) for government suppliers, formalizing provenance and dependency transparency at a policy level.

2023 • SLSA v1.0 and Sigstore Maturity

The Supply-chain Levels for Software Artifacts (SLSA) framework reaches v1.0, and Sigstore's keyless signing becomes broadly adopted, providing practical tooling for verifiable image provenance.

These events reveal a recurring pattern: the software industry repeatedly extends trust to artifacts whose origins are opaque. The central question this lesson addresses is straightforward but profound—when you run a container image, how do you know it is what it claims to be, and how do you account for the security posture of every dependency it contains?

SECTION 2

Core Principles & Definitions

Before diving into mechanisms and tools, it is essential to establish precise definitions for the foundational concepts that underpin image security. An image in this context refers to a container image—an ordered collection of filesystem layers plus metadata that, when instantiated by a container runtime, yields an isolated process. Provenance refers to the verifiable record of an artifact's origin, including who built it, when, from which source code, and using which build system. Dependency risk captures the aggregate exposure introduced by every library, binary, and base-image layer that an image transitively includes.

1

Image Provenance

The authenticated chain of custody for a container image—from source code commit through CI/CD build to registry publication—verified through cryptographic signatures and attestations.
2

Dependency Graph

The directed acyclic graph (DAG) of all software components an image requires, including the base OS layer, system libraries, language runtimes, and application-level packages.
3

Software Bill of Materials (SBOM)

A machine-readable inventory (typically in SPDX or CycloneDX format) enumerating every component, version, and license within an artifact—enabling automated vulnerability correlation.
4

Transitive Trust

When you trust image A, you implicitly trust every layer and package A depends on. A single compromised transitive dependency can undermine the entire image's integrity.
5

Attestation & Signing

Cryptographic mechanisms (e.g., Sigstore cosign, Notary v2) that bind a signature or provenance statement to a specific image digest, enabling consumers to verify authenticity before deployment.
✦

KEY TAKEAWAY

Think of a container image like a recipe passed through many kitchens. Provenance answers 'who wrote this recipe and can I trust them?' while dependency risk answers 'are all the ingredients safe?' Just as a single contaminated ingredient can ruin an entire dish regardless of the chef's skill, a single compromised dependency can undermine an otherwise well-secured image.

SECTION 3

Visual Explanation — Image Layer Architecture

A container image is built from discrete layers, each corresponding to a directive in a Dockerfile (or equivalent build specification). The bottommost layer is typically a base image—a minimal operating-system distribution such as Alpine, Debian, or Ubuntu—upon which application-specific layers are stacked. Each layer may introduce hundreds of packages, and each package carries its own dependency tree. The following diagram illustrates this layered architecture and highlights the provenance and dependency boundaries at each level.

Container Image Layer Stack & Provenance ChainLayer 5: Application CodeCOPY app/ • your sourceLayer 4: App Dependenciespip install / npm install • 3rd-party libsLayer 3: Language RuntimePython 3.12 / Node 20 • interpreter + stdlibLayer 2: System Librariesglibc, openssl, zlib • OS packagesLayer 1: Base Image (OS)alpine:3.19 / debian:bookworm-slimProvenanceYou control ✓Upstream pkgmaintainersLang communityOS vendorBase imagepublisher⚠ Risk propagation: a CVE in Layer 1 or 2 affects ALL layers above it — transitive dependency risk flows upward.
Each layer inherits everything below it. The topmost layer (your application code) is the only layer whose provenance you fully control. Every layer beneath it represents delegated trust to an external maintainer—the language community, the OS vendor, and the base image publisher. A vulnerability at any lower layer propagates upward through all dependent layers.

Notice that Layer 4 (application dependencies) is often the most voluminous and the least scrutinized. A typical Python web application may declare 15 direct dependencies in requirements.txt, but after transitive resolution those 15 may expand to over 150 packages. Each of those packages has its own maintainer, build pipeline, and potential for compromise. This exponential expansion of the trust boundary is the core of dependency risk.

SECTION 4

How Provenance Verification Works

While image provenance is primarily a trust-and-verification problem rather than a mathematical one, the underlying mechanisms rely on cryptographic primitives that can be expressed formally. The core operation is binding a content-addressable digest (a cryptographic hash of the image manifest and layers) to a provenance attestation signed by the builder's identity.

Content-Addressable Image Identification

IMAGE DIGEST

D(I)=SHA−256(manifest(I))D(I) = SHA-256( manifest(I) )

Where D(I) is the unique digest of image I, computed as the SHA-256 hash of the image manifest—a JSON document listing every layer digest. Any bit change in any layer yields a completely different D(I).

SIGNATURE VERIFICATION

Verify(pubKeybuilder,σ,D(I))→true,falseVerify(pubKey_builder, σ, D(I)) → {true, false}

A provenance signature σ produced by the builder's private key is validated against their public key pubKey_builder and the image digest. A 'true' result means the image has not been tampered with since signing and was produced by the claimed identity.

Quantifying Dependency Risk

Though not a single canonical formula exists, security teams commonly reason about dependency risk using a model that accounts for both the breadth and depth of the dependency graph. Consider an image I whose dependency graph contains n packages. If each package has an independent probability p of containing a critical vulnerability, the probability that the image is free of any critical vulnerability across all dependencies is:

AGGREGATE VULNERABILITY PROBABILITY

P(atleastoneCVE)=1−(1−p)nP(at least one CVE) = 1 − (1 − p)ⁿ

Where p is the per-package probability of a critical vulnerability and n is the total number of transitive dependencies. Even with a modest p = 0.01, at n = 200 dependencies, P ≈ 1 − 0.99²⁰⁰ ≈ 0.866—an 86.6% probability of at least one critical CVE.

💡

Why Minimizing Dependencies Matters

The equation above illustrates why distroless and scratch-based images are favored in production. By reducing n from hundreds to dozens, the aggregate probability of harboring a vulnerability drops dramatically. This is the mathematical justification for the principle of minimal images.

SECTION 5

Classifying Dependency Risks

Not all dependency risks are created equal. A mature security posture requires distinguishing between different categories of risk based on where the dependency originates, how it enters the image, and the blast radius of its compromise. The following classification framework organizes the primary dependency risk vectors encountered in modern container environments.

Dependency Risk TaxonomyContainer Image RiskBase Image RisksPackage-Level RisksBuild Pipeline RisksUnverified PublisherNo signature onbase image digestStale / EOL OSUnpatched CVEs inbase packagesTyposquattingMalicious namemimicsDep ConfusionPrivate namehijackedKnown CVEsUnpatched libraryvulnerabilitiesCompromised CIInjected steps inbuild pipelineTag MutabilityMutable tags overwrittenwith malicious contentBlast Radius: any risk materializing at a lower layer affects ALL images built upon itMitigation: verify provenance + scan SBOMs + pin digests + use minimal base images
This taxonomy organizes container dependency risks into three pillars: base image risks (unverified publishers, stale OS), package-level risks (typosquatting, dependency confusion, known CVEs), and build pipeline risks (compromised CI, mutable tags). The bottom band emphasizes that risk at lower layers has maximal blast radius.
Risk CategoryExample AttackMitigation Strategy
Base Image — Unverified PublisherAttacker publishes a look-alike image (e.g., offiicial/nginx) on Docker Hub with a backdoor embedded in the entrypoint script.Use only Docker Official Images or Verified Publisher images; verify signatures with cosign verify.
Package — Dependency ConfusionAttacker registers a public package with the same name as a private internal package; the package manager resolves the public (malicious) version due to higher version number.Scope packages to private registries; configure package managers to use --index-url pointing to internal artifact store.
Build Pipeline — Compromised CIAttacker gains write access to CI configuration (e.g., .github/workflows) and injects a step that exfiltrates secrets or modifies the built image.Require code review on CI config changes; use ephemeral, hardened build environments; adopt SLSA Build Level 3 with hermetic builds.
Registry — Tag MutabilityAttacker (or careless maintainer) overwrites the :latest tag to point to a different, possibly compromised image digest.Always pin images by sha256 digest rather than mutable tags; enable immutable tags in your registry configuration.

Common dependency risk vectors with real-world attack examples and mitigation strategies

SECTION 6

Worked Example — Auditing a Dockerfile

Consider a team deploying a Python Flask application. Their initial Dockerfile uses broad, mutable references and pulls from an unverified base. We will walk through the process of identifying provenance and dependency risks, then remediating them step by step.

Securing a Python Flask Dockerfile

  1. 1

    Step 1 — Identify the Base Image Risk

    The original Dockerfile begins with FROM python:3.11. This tag is mutable—it can be re-pushed at any time—and resolves to a full Debian image containing over 400 system packages. The provenance of this image depends entirely on trusting Docker Hub's 'Official Images' pipeline, and the bloated base dramatically increases the attack surface.
    Risk: mutable tag + large attack surface (~400 system packages)
  2. 2

    Step 2 — Pin the Base Image by Digest

    Replace the mutable tag with a digest-pinned reference: FROM python:3.11-slim@sha256:a1b2c3d4.... The -slim variant reduces the base from ~400 packages to ~100, and the digest pin ensures that every build uses the exact same filesystem layers. Even if the tag is overwritten upstream, the digest reference remains immutable.
    Remediation: digest pin eliminates tag mutability risk; slim variant reduces n by ~75%
  3. 3

    Step 3 — Generate and Inspect the SBOM

    Run syft packages myapp:latest -o spdx-json > sbom.json to generate a Software Bill of Materials. Then feed it into a vulnerability scanner: grype sbom:sbom.json. Suppose the scanner reports 3 critical CVEs in libexpat (a transitive system dependency) and 1 high-severity CVE in Jinja2 (a direct Python dependency). The SBOM made these transitive risks visible.
    Discovery: 3 critical + 1 high CVEs identified across 187 total packages
  4. 4

    Step 4 — Remediate and Lock Dependencies

    Update Jinja2 to the patched version in requirements.txt and use pip-compile to generate a fully pinned lockfile with hashes (--generate-hashes). For the libexpat CVEs, update the base image to a newer digest where the OS vendor has backported patches. Rebuild and re-scan to confirm zero critical or high findings.
    Final state: 0 critical/high CVEs, all dependencies pinned with hashes, base image digest-locked
  5. 5

    Step 5 — Sign and Attest the Final Image

    Use cosign sign --key cosign.key myregistry.io/myapp@sha256:... to attach a cryptographic signature. Then attach the SBOM and a SLSA provenance attestation: cosign attest --predicate sbom.json --type spdxjson. Downstream consumers and admission controllers (e.g., Kyverno, OPA Gatekeeper) can now verify both the image's integrity and its dependency inventory before allowing deployment.
    Provenance established: image is signed, SBOM attached, and verifiable by admission policy

SECTION 7

Tool Comparison & Tradeoffs

Multiple tools and frameworks address image provenance and dependency risk, but each makes different tradeoffs in terms of complexity, ecosystem coverage, and the guarantees they provide. Understanding these tradeoffs is essential for selecting the right toolchain for a given organizational context.

Tool / FrameworkPrimary FunctionStrengthsLimitations
Sigstore / cosignKeyless signing and verification of container images using ephemeral certificates from Fulcio and transparency log RekorNo long-lived key management; integrates with OIDC identity providers; transparency log enables auditabilityDepends on public Sigstore infrastructure; keyless mode requires trust in Fulcio CA; still maturing for air-gapped environments
SLSA FrameworkGraduated build-integrity requirements (Levels 1–4) for software artifacts, emphasizing build provenance attestationsVendor-neutral; prescriptive maturity model; well-defined threat model per levelAchieving Level 3+ requires significant CI/CD retooling; does not cover runtime behavior or dependency quality
Syft + GrypeSBOM generation (Syft) and vulnerability scanning against SBOM inventories (Grype) from AnchoreSupports many package ecosystems; fast CLI operation; output in SPDX and CycloneDX formatsScanner accuracy depends on vulnerability database freshness; cannot detect zero-day or logic bugs
Docker Scout / TrivyIntegrated image scanning providing CVE reports, SBOM generation, and policy-based recommendationsDeep integration with Docker/registry ecosystems; actionable remediation advice; supports VEX documentsDocker Scout has commercial tiers; Trivy's breadth can produce noisy results requiring triage effort
Notary v2 (ORAS)OCI-native artifact signing using the ORAS (OCI Registry As Storage) specificationFirst-class OCI support; works with any OCI-compliant registry; supports multiple signature typesNewer ecosystem with less adoption than Sigstore; requires PKI infrastructure or trust policy configuration

Comparison of leading image provenance and dependency risk tools

✦

KEY TAKEAWAY

No single tool solves the entire problem. Signing tools (cosign, Notary) answer 'who built this?'; SBOM tools (Syft) answer 'what is inside it?'; scanners (Grype, Trivy) answer 'is what is inside it safe?'; and frameworks (SLSA) answer 'was the build process itself trustworthy?' A defense-in-depth strategy composes all four categories together.

SECTION 8

Connection to Advanced Supply-Chain Security

Image provenance and dependency risk management are foundational layers within the broader discipline of software supply-chain security. The concepts introduced in this lesson—content-addressable digests, cryptographic attestations, SBOMs, and dependency graph analysis—serve as building blocks for more advanced techniques that are increasingly relevant in production cloud-native environments.

This Lesson (Foundational)Advanced Extension
Pin images by SHA-256 digestAdmission controllers (Kyverno, OPA Gatekeeper) that enforce signature and attestation verification at deployment time, rejecting any unsigned image
Generate and scan SBOMsContinuous SBOM lifecycle management with VEX (Vulnerability Exploitability eXchange) documents to track exploitability context and suppress false positives
SLSA Build Level 1–2 (provenance metadata)SLSA Build Level 3–4 with hermetic, reproducible builds; hardware-rooted attestation from Trusted Platform Modules (TPMs)
Vulnerability scanning at build timeRuntime dependency monitoring: eBPF-based tools that observe which libraries a container actually loads at runtime, narrowing the effective attack surface beyond static analysis
Manual dependency reviewAutomated dependency update bots (Dependabot, Renovate) combined with policy-as-code gates that enforce dependency freshness, license compliance, and provenance requirements

How foundational provenance concepts extend into advanced supply-chain security practices

The trajectory of the field is toward continuous, automated, policy-enforced provenance verification at every stage of the software delivery lifecycle—from code commit through CI build to runtime. As the ecosystem matures, expect to see provenance verification becoming as fundamental to container orchestration as TLS is to network communication: invisible when it works correctly, but catastrophic when absent.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

Explain the difference between image provenance and dependency risk. Why is it possible for an image to have strong provenance guarantees yet still carry significant dependency risk?
Show answer
Image provenance establishes who built the image, when, from which source, and using which build system—it verifies the chain of custody and integrity of the artifact. Dependency risk, by contrast, concerns the security posture of every software component included in the image. An image can have a perfectly verifiable provenance chain (signed by a trusted builder using SLSA Level 3 practices) yet still include a base image with unpatched CVEs or an application library with a known remote code execution vulnerability. Provenance answers 'can I trust the builder and that the image hasn't been tampered with?' while dependency risk asks 'are the contents themselves safe?' Both dimensions must be addressed for a secure deployment.

Question 2: BASIC CALCULATION

A container image has 120 transitive dependencies. Assume each dependency has an independent probability of p = 0.005 of containing a critical vulnerability. Using the formula P(at least one CVE) = 1 − (1 − p)ⁿ, calculate the probability that the image contains at least one critical vulnerability. Then recalculate for a minimal image with only 20 dependencies.
Show answer
For the full image with n = 120: P = 1 − (1 − 0.005)¹²⁰ = 1 − (0.995)¹²⁰. Computing (0.995)¹²⁰ = e120×ln(0.995)e^{120 × ln(0.995)} ≈ e120×(−0.005013)e^{120 × (−0.005013)} ≈ e−0.6015e^{−0.6015} ≈ 0.548. Therefore P ≈ 1 − 0.548 = 0.452, or about 45.2%. For the minimal image with n = 20: P = 1 − (0.995)²⁰ ≈ 1 − e−0.1003e^{−0.1003} ≈ 1 − 0.9046 ≈ 0.095, or about 9.5%. Reducing the dependency count from 120 to 20 cut the aggregate risk from ~45% to ~10%, demonstrating the powerful effect of minimizing dependencies even when per-package risk is modest.

Question 3: INTERMEDIATE

You discover that your organization's Dockerfiles reference base images using mutable tags (e.g., FROM node:18) and do not verify any signatures. Outline a three-part remediation plan that addresses (a) tag mutability, (b) provenance verification, and (c) dependency visibility. For each part, name a specific tool or technique and explain how it mitigates the corresponding risk.
Show answer
(a) Tag Mutability: Replace mutable tags with digest-pinned references, e.g., FROM node:18-slim@sha256:abc123.... This ensures that the exact filesystem content is deterministic across builds, even if the upstream tag is re-pushed. Tools like Renovate or Dependabot can automate digest updates when new patched versions are published. (b) Provenance Verification: Integrate cosign verification into the CI pipeline and configure a Kubernetes admission controller (e.g., Kyverno) with a policy that rejects any image lacking a valid signature from a trusted key or OIDC identity. This establishes a trust boundary: only images whose provenance can be cryptographically verified reach production. (c) Dependency Visibility: Add an SBOM generation step using Syft after every image build, outputting CycloneDX format. Feed the SBOM into Grype for vulnerability scanning as a CI gate—fail the pipeline on critical or high severity findings. Store SBOMs alongside the image in the OCI registry as attached artifacts for ongoing audit capability.

Question 4: APPLIED

A fintech startup runs 15 microservices, each built from a different Dockerfile, all sharing python:3.11-bullseye as a base image. A critical CVE is announced in glibc (a system library present in the base image). Using concepts from this lesson, (1) explain why all 15 services are affected, (2) calculate the organizational exposure if the base image has 350 packages and each service adds an average of 80 application-level dependencies, and (3) propose an architectural change that would reduce the blast radius of similar future events.
Show answer
(1) All 15 services share the same base image layer. Because container images inherit all layers beneath them, the glibc vulnerability exists in every service's dependency graph regardless of their application code. This is the transitive trust problem: trusting the base image means trusting all ~350 of its packages. (2) Each service has approximately 350 + 80 = 430 total dependencies. Across 15 services sharing the same base, the organizational dependency footprint is not simply 15 × 430 = 6,450 unique entries—there is significant overlap in the base layer—but the blast radius of a base-layer CVE is 15 services simultaneously, requiring coordinated patching across all pipelines. Using the probability model with p = 0.005 and n = 430: P(per-service) = 1 − (0.995)⁴³⁰ ≈ 1 − e−2.156e^{−2.156} ≈ 0.884, so each service has an ~88% chance of containing at least one critical CVE. (3) Architectural change: migrate to distroless or scratch-based images where the application binary is statically compiled, reducing n from 430 to approximately 20–50. Alternatively, adopt a multi-stage build pattern where only runtime-necessary artifacts are copied into a minimal final stage. This compartmentalizes the base-layer exposure and dramatically reduces the blast radius of OS-level CVEs.

Question 5: CRITICAL THINKING

SLSA Build Level 3 requires that builds occur on an ephemeral, isolated build platform with provenance generated by the platform (not the developer). Argue for or against the following claim: 'SLSA Level 3 alone is sufficient to guarantee that a container image is safe to deploy in production.' In your argument, identify at least two specific attack vectors that SLSA Level 3 does not address and propose complementary controls for each.
Show answer
The claim is false. SLSA Level 3 provides strong assurance about build integrity—it ensures that the build was not tampered with, that provenance is accurately recorded, and that the build environment was ephemeral and isolated. However, it does not address at least two critical vectors. First, SLSA does not evaluate the security of the source code or dependencies themselves. A build can be perfectly hermetic and reproducible yet faithfully compile vulnerable source code or include a malicious dependency declared in the lockfile. Complementary control: integrate vulnerability scanning (e.g., Grype against an SBOM) and static analysis (e.g., Semgrep, CodeQL) as additional pipeline gates that run before signing. Second, SLSA does not cover runtime behavior. An image with valid SLSA Level 3 provenance might still be deployed with excessive privileges, mount sensitive host paths, or communicate with unexpected external endpoints. Complementary control: enforce runtime security policies using tools like Falco or eBPF-based monitors, combined with Kubernetes SecurityContexts and NetworkPolicies that restrict container capabilities and egress. A third subtle gap is that SLSA does not address the trust placed in the build platform itself—if the CI/CD provider is compromised at the infrastructure level, all attestations become untrustworthy. Complementary control: verify provenance attestations against multiple independent transparency logs and consider reproducible builds that can be independently verified by third parties.

SUMMARY

Lesson Summary

Summary

Image provenance establishes the verifiable chain of custody for a container image—from source code commit through CI/CD build to registry publication—using cryptographic signatures and attestations (tools like Sigstore cosign and the SLSA framework). Dependency risk captures the aggregate exposure from every base image layer, system library, and application package in the image's transitive dependency graph, quantified by the relationship P(at least one CVE) = 1 − (1 − p)ⁿ, which shows why minimizing dependencies is a first-order security control.

A robust defense-in-depth posture combines four complementary capabilities: digest pinning to eliminate tag mutability, SBOM generation (via Syft/CycloneDX) for dependency visibility, vulnerability scanning (via Grype/Trivy) for risk identification, and provenance signing and admission-time verification to ensure that only trusted, inspected images reach production. Together, these practices transform container image security from a best-effort activity into a policy-enforced, auditable discipline.

Varsity Tutors • Cyber Security • Image Provenance & Dependencies