Introduction
In March 2026, the axios package was compromised through a hijacked npm maintainer account. A malicious version was published containing a credential-stealing backdoor that exfiltrated cloud keys before self-destructing. This incident exemplified a persistent problem: downstream users must trust artifacts blindly without cryptographic verification of build provenance.
At Fystack, a crypto custody infrastructure provider, supply chain integrity is critical—"a tampered image in our environment doesn't mean a bug, it means compromised keys and drained wallets." The company addressed this challenge through SLSA L3 provenance implementation.
The Verification Gap Nobody Talks About
When pulling a Docker image, users receive a SHA-256 digest proving content integrity. However, this reveals nothing about production methods. Signatures verify identity but not whether the build environment was compromised or if code matched the source commit.
The gap exists between "signed" and "provable." A malicious actor accessing CI runners can build and sign anything with legitimate credentials. Dependency poisoning during builds produces validly-signed images containing malicious code.
This gap requires a third guarantee: provenance—a cryptographically signed record of the exact source commit, build environment, workflow, and parameters, generated by a process isolated from the build itself.
What SLSA Actually Means (Beyond the Acronym)
Supply-chain Levels for Software Artifacts was developed by Google and is governed by the OpenSSF. The framework defines graduated security guarantees for build pipelines:
- L1: Untrusted provenance document; useful for auditing but easily forgeable
- L2: Cryptographically signed provenance by CI platform; prevents post-build tampering but the same job generating the build creates the proof
- L3: Provenance generated in a completely isolated process with separate identity and credentials; the build job cannot influence it
In practical terms:
- No SLSA/L1: "Trust me, I built this"
- SLSA L2: "Our CI built this, but if compromised, proof can be faked"
- SLSA L3: "This image was built by our CI in a locked-down environment, and we can prove it, even if the build job is fully compromised"
SLSA L3 is now baseline for serious infrastructure providers. Google ships official container images at SLSA L3; GitHub builds Artifact Attestations on SLSA L3; Bitnami's Secure Images are SLSA L3 with publicly published verification keys.
The Critical Difference: BuildKit vs. SLSA Generator
Most implementations conflate these approaches. Docker's build-push-action with provenance: true provides L2 guarantees, not L3.
BuildKit Provenance (provenance: true):
- Generated in the same job as the build
- Forgeable if the build is compromised
- SLSA L1–L2
SLSA L3 Provenance (via slsa-github-generator):
- Generated in a separate isolated job
- Receives only the image digest
- Not forgeable even if the build is compromised
- Signed by the SLSA generator's identity
How Fystack Applied SLSA
Fystack's implementation uses three sequential jobs:
Job 1: Build & Push
BuildKit compiles and pushes the image; native provenance is disabled, keeping only the immutable image digest.
Job 2: SLSA L3 Provenance
Uses slsa-framework/slsa-github-generator in an isolated job. It receives only the final image digest, independently verifies the source repository, commit, and workflow via GitHub APIs, and generates non-forgeable SLSA Level 3 attestation. Even if Job 1 is compromised, this provenance cannot be faked.
Job 3: Signing & Attestation
- Signs the image using cosign with keyless signing (GitHub OIDC + Fulcio); no private keys touch the repository or runner
- Generates full SPDX SBOM with Syft and attests it to the image
- Stores signatures and attestations using OCI 1.1 referrers mode to avoid tag pollution
The final image carries five artifacts on the same digest:
- Image layers
- BuildKit SBOM (for Docker Scout)
- Cosign signature
- SLSA L3 provenance
- Sigstore-attested SPDX SBOM
Fystack open sourced this pipeline as a reusable GitHub Actions workflow at fystack/slsa-workflows.
What Verification Looks Like
Downstream consumers verify independently with two commands:
# 1. Verify the cosign signature
cosign verify \
--certificate-identity-regexp='https://github.com/fystack/slsa-workflows/.github/workflows/docker-build-slsa.yml@.*' \
--certificate-oidc-issuer='https://token.actions.githubusercontent.com' \
fystacklabs/apex:v1.0.54
# 2. Verify SLSA L3 provenance
slsa-verifier verify-image \
--source-uri github.com/yourorg/your-repo \
fystacklabs/apex@sha256:...
If the build was tampered with, provenance checks fail even if the signature remains valid.
All signatures and attestations are recorded in Rekor, Sigstore's public transparency log, creating an immutable, independently auditable record.
What This Still Doesn't Solve
SLSA L3 is powerful but not comprehensive. Dependency attacks remain real threats. Malicious packages can be legitimate at build time while the image passes all verification. SBOMs provide visibility, not prevention.
Base image risks are inherited. Backdoors like XZ Utils hid in official Debian images for over a year. Provenance records the base used but cannot detect compromise. Pinning by digest helps but doesn't eliminate risk.
Malicious maintainers bypass everything. If trusted committers merge backdoored code, SLSA L3 still passes. It proves the pipeline ran correctly, not that code was safe. Code review and branch protection remain essential.
Language registries such as npm and PyPI still lag behind container registry tooling.
The Standard Is Moving
Three years ago, SLSA L3 was considered advanced security theater. Today it's becoming baseline expectation for serious projects.
The question has shifted from "Should we adopt SLSA L3?" to "Why haven't we done it yet?"
Tools are free, mature, and maintained by Google and the OpenSSF. The effort is real but measured in hours, not weeks.
"Your users run your code in production. They deserve more than 'trust me.' They deserve cryptographic proof."






Top comments (1)
The axios incident is the one that hit closest to home for me. I've been building a CVE scanner for self-hosted Docker environments — NEXUS Security — and when I ran Grype against my own images, axios 1.14.0 came back with two Critical CVEs: GHSA-3p68-rc4w-qgx5 (SSRF bypass) and GHSA-fvcv-3m26-pcqx (Cloud Metadata Exfiltration). Both fixed in 1.15.0. I was running 1.14.0 in production without knowing it.
CVE scanning catches known vulnerabilities in what you're running. What you're describing — SLSA L3 provenance — catches something different and arguably more dangerous: whether what you pulled is actually what was built from the source you think it was. The axios supply chain attack you mention is exactly the failure mode that provenance is designed to catch and CVE scanning can't — a clean-looking package with a malicious payload that hasn't been indexed as a CVE yet.
The verification gap framing is the right one. SHA-256 proves content integrity. It says nothing about build integrity. Those are different guarantees and most teams treat them as the same thing.
The part I'd be curious about: at what point in your pipeline does the provenance check fail loudly enough to stop a deploy? The tooling exists, but the operational question of where to put the gate — and what happens when a third-party base image can't provide L3 provenance — is where most teams I've seen get stuck.