TMGoat

July 10, 2026 · View on GitHub

TMGoat is two things at once:

  • a dojo for threat-modeling engineers — graded challenges with reference solutions, hints, and a skills path;
  • a benchmark for threat-modeling tools — a scored harness with a published reference baseline.

This guide is the engineer's playbook. New to threat modeling? Start here, then open any fixture's README.md.

The method: Shostack's four questions

  1. What are we building? Read inputs/. Identify components, data, and trust assumptions. Sketch a data-flow diagram (DFD) and mark the trust boundaries.
  2. What can go wrong? Apply STRIDE (Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Elevation of privilege) to each element and each flow. Then go beyond the checklist: hunt authorization gaps, trust-boundary violations, business-logic flaws, and chained attack paths.
  3. What are we going to do about it? Propose a mitigation per threat; map it to a control/standard (NIST 800-53, PCI DSS, IEC 62443, …).
  4. Did we do a good job? Compare against solution/ after you attempt. Did you find the planted design threats? Did you avoid the documented false positives?

How to work a challenge

  1. Open the fixture's README.md — scenario, your task, and how many planted threats to find.
  2. Analyze inputs/ (diagrams, docs, code, IaC). The truth is in the code and IaC; the docs may be aspirational — and in adversarial fixtures they are deliberately wrong, so reconcile them.
  3. Decompose → enumerate threats → propose mitigations.
  4. Stuck? hints.md gives three graduated nudges.
  5. Score yourself (below), then read result/threat-model.md (the reference) and solution/threat-model.yaml (the answer key).

Scoring — humans and tools, same rule

Put your findings in a JSON list [{ "title": "...", "stride": ["T"], "target": "<component>" }] and run:

python harness/score.py --expected fixtures/<sector>/<tier>/solution/threat-model.yaml --findings your-findings.json
  • Recall — of the planted design threats, how many you found (the headline metric).
  • Precision — did you avoid noise and the documented false positives.
  • Belts: Bronze = all planted found · Silver = + the chained/subtle threat · Gold = + mitigations mapped to standards + residual risk.

What's in each fixture

File / folderWhat it is
README.mdthe challenge brief + learning objectives
inputs/what you analyze — diagrams/ docs/ code/ iac/
hints.mdthree graduated hints
solution/threat-model.yamlthe answer key (planted threats + mitigations + standards) — don't peek early
result/the reference threat model (the model answer) + dfd.png + its score.json

The one idea to internalize

Difficulty here is subtlety, not size. A 6-component app can hide a nastier flaw than a 30-component one. Tools (and juniors) that just run STRIDE on each box miss the race condition, the fail-open control, the over-trusted channel, the doc that lies about the code. Those design threats are where the points — and the real risk — live.