Supply chain: trusting code you did not write
Dependencies, build systems and artifacts are now the attack surface. SBOMs, signing, provenance and hermetic builds, and what SolarWinds and xz taught us.
● Must know for interviewsFREELesson·24 min read·Intermediate → Advanced
supply chainSBOMSigstoreSLSA
01The new attack surface
✓What you will learn
- Draw the software supply chain and the attack at each link
- Explain SBOM, signing and provenance and what each proves
- Describe SLSA levels in plain words
- Know the xz lesson: maintainers are a trust boundary too
FigA supply chain with verification at every hand-off
- ACTOR
- EDGE
- SERVICE
- DATA
- CONTROL
- Live flow
- Lookup / async
| Link | Attack | Control |
|---|---|---|
| Developer | Stolen token pushes code | Hardware keys, signed commits, short-lived tokens |
| Dependencies | Typosquat, hijacked maintainer, malicious update | Lockfiles, private mirror with quarantine, SCA, cooldown period on new versions |
| Build | Compromised CI runner injects code | Ephemeral runners, no long-lived creds, hermetic builds, provenance (SLSA) |
| Artifact | Image swapped in registry | Sign with Sigstore/cosign, verify at admission |
| Deploy | Unsigned image runs anyway | Admission policy: no signature + provenance, no run |
02What each proof proves
- SBOM (CycloneDX / SPDX): what is inside. Lets you answer "are we affected by CVE-X?" in minutes, not days.
- Signature: this artifact was produced by this identity. Keyless signing with Sigstore ties it to a CI workload identity, not a long-lived key.
- Provenance (in-toto / SLSA): how it was built, from which commit, by which builder. Lets admission refuse anything not built by your pipeline from your repo.
# Kyverno admission policy: only run images signed by our CI identity
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata: { name: verify-image }
spec:
validationFailureAction: Enforce
rules:
- name: cosign-keyless
match: { any: [{ resources: { kinds: [Pod] } }] }
verifyImages:
- imageReferences: ["registry.cyart.io/*"]
attestors:
- entries:
- keyless:
subject: "https://github.com/cyart/*/.github/workflows/release.yml@refs/heads/main"
issuer: "https://token.actions.githubusercontent.com"“How to say it in the room
"Signing alone tells me who signed, not what they built. I want provenance too: the image must come from our release workflow on main. Then a stolen registry credential cannot get code into production."
Q1What did xz teach?+
A patient attacker became a trusted maintainer over two years and shipped a backdoor in a release tarball that differed from git. Lessons: build from source you can diff, watch for release artifacts that differ from the repo, and treat upstream maintainers as a trust boundary.
Q2Pin by version or by hash?+
Hash. Versions can be re-published; a lockfile with integrity hashes cannot be silently swapped.
Finished this one?
Tick it and it shows as done on the roadmap and the course.