The Factory Is the Target - A Threat Taxonomy for the Software Supply Chain

TL;DR: Most of today’s supply chain compromises start in the software factory, the machinery that turns source code into running software, and there is still no threat taxonomy that covers it end to end. I have published one: 221 threats across 17 stations of the factory, from the developer’s laptop to the last hop into production, plus 10 structural hazards, each with a mitigation principle and concrete design measures. It is the reference for my card game Software Factory. Walk it against a pipeline you know and tell me what it misses. The full taxonomy, with a page per station and downloads in four formats, is at Software Factory Threat Taxonomy.
Every software company now runs a factory. Developer laptops with AI agents on them, a hosting platform, hundreds of pipeline files, runners, caches, build tools, thousands of dependencies, scanners, registries, firewalls, SBOMs, Terraform, images and clusters. Each one holds credentials to the next, and each one trusts what the last one handed it.
Attackers have noticed. They no longer need the application when they can have the pipeline that builds it, the token that publishes it, or the scanner that inspects it. SolarWinds, Codecov, xz Utils, tj-actions, Shai-Hulud and, in March this year, Trivy are all the same lesson. The factory is the target.
The problem is not that teams skip threat modeling. The problem is that the frameworks were built for the application, not for the machinery that builds it. Apply STRIDE to a CI/CD design and it will surface something: spoofing, tampering, elevation of privilege. It will rarely surface a release cache that pull requests can write to, a cloud role that trusts every repository in the organisation, a version tag that someone else can move, or a dependency firewall that waves everything through when its feed is down.
I have published a taxonomy that does: 221 threats across 17 stations of the software factory, plus 10 structural hazards, each with the principle a sound design follows and concrete measures that put it into practice. It has a home of its own on this site, with a page for every station, and this post explains why it exists and what it covers. It is the reference for a card game I designed first, Software Factory: every entry is one of the game’s cards, restated as prose.
Why the gap exists
The software supply chain is not short of frameworks. It is short of one that covers the whole factory, in the form a design review needs. Each of the frameworks we have covers a slice, and covers it well:
- SLSA covers the integrity of source, build and dependencies, and says plainly that it does not address every threat it lists.
- The OWASP Top 10 CI/CD Security Risks names ten risk areas, which is a starting point rather than a classification.
- The Kubernetes threat matrices from Microsoft and MITRE ATT&CK start after deployment.
- The SAP taxonomy of attacks on open-source supply chains (Ladisa et al.) is the most complete of all, but it is an attack tree for getting malicious code into packages, and it stops at the package.
- OSC&R and the CNCF catalogue of supply chain compromises describe attacker behaviour and real incidents, not properties of the components a team is building.
Between them, they leave three gaps. Nothing spans the factory from the workstation to the cluster in one classification. Nothing states each threat as a property of a component or a design decision, the form a threat model needs, rather than as an attacker technique or an incident. And almost nothing treats the security controls themselves as attack surface: the scanners, the dependency firewall, signing, provenance and SBOMs.
That last gap is the one that has hurt most recently. In the Trivy compromise, attackers force-pushed 76 of 77 version tags of the trivy-action GitHub Action and shipped a credential-stealing scanner binary into every pipeline that ran it. The control was the way in.
The result is not that the software factory is insecure by intention. It is unexamined by default. The people who build pipelines, runners, registries, scanners and clusters are very good at what they build. What they rarely have is a framework for asking: what can go wrong at this station, at this trust boundary, in this sequence?
When the framework does not exist, the question does not get asked systematically. And when the question does not get asked, the findings do not get made.
What the taxonomy is
It is a structured catalogue of what can go wrong in the software factory, organised by the station where the threat lives. The stations run along two production lines, and a further group of structural hazards belongs to the factory as a whole, so no single station can fix them.
- Line 1, Source to Artifact: nine stations, from the developer’s machine to a built, scanned and attested artifact.
- Line 2, Artifact to Runtime: eight stations, from the registry to a running workload.
Every entry has the same parts:
- A name, short enough to say in a design review.
- A threat, stated as a property of a component or a design decision. Not “an attacker could”, but “the pipeline does”.
- A mitigation principle: what a sound design does, stated so that different designs can satisfy it in different ways.
- Design measures: two to four concrete ways of satisfying the principle. They are examples of what works, not the only acceptable answers.

Where a threat has been seen in the wild, the entry names the public incident or disclosure (75 of the 231 entries do). The others are design weaknesses with no single headline incident, which does not make them less real.
The format is deliberate. A threat on its own is an accusation, and a list of measures on its own is a checklist that fits one architecture and no other. The principle sits between them: it says what must be true, and the measures show what that looks like in practice. Against a real design, each entry produces a finding, or a one-line “no exposure” with the reason, which is worth writing down too.
Each entry carries a reference such as PD·J or T9: the station code plus a playing-card rank, from Ace down to 2, or T1 to T10 for the structural hazards. The taxonomy is the reference for the card game Software Factory: each entry is one of its cards, and the two share one set of references. The reference is a stable identifier, not a severity. In the game the ranks follow severity, because play is trick-based; here a reference only names an entry, and it stays the same as the taxonomy grows.
Who it is for and how to use it
If you build or run the factory, whether you are on a platform, DevOps or DevSecOps team, or you own the path from a developer’s commit to production, this was written for you first. You do not need a security background. Each entry tells you what to look for, what a sound design does about it, and concrete ways that has been done.
If you build tools that sit in the factory, a scanner, a registry, a dependency firewall, a signing service or a CD controller, your product is on this map as a component with threats of its own, not only as a control. Walk its station against your own design.
If you are a security engineer who has been handed a pipeline to threat model and found that STRIDE gives you the obvious but misses the specific (the moved tag, the poisoned cache, the firewall that fails open), this names what you have been trying to name. The stations match the way the factory is already drawn, and the entries are precise enough to write findings against.
If you are a CISO, there is one question here for you. Has anyone ever threat modeled the factory itself, end to end, including the security tools you bought to protect it?
Using it is simple:
- Draw the factory: every machine, repository, pipeline, runner, store, registry and cluster a change passes through on its way to production, with the trust boundaries and the credentials marked.
- Take one station and walk every entry in it against each element it applies to.
- For each entry, ask whether the design satisfies the principle. Write down a finding, or “no exposure” and the design decision that defeats it.
- Where there is a finding, start from the measures given and adapt them to your architecture. They are the shape of a fix, not a prescription.
- Finish with the structural hazards, played against the design as a whole. They usually explain several findings at once and point to an architectural change, not a patch per finding.
Note to platform teams: start with Pipeline Identity and Secrets. The pipeline is the most privileged identity you have, and every other station is only as safe as what its credentials can reach.
Scope and origin
The taxonomy covers the machinery: the developer’s tools, the source, the pipeline and the identities it holds, the build, the dependencies, the security controls, the artifacts and their registries, the infrastructure code, the containers, the cluster and the path to production. It does not cover vulnerabilities in the application being built, which existing frameworks already serve well, nor the business processes around a release. It covers how the factory itself can be turned against you.
It started as a game. I designed Software Factory, a threat modeling card game, because I saw a gap in the games we already have: they cover web applications, cloud, privacy, AI and more, but none of them walks the software supply chain station by station. The deck came first, and this taxonomy is its reference: each card’s threat became an entry, each card’s suit became a station, and the mitigation principle and measures were written to answer the questions the card asks. What you are reading is the game’s content, restated so that it can be used without the game.
I want to be clear about one thing: it is not that these issues did not exist. Many were already known, publicly disclosed in real systems. Dependency confusion, the tj-actions and Trivy tag compromises, the Codecov uploader, SolarWinds SUNSPOT, xz Utils, Shai-Hulud and Leaky Vessels are well-known examples, and the references at the end point to the original disclosures. What was missing was the translation. Each issue had to be restated as a threat that a designer can test their own system against, and the whole lot collated into a single resource that spans the factory. That is the contribution here: the translation and the collection, not the discovery.

The public cases are not evenly spread. Fifty of the 75 sit at the first seven stations of Line 1, from the workstation to dependency resolution, where attackers have been busiest and researchers have written the most. The four control stations have three between them, and SBOM and VEX has none. That is not a sign that the controls are safe. It is a sign that nobody has written up the incident yet, which is the best reason to model those threats now.
What the taxonomy covers
The full taxonomy lives in the Software Factory Threat Taxonomy section of this site, with a page for every station. Each station page has its entries, where it touches the stations next to it, the public cases its threats were seen in, and how it maps to STRIDE, CAPEC and CWE. These are the 17 stations and the structural hazards:

Line 1, Source to Artifact
- 01 · Workstation and Agents (WS): 13 threats. IDEs, extensions, dev containers, local credentials, AI coding assistants and agents, pre-commit hooks.
- 02 · Version Control (VC): 13 threats. Repositories, branches, tags, review, forks, the hosting platform, its apps and bots.
- 03 · Pipeline Definition (PD): 13 threats. Workflow files, triggers, expressions, reusable workflows, third-party actions and plugins.
- 04 · Runners (RN): 13 threats. Hosted and self-hosted build agents, caches, artifacts passed between jobs, isolation.
- 05 · Pipeline Identity and Secrets (ID): 13 threats. Secret stores, OIDC federation, tokens, service accounts, access to signing keys.
- 06 · Build Systems (BS): 13 threats. Make, Maven, Gradle, Bazel, compilers, toolchains, build plugins, remote cache and execution.
- 07 · Dependency Resolution (DR): 13 threats. Package managers, manifests, lockfiles, install scripts, dependency update bots.
- 08 · Scanners and Gates (SG): 13 threats. SAST, SCA, secrets, IaC, container, licence and DAST scanners; quality gates; policy checks.
- 09 · Provenance and Attestation (PV): 13 threats. SLSA provenance, in-toto attestations, signing, Sigstore, transparency logs, verification.
Line 2, Artifact to Runtime
- 10 · Registries (RG): 13 threats. Public package and image registries, internal artifact repositories, proxies and mirrors.
- 11 · Firewall and Quarantine (FW): 13 threats. Dependency firewalls, curated proxies, cooldowns, quarantine, allow lists and exceptions.
- 12 · SBOM and VEX (BM): 13 threats. SBOM generation, storage and exchange, VEX statements, decisions driven by inventory.
- 13 · Infrastructure as Code (IC): 13 threats. Terraform and OpenTofu, Pulumi, CloudFormation, Ansible; state, modules, providers, plan and apply.
- 14 · Container Images (IM): 13 threats. Base images, Dockerfiles, layers, image builds, tags and digests.
- 15 · Container Runtime (RT): 13 threats. Runtimes, isolation boundaries, the host kernel, sandboxes.
- 16 · Orchestration (OR): 13 threats. Kubernetes API, RBAC, admission, operators, Helm, nodes, cluster networking.
- 17 · Delivery and Deployment (DL): 13 threats. CD tools, GitOps controllers, promotion, environments, approvals, rollback.
The whole factory
- Structural hazards (T): 10 hazards. Hazards of the software factory as a whole.
That is 221 threats and ten structural hazards in all. The overview page also covers where the stations touch, the sources for every known case, the licence and the version history.
Final thoughts
This is a first published version, not a final one. The factory changes every month, with new package ecosystems, new runners, new AI agents with commit rights and new security tools in the path, and I have no doubt there are threats I have missed and entries that belong at a different station.
So take it, walk a station against a pipeline you know well, and tell me where it falls short. Corrections, missing threats and worked examples from practitioners are all welcome: reach out to me on LinkedIn.
The factory has gone unexamined by default for long enough, and it is where the attackers are now. Let’s start asking the question. More on the game the taxonomy came from in a later post. Stay tuned!
Resources
The taxonomy is also available to download in four formats, all with the licence embedded. The overview page lists them too.
| Download | Format | What it is for |
|---|---|---|
| A4 landscape, a section per station, with each entry’s mappings | Reading and printing | |
| Excel | One station per sheet, with the STRIDE, CAPEC and CWE mappings | Filtering, sorting, and tracking findings against each entry |
| SKOS (JSON-LD) | W3C SKOS concept scheme | Linked data and knowledge graphs |
| STIX 2.1 | STIX 2.1 bundle | Threat intelligence and security tools |
Licence
© 2026 Jonathan Brett Crawley. The taxonomy is licensed under CC BY-NC-ND 4.0 with additional permissions: you can share it freely for non-commercial purposes, threat model with it (including for paying clients), use it internally and for training in any organisation, and quote entries with credit in paid work. Shipping it in a product needs permission. The full terms are on the overview page.
References
Every known case named in the tables was checked against a primary or near-primary source in October 2026. The frameworks the taxonomy builds on come first, then a source for each known case, then the facts that are still contested.
Frameworks and taxonomies
- Taxonomy of Attacks on Open-Source Software Supply Chains, Ladisa, Plate, Martinez, Barais
- Risk Explorer for Software Supply Chains, SAP
- SLSA v1.0 threats and mitigations and supply chain threats overview
- OSC&R launch announcement, OX Security
- OWASP Top 10 CI/CD Security Risks
- Threat Matrix for Kubernetes, Microsoft
- Catalog of Supply Chain Compromises, CNCF TAG Security
- NIST SP 800-204D
- Enhancing Software Supply Chain Security through STRIDE-Based Threat Modeling of CI/CD Pipelines (2025)
- Systematic Review of Identity-Centric Security in Cloud-Native CI/CD Pipelines
- Guidance for the Trivy supply chain compromise, Microsoft
- Trivy compromised by TeamPCP, Wiz
- Trivy supply chain compromise timeline, SafeDep
- Shai-Hulud research note, Cloud Security Alliance
- Dependency Firewall product initiative, GitLab (source for the pre-policy cache gap)
- Package Firewall policy, Endor Labs (source for exceptions that skip every check)
Known cases, by station
- Workstation: CircleCI incident report (2023); s1ngularity post-mortem, Nx, and s1ngularity’s aftermath, Wiz (2025); hackerbot-claw GitHub Actions exploitation, StepSecurity (2026); GlassWorm, Koi Security (2025); Contagious Interview VS Code tasks, OpenSourceMalware, and Void Dokkaebi, Trend Micro; package hallucination study, Spracklen et al. (2024)
- Version control: Bypassing required reviews using GitHub Actions, Cider Security (2021); tj-actions/changed-files alert, CISA (2025); Trivy incident discussion, Aqua Security (2026); Gentoo GitHub incident report (2018); Stolen OAuth user tokens, GitHub (2022); xz Utils disclosure, oss-security (2024); Trojan Source (2021); CAPEC-695 repo jacking; Cross Fork Object Reference, Truffle Security (2024); CVE-2022-36804
- Pipeline definition and runners: Ultralytics attack analysis, PyPI, and zizmor and the Ultralytics injection, William Woodruff (2024); reviewdog/action-setup, Wiz (2025); Codecov security update (2021); AWS-2025-015, AWS (2025); Playing with fire: PyTorch, John Stawinski (2024); CVE-2024-27198; Jenkins advisory 2024-01-24; Artifact poisoning in Rust, Legit Security (2022); ArtiPACKED, Unit 42 (2024)
- Identity and build: GitHub to AWS keyless authentication flaws, Datadog Security Labs (2023); Leaked MSI source code with Intel OEM keys, Binarly (2023); SUNSPOT technical analysis, CrowdStrike (2021); Webmin exploit page and CVE-2019-15107; XcodeGhost, Unit 42 (2015)
- Dependency resolution: GHSA-pjwm-rvh2-c87w, ua-parser-js (2021); Dependency confusion, Alex Birsan (2021); Compromised nightly dependency, PyTorch (2022); colors and faker, Snyk (2022); crossenv malware, npm (2017); event-stream issue 116 (2018); Revival Hijack, JFrog (2024); npm lockfiles as a blind spot, Liran Tal (2019); CVE-2022-23812, node-ipc; The massive hole in the npm ecosystem, Darcy Clarke (2023); kik, left-pad and npm, npm (2016)
- Scanners and provenance: Trivy supply chain attack, Aqua Security, and KICS GitHub Action, Wiz (2026); Malware using NVIDIA’s stolen certificates, BleepingComputer (2022)
- Registries and firewalls: npm debug and chalk compromised, Aikido (2025); Docker Hub database breach, BleepingComputer (2019); PEAR compromise, Rapid7 (2019); Go module proxy caching, Socket (2025); Shai-Hulud v2 spreads from npm to Maven, The Hacker News (2025); StarJacking, Checkmarx (2022)
- Infrastructure, images and runtime: Security smells in IaC scripts, Rahman et al., ICSE (2019); Leaky Vessels, Snyk (2024); Backdoored images removed from Docker Hub, Ars Technica (2018); CVE-2019-5736; CVE-2024-21626; Graboid, Unit 42 (2019)
- Orchestration and delivery: Tesla cloud cryptojacking, Wired (2018); IngressNightmare, Wiz (2025); CVE-2022-24348, Argo CD; 3CX software supply chain compromise, Mandiant (2023); Polyfill supply chain attack, Sansec (2024)
Contested or single-source facts
- The link from the reviewdog compromise to the tj-actions token theft is described by Wiz as likely, not proven.
- Travis CI disputes that its key stolen in the 2022 Heroku attack gave access to customer repositories.
- The motive of the hackerbot-claw account, and any link between it and TeamPCP, are not established.
- The identity of “Jia Tan” in the xz Utils backdoor is unknown, and claims of state sponsorship are speculation.
- GlassWorm’s self-propagation rests on Koi Security’s analysis.
- The Ultralytics cache poisoning is confirmed by PyPI, but the exact poisoning steps are inferred.
- Package hallucination is shown by research; no attack in the wild exploiting a hallucinated name was found.
- Webmin’s own page cites CVE-2019-15231, while NVD records the backdoor as CVE-2019-15107.
- The docker123321 case rests on Kromtech’s analysis as reported by Ars Technica: 17 images pulled more than 5 million times, most carrying cryptominers, and one reported by a GitHub user as backdoored. The roughly $90,000 mined is Kromtech’s estimate from a single wallet address. The report does not say the images were named to pass for official ones; that part of IM·8 is the general pattern, not this case.
- In the Tesla case, Wired reports RedLock’s finding: an unprotected Kubernetes console with a pod holding AWS credentials, used to run a hidden miner. What was exposed is unresolved. Tesla says only internal engineering test cars were affected, while RedLock did not check what the attackers could reach in the S3 bucket. How much was mined is unknown.



