Threat Modelling Without the Ceremony

By Davy Rogers

Four questions, asked at design time. No week-long workshops.

Threat modelling has a reputation for week-long workshops and wall-sized diagrams, and that reputation is why most teams never do it. Strip away the ceremony and it comes down to four questions you can ask about any feature in an afternoon.

  1. What are we building?
  2. What can go wrong?
  3. What are we going to do about it?
  4. Did we do a good enough job?

STRIDE, PASTA, attack trees, data flow diagrams: every framework you have heard of is just structure bolted onto those four questions. You can start without any of them.

Doing it by hand

You don't need a tool. Sketch the system on paper: user, browser, API, database, third-party services. Draw arrows for how data moves between them. Then walk each component and ask whether someone could spoof it, tamper with it, read what they shouldn't, take it offline, or use it to gain more access than they're entitled to.

For every threat you find, pick one of four responses: mitigate it, accept it, transfer it, or design it away. Write down which you chose. Check after you have built the thing that you actually did it.

When it's worth doing

Do it while you're still designing, when changing your mind is free. The triggers worth stopping for:

  • A new feature that handles sensitive data
  • A new external integration
  • A change to a trust boundary
  • Any significant shift in the architecture

You do not need to threat model every bug fix. Save it for changes that move the shape of the system.

Speeding up the first draft

The slowest part is getting the first version onto paper, and that part you can hand to a coding agent. The JustAppSec threat model editor generates a prompt for whatever agent you already use (Copilot, Claude, Cursor). The agent reads your code and produces a plain JSON file you can open back in the editor: open threats, the mitigations already in place, severities, attack scenarios, and the component paths each threat affects.

What you get is a starting point, not an answer. The part the AI can't do is apply judgement. Update statuses, assign owners, close the threats you have handled, and push back on the ones it got wrong.

Whichever way you produce the model, commit it to the repository. Now it versions with the code: when the design changes, you update the affected threats alongside the change, and a reviewer can see exactly what the security thinking was at the time. You can automate that step too, with CI proposing threat model updates when the code moves underneath it. See automated threat model updates with GitHub Actions.

Where teams go wrong

  • Boiling the ocean. Model the thing you're changing, not the entire estate.
  • Only picturing external attackers. Insiders, a compromised dependency, and misconfigured infrastructure are threats too.
  • Stopping at the list. Finding threats is worthless unless you decide what to do about each one.
  • Treating it as a one-off. A model is a snapshot. Revisit it when the system moves.

Start with the four questions on paper this afternoon. Bring in tooling when you want the model to live alongside the code. Either way, you catch design-level flaws before a single line of vulnerable code exists.