Software Factory Threat Taxonomy

Taxonomies › Software factory

This is the reference for the Software Factory card game: every card’s threat, the mitigation principle a sound design follows, design measures, and mappings to STRIDE, CAPEC and CWE.

The software factory is the machinery that turns source code into running software: developer machines and their agents, version control, pipelines and runners, builds and dependencies, the security controls, registries, infrastructure code, containers, clusters and the path to production. This taxonomy catalogues what can go wrong in it: 221 threats at 17 stations on two production lines, plus ten structural hazards, each with the principle a sound design follows and concrete measures that put it into practice.

Every entry is one of the game’s cards, written out so that it can also be used without the game, and the taxonomy card in the game’s box links here with a QR code. Why the taxonomy exists, and what the existing frameworks miss, is in The Factory Is the Target.

The stations

Overview of the stations and the structural hazards, with each one's prefix, number of entries and scope. Each station is linked in the list below.

Line 1, Source to Artifact

Line 2, Artifact to Runtime

The whole factory

The factory, station by station: Line 1 runs through nine stations from Workstation and Agents to Provenance and Attestation, the artifact crosses over, and Line 2 runs through eight stations from Registries to Delivery and Deployment. Ten structural hazards cover the factory as a whole.

What an entry contains

  • 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.
Anatomy of an entry: PD·J, Unpinned Third-Party Step, with its reference, threat, mitigation principle, three design measures and the public cases it was seen in

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.

How to use it

  1. 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.
  2. Take one station and walk every entry in it against each element it applies to.
  3. For each entry, ask whether the design satisfies the principle. Write down a finding, or “no exposure” and the design decision that defeats it.
  4. 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.
  5. 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.

Each station page shows its entries as a table graphic. The downloads carry the same content as text that can be searched, filtered and copied.

Where stations touch

Some stations touch, and it helps to know which side of the line an entry sits on:

  • Registries and Firewall and Quarantine: the registry is where components live; the firewall decides which of them reach a build.
  • Dependency Resolution and Firewall and Quarantine: resolution decides what is asked for; the firewall decides what is served.
  • Scanners and Gates and Firewall and Quarantine: scanners judge what the factory makes; the firewall judges what comes in from outside. Both stations treat the control itself as a component that can fail or be attacked.
  • Pipeline Definition and Runners: the definition is what the pipeline is told to do; the runner is where it executes and what survives between jobs.
  • Pipeline Identity and Secrets and every other station: Pipeline Identity covers the credentials themselves; each other station covers what a credential lets its component do.
  • Build Systems and Dependency Resolution: the build system runs the build logic and fetches its own plugins; resolution chooses the application’s components.
  • Provenance and Attestation and SBOM and VEX: provenance says how an artifact was made; the SBOM says what is in it. A verifier needs both to be true and both to describe the same artifact.
  • Container Images and Container Runtime: the image is what is packaged; the runtime is how it is contained.
  • Orchestration and Delivery and Deployment: orchestration is the cluster that runs workloads; delivery is the path that puts them there.

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. This taxonomy 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 sources below 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.

Seen in the wild: the number of entries at each station that name a public incident or disclosure, 75 of 231 in all, with the four control stations outlined

STRIDE, CAPEC and CWE

Every entry is mapped to STRIDE and to CAPEC 3.9. STRIDE fits 169 of the 231 entries cleanly and 62 only loosely. CAPEC has a pattern that describes 53 directly, only a generic parent for 146, and nothing for 32. What the mapping shows is in Mapping the Software Factory Threat Taxonomy to STRIDE, CAPEC and CWE. Every entry is also mapped to CWE 4.20, the catalogue of software weaknesses: a CWE weakness names the flaw directly for 126 entries, only a broader weakness applies to 95, and CWE has nothing for 10. Each station page gives its own figures and its mapping table, entry by entry; the Excel, SKOS and STIX downloads carry every mapping as text.

Downloads

DownloadFormatWhat it is for
PDFA4 landscape, a section per station, with each entry’s STRIDE, CAPEC and CWE mappingReading and printing. Also the text version of the tables on these pages.
ExcelWorkbook, one station per sheetFiltering, sorting, copying entries into a threat model, tracking findings.
SKOS (JSON-LD)W3C SKOS concept schemeLinked data: the hierarchy, references, mitigations, and links to STRIDE, CAPEC and CWE.
STIX 2.1STIX 2.1 bundleSecurity tooling: an attack pattern and a course of action per entry, grouped by station, with CAPEC and CWE references.

All four carry the licence. The STIX bundle’s extra fields are described by this JSON Schema.

Licence

© 2026 Jonathan Brett Crawley. This taxonomy is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International licence (CC BY-NC-ND 4.0), with the additional permissions below. You can share the whole taxonomy freely for non-commercial purposes, unchanged and with credit.

UsePermission needed?
Sharing the whole taxonomy non-commercially (OWASP, universities, conferences, individuals)No
Threat modeling with it, including for paying clientsNo
Internal use and training inside any organisationNo
Quoting entries, with credit, in paid courses, reports and talksNo
Shipping the taxonomy in a product: a tool’s built-in library, a printed deck, a reprint for saleYes, ask me

Additional permissions. In addition to the rights the licence gives, and whether or not the use is commercial, the copyright holder grants you permission to:

  • Use the taxonomy to threat model systems you build, operate or assess, including for paying clients;
  • Use it internally, and for training, inside any organisation;
  • Quote individual entries, with credit, in paid courses, reports, findings and talks.

Any other commercial use, including shipping the taxonomy or a substantial part of it in a product (a tool’s built-in library, a printed deck, a reprint for sale), needs written permission. Ask me on LinkedIn.

Credit: “Software Factory Threat Taxonomy” by Jonathan Brett Crawley, ostering.com, licensed under CC BY-NC-ND 4.0.

These additional permissions are given alongside the licence. They add to what the licence allows and do not take anything away from it.

Version

VersionDateChange
1.026 October 2026First published as reference pages, with PDF, Excel, SKOS and STIX downloads. References are stable identifiers.

Corrections, missing threats and worked examples are welcome: reach out to me on LinkedIn. Changes are logged here.

Sources

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

Known cases, by station

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.