Spec Kit extension · open source

Know how you will be attacked before you write the code.

AttackTree turns your spec into an attack tree: who attacks, what they want, and every path that gets them there. It simulates which security controls actually cut those paths, writes them into the spec as testable requirements, and verifies each one with evidence after implementation.

specify extension add attacktree --from https://github.com/hupe1980/spec-kit-attacktree/archive/refs/tags/v0.1.0.zip

Requires Spec Kit ≥ 1.0 and Python 3.11+ with PyYAML or uv. Works with Claude Code, Copilot, Cursor, Gemini, and every other Spec Kit agent.

An attack tree from the shipped exampleThe goal "read restricted documents" needs two steps (AND): get restricted content into the model context, and get it out. Each step has alternatives (OR). The most likely path, asking directly and having the answer quote the document, reaches 59.5 percent. One control on the choke point cuts every path.Read restricted documentsgoal · critical impact · ANDGet it into the contextOR · choke pointGet it outORAsk directlyemployee · 70 %Poison contentauthor · 65 %Quote in answeremployee · 85 %Paste in a ticketoutsider · 45 %visibility filterMost likely path 70 % × 85 % = 59.5 % → critical riskOne control on the choke point cuts every path · simulate --apply proves it

Threat lists tell you what can go wrong. Attack trees tell you how.

Rank by the path, not the finding

An attacker takes the easiest route to what they want. The tree finds that route per attacker profile, so a trivial insider step outranks an elaborate exploit nobody would try.

Spend on the choke point

Some nodes sit on every path to a goal. One control there does more than five controls on the leaves. The simulation names those nodes and the controls your defence depends on alone.

Verify, don't assume

Controls become CR-### requirements with Given/When/Then acceptance. After implementation, residual risk is recomputed from verified controls only, including measured bypass rates for guardrails.

“One of the surprising things that comes out of this kind of analysis is that the areas people think of as vulnerable usually aren't.”

Everything an attack tree workshop produces, inside your repository

Actors, goals, AND/OR paths

Threat actors with skill, resources, access, and risk appetite. Goals with business impact. Leaves rated by complexity, cost, and likelihood, filtered by who can actually run them.

Simulation you can act on

Most likely and cheapest path per actor, choke points, single points of failure, what-if for every inactive control, a cost-ranked roadmap, and a seeded Monte Carlo.

Requirements in the spec

Controls become CR-### control requirements in spec.md, so planning and task generation treat them like any functional requirement.

16 deterministic checks

Dangling references, uncontrolled paths, controls without requirements, requirements without tasks or evidence, expired risk decisions, drift. Markdown, JSON, or SARIF.

Evidence-based convergence

Every requirement is judged from tests, reviews, or micro attack simulations. Verified status, bypass rates, and gaps flow back into the tree and into tasks.md.

Built for agentic systems

An agentic profile with five attack-surface zones, vectors mapped to OWASP Top 10 for LLM and Agentic Applications 2026 and MITRE ATLAS, and probabilistic controls.

Four commands along the Spec Kit lifecycle

  1. 1

    /speckit-attacktree-model

    After /speckit-specify: the agent builds attack-tree.yaml and publishes control requirements into the spec. After /speckit-plan: a second pass pins attacks and controls to real files.

  2. 2

    /speckit-attacktree-simulate

    Residual risk per goal, choke points, single points of failure, and a roadmap of controls ranked by risk reduction per cost. The team picks what to build.

  3. 3

    /speckit-attacktree-check

    After /speckit-tasks: every path has a control, every control a requirement, every requirement a task. Findings as Markdown or SARIF.

  4. 4

    /speckit-attacktree-converge

    After /speckit-implement: evidence per requirement, verified controls, residual risk from what was proven, and remediation tasks for the gaps.

See the full workflow →

Real output, not a dashboard mock-up

This is the simulation of the shipped example, an internal assistant that answers questions from a knowledge base and opens support tickets, with every control still only proposed. Four goals block; one node is the choke point for the critical one; one control is the quick win.

Everything here comes from a single command that also runs in CI:

attacktree.sh simulate --scenario current

Reproduce it in five minutes →

Goal                            Impact    Likelihood  Risk
goal.read-restricted-documents  critical  59.5 high   critical
goal.abuse-ticket-credential    high      80.0 v-high critical
goal.poison-answers             high      80.0 v-high critical
goal.impersonate-employee       high      75.0 v-high critical
goal.forge-ticket               high      55.0 high   high
goal.deny-service               medium    85.0 v-high high

Uncovered choke point
  goal.read-restricted-documents → node.rrd-reach

What-if, best first
  1 control.visibility-filtered-retrieval  quick win
  2 control.reporter-from-session          quick win
  3 control.rate-and-size-limits           quick win
  8 control.ticket-confirmation            defence in depth
Condensed from security/attacktree-simulation.md of the example.

Gate pull requests on residual risk

The bundled GitHub Action runs the checks and the simulation, uploads findings to code scanning as SARIF, and can fail the build while a goal stays at blocking risk.

CI guide →

- uses: hupe1980/spec-kit-attacktree@v0.1.0
  with:
    feature-dir: specs/007-agent-assistant
    scenario: current
    fail-on-blocking-goals: "true"

Built on published methods and open standards

  • SchneierAttack trees, 1999
  • SchneiderScenario-driven attack trees
  • MITRE CAPECAttack patterns
  • MITRE ATLASAI attack techniques
  • OWASP ASVSControl references
  • OWASP Top 10 2026LLM and Agentic Applications
  • Open Threat ModelImport
  • SARIF 2.1.0Code scanning

Questions

What is an attack tree?

A diagram of how an attacker reaches a goal, introduced by Bruce Schneier in 1999. The goal is the root, the ways to reach it are the branches, and concrete attacks are the leaves. OR nodes are alternatives, AND nodes are steps that all have to succeed. Rate the leaves and the tree tells you which attack is the most likely, the cheapest, and which single defence blocks the most paths.

How is this different from STRIDE or a threat list?

A threat list tells you what can go wrong per component. An attack tree tells you how an attacker gets from where they start to what they want, so it can rank threats by the path an attacker would really take and show where one control covers many paths. The two complement each other; AttackTree can seed its goals from any Open Threat Model file.

Do I need an LLM to run the checks and the simulation?

No. The engine is a single Python script that needs only PyYAML. Checks, simulation, Monte Carlo, and SARIF output run without an agent, so they work in CI. The coding agent builds the tree from your spec and judges evidence; the engine does all the arithmetic.

Which coding agents does it work with?

Every agent Spec Kit supports, including Claude Code, GitHub Copilot, Cursor, Gemini CLI, opencode, and Codex. Spec Kit renders the four commands for the agent you initialised the project with.

Can I import the tree into attacktree.online?

Not yet. attacktree.online does not publish a schema for its file format, and AttackTree only writes formats it can validate. An exporter is on the roadmap for when the format is specified. The modelling vocabulary is the same: actors, goals with impact, AND/OR paths, controls with effect and cost.

Is it free?

Yes. AttackTree is open source under the MIT license.

Model your first attack tree today

Install the extension, run one command after /speckit-specify, and read the simulation.