Know what you ship and where it came from. SBOM tracks dependencies, signing prevents tampering, provenance proves origin — every artifact, every build.
Know what you ship and where it came from. SBOM tracks dependencies, signing prevents tampering, provenance proves origin — every artifact, every build.
Lesson outline
When you build a modern web application, you write maybe 10% of the code. The other 90% comes from third-party libraries: npm packages, Docker base images, internal packages, and transitive dependencies (dependencies of dependencies). A typical Node.js application has 1,000+ transitive dependencies. A Python app might have 500+. Each dependency is a potential attack surface.
The three supply chain attack types
| Attack Type | Detection Time | Blast Radius | Cost to Remediate |
|---|---|---|---|
| SolarWinds (build compromise) | 6 months | 18,000 customers, US government | $18 billion+ across ecosystem |
| npm left-pad removal | Hours | Thousands of packages broke | Reputational damage to npm |
| Log4j CVE (transitive dep) | 1-2 days | Every app using the library | Hours to days to patch — if SBOM available |
| Typosquatting | Minutes to days | Whoever installed the malicious package | Data exfiltration, backdoor install |
Key insight
You cannot trust a package just because it is from a legitimate vendor or popular on npm. You need to verify: (1) what is in it (SBOM), (2) it was not tampered with (signing), (3) where it came from (provenance).
Select a package from the tree to see details, CVEs, and attack scenarios.
An SBOM (Software Bill of Materials) is a structured list of every dependency in your software: package name, version, supplier, and dependency relationships (direct vs transitive). When a CVE is announced for library X version Y, you query your SBOMs and get an instant answer — "which services are affected?" — in 30 seconds instead of three weeks.
| Format | Pros | Cons | Best For |
|---|---|---|---|
| SPDX | Standard, comprehensive, widely supported | Verbose, complex | Enterprise compliance, audits, federal requirements |
| CycloneDX | Lightweight, container-focused, fast | Less mature than SPDX | Container images, CI/CD pipelines |
| Syft JSON | Easy to parse, human-readable | Not standardized | Internal tooling, quick scanning |
SBOM is not just for security
SBOM also enables: compliance ("prove you know what code runs in prod" for SOC 2), license tracking (do we have GPLv3 libraries that require open-sourcing?), and cost optimization (which services can we decommission?).
1# GitHub Actions: Generate SBOM for every build2- name: Build Docker image3run: docker build -t myapp:${GITHUB_SHA} .45- name: Generate SBOM with Syft6run: |7curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/binSyft scans the built image and generates a machine-readable SBOM8syft myapp:${GITHUB_SHA} -o spdx-json > sbom.spdx.json9syft myapp:${GITHUB_SHA} -o cyclonedx-json > sbom.cyclonedx.json1011- name: Scan for CVEs with Grype (using the SBOM)Grype uses the SBOM to scan for CVEs — --fail-on high blocks deployment12run: |13grype sbom:./sbom.spdx.json --fail-on high1415- name: Attach SBOM to image (Cosign attestation)Cosign attaches the SBOM to the image in the registry — it travels with the artifact16run: |17cosign attach sbom --sbom sbom.spdx.json myapp:${GITHUB_SHA}1819- name: Push image with SBOM attestation20run: docker push myapp:${GITHUB_SHA}
1#!/bin/bash2# When CVE-2021-44228 (Log4j) announced:3# Query: Which builds contain log4j with version < 2.17.1?45# If SBOMs stored in Dependency-Track SBOM server:SBOM query returns affected services in seconds — not weeks of manual searching6curl -X GET "https://dtrack.example.com/api/v1/bom/search?name=log4j&version=2.17.0" \7-H "X-API-Key: $API_KEY"89# Returns instantly:Structured response: exact services, exact versions — actionable immediately10# [11# { "project": "auth-service", "affectedComponent": "log4j:2.14.1" },12# { "project": "api-gateway", "affectedComponent": "log4j:2.14.1" },13# ... 45 more services14# ]15# Total: 47 services need patching. You know EXACTLY which ones.16Without SBOM: manual grep misses transitive deps — some services remain vulnerable17# Without SBOM: grep through 500 repos, miss transitive deps, leave 12 unpatched
Signing answers: has this artifact been modified since it was built? Provenance answers: did this artifact come from my trusted pipeline and commit? SolarWinds was signed with a legitimate key — but the build was compromised before signing. Provenance would have caught the discrepancy: "built from commit X, but commit X does not contain this code."
The signing workflow
Keyless signing with Sigstore
Sigstore eliminates private key management entirely. Your CI provider (GitHub Actions, GitLab) issues a short-lived OIDC token that proves identity. Cosign uses this to get a certificate from Sigstore's Fulcio CA and records the signing event in the Rekor transparency log. No key to manage, rotate, or accidentally expose.
1#!/bin/bash2# 1. Generate signing keys (once — store private key in HSM or Vault)3cosign generate-key-pair4# Outputs: cosign.key (private), cosign.pub (public)5# Best practice: use Sigstore keyless signing in CI to avoid key management67# 2. Sign image in CI/CD pipeline after buildingSign immediately after build — before push to registry8cosign sign --key cosign.key myregistry/myapp:latest9# Signature stored in container registry alongside the image1011# 3. Generate SLSA provenance (links artifact to source commit + build pipeline)12# In GitHub Actions, use slsa-github-generator13# Provenance proves: "built from commit abc123 by pipeline X"14Verify at deploy: this is the gate that stops tampered images from running15# 4. Verify at deploy time (or in Kubernetes admission controller)16cosign verify --key cosign.pub \17--certificate-github-workflow-repository myorg/myrepo \18myregistry/myapp:latest19Provenance check: verifies the image was built from the expected commit and pipeline20# 5. Verify provenance21cosign verify-attestation --key cosign.pub \22--type slsaprovenance \23myregistry/myapp:latest | jq .Non-zero exit code = gate fails = pod never scheduled2425# If signature invalid or provenance mismatch -> reject the image26if [ $? -ne 0 ]; then27echo "❌ Verification failed. Image rejected."28exit 129fi30echo "✅ Signature and provenance verified. Deploying."
Understanding exactly which controls catch which attacks — and which ones they miss — is essential for building layered defenses.
| Attack | SBOM | SCA Scanning | Signing | Provenance | Private Registry |
|---|---|---|---|---|---|
| Typosquatting (Iodash) | Detects after | ✗ (unknown package) | ✗ (attacker signs it) | ✗ | ✅ Blocks entirely |
| Compromised transitive dep (Log4j) | ✅ Query in seconds | ✅ Scans transitive | ✗ (legitimate sig) | ✗ | ✗ |
| Build compromise (SolarWinds-style) | ✅ After-the-fact | ✗ | ✅ Sig fails if key safe | ✅ Provenance mismatch | ✗ |
| Modified image in registry | ✗ | ✗ | ✅ Sig invalid | ✅ Hash mismatch | ✗ |
| Dependency confusion | ✅ Detects package | ✅ Scans it | ✗ | ✗ | ✅ Blocks entirely |
Layered defense — no single control is sufficient
SBOM gives visibility. SCA finds known CVEs. Private registry prevents unknown packages. Signing proves integrity. Provenance proves origin. You need all five layers for comprehensive supply chain security.
Supply chain security initiatives fail in predictable ways. Knowing the anti-patterns saves months of wasted effort.
The five most common failures
How supply chain security matures from startup to enterprise, and how it connects to the rest of your security program.
| Scale | Team Size | Supply Chain Setup | Tools | Primary Challenge |
|---|---|---|---|---|
| Startup | <20 eng | SCA in CI, dependency pinning, private registry | Snyk, npm audit, GitHub Advanced Security | Cost, false positives |
| Scale-up | 100-500 eng | SBOM generation, basic signing, SCA + DAST | Syft + Cosign, Snyk, Dependency-Track | SBOM accuracy, key management |
| Enterprise | 1000+ eng | SBOM + signing + provenance + monitoring + policy-as-code | Dependency-Track, Sigstore, supply chain governance | Coordination across teams, legacy apps |
Key metrics to track
Log4j with full supply chain security — the ideal response
CVE announced → minute 1: SBOM query finds 47 affected services → hour 1: patch log4j in base image → hour 2-4: rebuild all 47 services → hour 5: sign and generate provenance → hour 6: deploy to staging with verification → hour 8: production patched and verified. Total: 8 hours. Without supply chain security: weeks of manual searching, some services missed, vulnerabilities left in production.
Principal engineer, staff engineer, DevSecOps architect, platform team interviews. Common in companies with compliance requirements (SOC 2, FedRAMP) or those affected by high-profile supply chain incidents. Often presented as a scenario: "A critical CVE drops — walk me through your response."
Common questions:
Strong answer: Immediately mentions SBOM and CVE response workflow (query → identify affected services → patch → rebuild → redeploy). Knows SolarWinds was a build compromise and explains why provenance would have caught it. Distinguishes signing (integrity) from provenance (origin) from scanning (known CVEs). Mentions Sigstore keyless signing. Talks about monitoring for supply chain anomalies beyond CVE databases.
Red flags: Says supply chain security is just dependency scanning. Does not know about SolarWinds attack. Thinks signing eliminates the need for monitoring. No mention of SBOM or how they would respond to CVE quickly. Stores private signing keys in CI environment variables.
Quick check · Supply Chain Security: SBOM, Signing, and Provenance
1 / 4
Key takeaways
You receive an alert that CVE-2021-44228 (Log4Shell RCE) affects log4j < 2.17.1. Walk through how you identify and patch all affected services.
Query the SBOM server: "which builds contain log4j with version < 2.17.1?" Get the list (e.g., 47 services). Update the log4j version in the shared base image or each service. Trigger rebuilds. New SBOMs are generated automatically. Grype scans confirm the CVE is resolved. Sign the new images. Deploy with signature and provenance verification. Confirm production is running the patched version via provenance check.
Why does Sigstore keyless signing improve security compared to using a static private signing key in CI?
A static private key must be stored somewhere (CI secret, Vault) and can be leaked or stolen — if it is, an attacker can sign malicious artifacts that pass verification. Sigstore keyless signing uses your CI provider's OIDC token (e.g., GitHub Actions ID token) to get a short-lived certificate from Sigstore's Fulcio CA. The certificate is valid for minutes and is bound to the specific pipeline run. There is no long-lived key to steal. The Rekor transparency log records every signing event — detectable if misused.
From the books
Software Supply Chain Security (O'Reilly, 2023)
Comprehensive guide covering SBOM formats (SPDX vs CycloneDX), Sigstore ecosystem (Cosign, Fulcio, Rekor), SLSA framework levels, and enterprise supply chain governance. Essential reading for anyone building out supply chain security at scale.
💡 Analogy
Customs at a port of entry
⚡ Core Idea
Supply chain security is like customs at a port. You need to know what container you are importing (SBOM), verify it was not tampered with during shipping (signing), know where it came from (provenance), and check the manifest against what actually arrived. One compromised shipment can poison the entire port.
🎯 Why It Matters
SolarWinds compromised 18,000 organizations through a single build pipeline. The attackers did not hack each customer — they hacked the supply chain once and got everyone. Your application is 90% third-party code. Securing your own code while ignoring your dependencies is like locking your front door while leaving the back door open.
Ready to see how this works in the cloud?
Switch to Career Paths for structured paths (e.g. Developer, DevOps) and provider-specific lessons.
View role-based pathsSign in to track your progress and mark lessons complete.
Questions? Discuss in the community or start a thread below.
Join DiscordSign in to start or join a thread.