How We Got Here: Supply Chain Security¶
Arc: Security Eras covered: 5 Timeline: ~2015-2025 Read time: ~11 min
The Original Problem¶
For most of software's history, the supply chain was invisible. You pulled a Docker image from Docker Hub, installed a package from npm, or downloaded a binary from a project's website, and trusted it implicitly. Nobody verified who built it, what source code produced it, or whether it had been tampered with. The trust model was: "it has a lot of downloads, so it's probably fine."
Then SolarWinds happened (December 2020). Attackers compromised the build system of a widely-used IT management tool and inserted a backdoor into a legitimate software update. 18,000 organizations — including US government agencies — installed the trojanized update. The industry realized that the software supply chain was a massive, undefended attack surface.
Era 1: Trust Everything (~2015-2018)¶
The Solution¶
There was no solution — there was barely an awareness of the problem. Teams pulled base images tagged :latest, installed packages without verifying checksums, and used GitHub Actions from unknown authors. Package managers provided convenience; security was an afterthought.
What It Looked Like¶
# Dockerfile circa 2016 — trust everything
FROM ubuntu:latest
RUN apt-get update && apt-get install -y curl
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN apt-get install -y nodejs
RUN npm install -g some-random-package
COPY . /app
RUN npm install
CMD ["node", "/app/server.js"]
# GitHub Actions — use third-party actions without pinning
steps:
- uses: actions/checkout@v2
- uses: some-random-person/deploy-action@master
with:
token: ${{ secrets.DEPLOY_TOKEN }}
Why It Was Better¶
- Fast iteration: pull, build, deploy without friction
- Huge ecosystems: npm, PyPI, Docker Hub had everything you needed
- Community-driven: open source provided massive value
Why It Wasn't Enough¶
- No verification of image provenance or integrity
- Typosquatting attacks:
crossenvinstead ofcross-env(npm, 2017) - Event-stream attack (npm, 2018): malicious code injected into a popular package
- No SBOM: you couldn't enumerate what was in your containers
:latesttags were mutable — the image could change under you- Dependency confusion attacks were trivially easy
Legacy You'll Still See¶
The "trust everything" model persists in most development environments. Many teams still use :latest tags, don't pin dependency versions, and pull from public registries without verification. Changing this requires both tooling and cultural shift.
Era 2: Container Image Scanning (~2018-2021)¶
The Solution¶
Container image scanners — Trivy (Aqua, 2019), Clair (CoreOS/Red Hat), Snyk Container, and commercial tools from Aqua, Prisma Cloud, and Sysdig — analyzed container images for known vulnerabilities (CVEs). They compared installed packages against vulnerability databases (NVD, vendor advisories) and reported findings. CI pipelines gained a "scan" step that could block deployment of vulnerable images.
What It Looked Like¶
# Trivy scan in CI pipeline
trivy image --severity CRITICAL,HIGH --exit-code 1 \
registry.example.com/myapp:${COMMIT_SHA}
# Output:
# myapp:abc123 (debian 11.3)
# Total: 15 (CRITICAL: 2, HIGH: 13)
#
# ┌─────────────┬────────────────┬──────────┬───────────────────┐
# │ Library │ Vulnerability │ Severity │ Fixed Version │
# ├─────────────┼────────────────┼──────────┼───────────────────┤
# │ libssl1.1 │ CVE-2022-0778 │ HIGH │ 1.1.1n-0+deb11u1 │
# │ curl │ CVE-2022-22576 │ HIGH │ 7.74.0-1.3+deb.. │
# └─────────────┴────────────────┴──────────┴───────────────────┘
# GitHub Actions with Trivy scan
- name: Scan image
uses: aquasecurity/trivy-action@0.14.0
with:
image-ref: ${{ env.IMAGE }}
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'
exit-code: '1'
- name: Upload scan results
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
Why It Was Better¶
- Visibility: teams could see what vulnerabilities existed in their images
- Automation: scanning in CI caught issues before production
- Prioritization: severity ratings helped focus remediation
- Registry integration: scan on push, block pulls of vulnerable images
- Free, high-quality tools (Trivy) lowered the barrier
Why It Wasn't Enough¶
- CVE-focused: only found known vulnerabilities, not malicious insertions
- False positives overwhelmed teams (100+ findings, most not exploitable)
- No provenance: scanning told you what was in the image, not who built it
- Lag between vulnerability disclosure and scanner database updates
- Base image vulnerabilities were often outside the team's control
- Did nothing about compromised build systems (SolarWinds-style attacks)
Legacy You'll Still See¶
Image scanning is now standard in CI pipelines. Trivy, Snyk, and Grype are the most common tools. Registry-level scanning (ECR, GCR, Harbor) provides a second layer. The challenge has shifted from "how do we scan?" to "how do we prioritize and fix findings at scale?"
Era 3: SBOM (Software Bill of Materials) (~2021-2023)¶
The Solution¶
The Log4Shell vulnerability (December 2021) made the case for SBOMs undeniable. Organizations scrambled to determine if any of their software used log4j — and most couldn't answer quickly. SBOMs (SPDX from Linux Foundation, CycloneDX from OWASP) provided a machine-readable inventory of every component in a software artifact. US Executive Order 14028 (May 2021) required SBOMs for software sold to the federal government.
What It Looked Like¶
# Generate SBOM with Syft
syft registry.example.com/myapp:v1.2.3 -o spdx-json > sbom.json
# Query the SBOM: "do we use log4j?"
cat sbom.json | jq '.packages[] | select(.name | contains("log4j"))'
# Generate with CycloneDX format
syft registry.example.com/myapp:v1.2.3 -o cyclonedx-json > sbom-cdx.json
{
"spdxVersion": "SPDX-2.3",
"name": "myapp-v1.2.3",
"packages": [
{
"name": "express",
"versionInfo": "4.18.2",
"supplier": "Organization: OpenJS Foundation",
"downloadLocation": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
"checksums": [
{ "algorithm": "SHA256", "checksumValue": "abc123..." }
],
"externalRefs": [
{ "referenceType": "purl", "referenceLocator": "pkg:npm/express@4.18.2" }
]
}
]
}
Why It Was Better¶
- Inventory: know exactly what's in every artifact
- Rapid CVE response: "are we affected?" becomes a database query
- Compliance: meets federal and emerging regulatory requirements
- Machine-readable: enables automated vulnerability matching
- Dependency transparency: transitive dependencies are visible
Why It Wasn't Enough¶
- SBOM generation tools are imperfect (miss dynamically loaded libraries, build tools)
- Two competing standards (SPDX vs CycloneDX) with different strengths
- Consuming SBOMs is harder than generating them (tooling is immature)
- SBOMs are a snapshot: they don't update when new CVEs are disclosed
- "SBOM washing" — generating SBOMs to check a compliance box without acting on them
- Doesn't prove how the software was built or who built it
Legacy You'll Still See¶
SBOM generation is becoming standard in CI pipelines. Syft and cdxgen are the common generators. Federal contractors are required to provide SBOMs. The tooling ecosystem is growing rapidly, but consumption and analysis tools lag behind generation.
Era 4: Sigstore and Artifact Signing (~2022-2024)¶
The Solution¶
Sigstore (Linux Foundation, 2021, GA 2022) made cryptographic signing of software artifacts easy and free. Cosign signs container images using keyless signing (OIDC identity from GitHub Actions, Google, etc.). Rekor provides a transparency log (immutable record of all signatures). Fulcio issues short-lived signing certificates. For the first time, signing was easy enough that anyone could do it.
What It Looked Like¶
# Keyless signing with cosign — identity comes from OIDC (e.g., GitHub Actions)
cosign sign registry.example.com/myapp:v1.2.3
# No private key needed — cosign authenticates via GitHub OIDC
# Signature stored in the registry alongside the image
# Signing event recorded in Rekor transparency log
# Verify a signature
cosign verify registry.example.com/myapp:v1.2.3 \
--certificate-identity=https://github.com/myorg/myapp/.github/workflows/build.yml@refs/heads/main \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com
# Attach an SBOM attestation
cosign attest --predicate sbom.json --type spdxjson \
registry.example.com/myapp:v1.2.3
# Verify the attestation
cosign verify-attestation --type spdxjson \
registry.example.com/myapp:v1.2.3
# Kyverno policy — enforce image signatures in the cluster
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-signed-images
spec:
validationFailureAction: Enforce
rules:
- name: check-signature
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "registry.example.com/*"
attestors:
- entries:
- keyless:
issuer: "https://token.actions.githubusercontent.com"
subject: "https://github.com/myorg/*"
Why It Was Better¶
- Keyless: no key management, no key rotation, no key distribution
- Transparency log: public, immutable record of all signing events
- Free and open source: no vendor dependency
- CI integration: GitHub Actions, GitLab CI sign automatically
- Kubernetes enforcement: admission controllers verify before deployment
Why It Wasn't Enough¶
- Adoption is still early — most images are unsigned
- Verification adds deployment latency (checking signatures + transparency log)
- Keyless signing ties identity to OIDC provider (GitHub, Google)
- The ecosystem is complex (cosign, Rekor, Fulcio, policy engines)
- Doesn't verify the content of the software — only who built it
Legacy You'll Still See¶
Sigstore is growing rapidly. Kubernetes ecosystem projects sign their releases with cosign. Major Linux distributions are adopting Sigstore. GitHub Actions has built-in artifact attestation using Sigstore. This is becoming the standard, but most organizations haven't adopted it yet.
Era 5: SLSA Framework and VEX (~2023-2025)¶
The Solution¶
SLSA (Supply chain Levels for Software Artifacts, pronounced "salsa," Google 2021, v1.0 2023) defined a maturity framework with four levels for build integrity. VEX (Vulnerability Exploitability eXchange) addressed the false positive problem by letting vendors state whether a reported CVE is actually exploitable in their specific artifact. Together, they provide a comprehensive supply chain security posture.
What It Looked Like¶
# SLSA Levels:
# Level 0: No guarantees
# Level 1: Build process documented, provenance generated
# Level 2: Hosted build service, signed provenance
# Level 3: Hardened build platform, non-falsifiable provenance
# Level 4: (Future) Two-person review, hermetic builds
# GitHub Actions SLSA provenance generation
- uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.8.0
with:
image: registry.example.com/myapp
digest: ${{ needs.build.outputs.digest }}
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://example.com/vex/2024-001",
"statements": [
{
"vulnerability": {
"@id": "https://nvd.nist.gov/vuln/detail/CVE-2023-44487"
},
"products": [
{ "@id": "pkg:oci/myapp@sha256:abc123" }
],
"status": "not_affected",
"justification": "vulnerable_code_not_present",
"impact_statement": "This application does not use HTTP/2 server functionality"
}
]
}
Why It Was Better¶
- SLSA provides a clear maturity model (where are we? where do we need to be?)
- Non-falsifiable provenance: cryptographic proof of how the artifact was built
- VEX eliminates false positives: vendors declare what's actually exploitable
- Standardized: industry-wide framework, not vendor-specific
- Composable: SLSA provenance + SBOM + signatures + VEX = complete picture
Why It Wasn't Enough¶
- SLSA Level 3+ requires significant build infrastructure investment
- VEX is manual and labor-intensive (someone must analyze each CVE)
- Tooling for consuming and enforcing SLSA is immature
- Most organizations are at Level 0 or 1
- The full chain (build → sign → attest → verify → enforce) is complex
- Regulatory requirements are outpacing tooling maturity
Legacy You'll Still See¶
SLSA is becoming the reference framework for supply chain security maturity. GitHub, Google, and the Linux Foundation are driving adoption. VEX is emerging as a companion to SBOMs. Most organizations are in the "awareness and planning" phase rather than full implementation.
Where We Are Now¶
Supply chain security is the fastest-moving area in DevOps security. Image scanning is table stakes. SBOM generation is becoming standard. Sigstore signing is growing rapidly. SLSA provides a maturity framework. The complete picture — signed artifacts with provenance, SBOMs, and VEX statements, verified at deployment by admission controllers — is achievable but not yet common. Most organizations are somewhere between "we scan images" and "we sign and attest everything."
Where It's Going¶
Regulatory pressure (EU Cyber Resilience Act, US EO 14028, FedRAMP) will make supply chain security mandatory, not optional. SBOM and provenance attestation will become requirements for software procurement. The tooling will converge on Sigstore for signing and SLSA for provenance. The remaining challenge is making this invisible to developers — the build system handles everything, developers never touch a key or generate an SBOM manually.
The Pattern¶
Every generation of supply chain security adds a new dimension of trust: from "I downloaded it" to "I scanned it" to "I know what's in it" to "I know who built it and how" to "I can prove it meets a security standard." Each layer addresses a different attack vector, and all layers are needed simultaneously.
Key Takeaway for Practitioners¶
Start with image scanning (Trivy) — it's free and catches the lowest-hanging fruit. Add SBOM generation (Syft) next. Then add signing (cosign). Don't try to jump to SLSA Level 3 on day one. Each step materially improves your security posture. The order matters: visibility before enforcement.
Cross-References¶
- Topic Packs: Trivy, Sigstore, SLSA
- Tool Comparisons: Supply Chain Security Tools
- Evolution Guides: Artifact Management, Secrets Management