Threat Modelling Is Design Work, Not Review Work

A system diagram beside a dashed trust boundary, with each crossing flow marked

There is a moment in the life of a system when a threat model is worth something, and it is earlier than almost anyone runs one.

The moment is while the diagram is still a whiteboard sketch and somebody can still say “actually, let’s not put the queue there” without a migration plan. Once the queue is deployed, the credentials are provisioned, three services are talking to it and a dashboard depends on its metrics, the same observation becomes a finding. Findings go into a backlog. Design decisions go into the system.

That gap — between a remark that changes an arrow and a ticket that waits behind forty others — is the entire difference between threat modelling as a practice and threat modelling as a compliance artefact.

The four questions do most of the work

The framing that has held up best across every methodology is deliberately plain. What are we building? What can go wrong with it? What are we going to do about that? And did we do a decent job of asking?

None of those questions requires a taxonomy, a tool, or a certification. What they require is a room containing the people who know how the thing actually works, a drawing they all agree with, and enough time to be wrong out loud. Teams that never get past the first question — because nobody can produce a diagram the whole team endorses — have already learned something valuable, and usually something uncomfortable.

Draw the flows, not the org chart

The most common way a modelling session fails is that the drawing is a component inventory. Boxes labelled with service names, lines meaning “these two talk”. A diagram like that supports almost no analysis, because the interesting question is never do these components communicate — it is what crosses between them, under whose authority, and who could interpose.

A useful drawing carries three things a component inventory lacks. It shows the direction and content of each flow: not “auth service ↔ database”, but “a bearer token, minted here, validated there, cached in between”. It shows where data comes to rest, because storage has a different threat profile than transit. And it shows the trust boundaries — the lines across which the assumptions change.

Trust boundaries are the unit of analysis. Everything inside one shares an assumption; everything crossing one is where the assumption gets tested. When a team argues for twenty minutes about whether a particular line is a trust boundary, that argument is the session doing its job. Somebody in the room believed the network was a boundary and somebody else was writing code as though it were not.

The assumptions are the deliverable

Ask most teams what a threat model produced and they will show you a list of threats. Ask them six months later which of those threats they remember and they will show you nothing.

The durable output is different: it is the list of things the design depends on being true. This queue is reachable only from within the private subnet. The client never sees the signing key. Nobody but the platform team can attach an IAM role to this compute. Our upstream validates the schema before we get the payload.

Assumptions written down like that have a property that threat lists do not. They can be checked — by a test, by a config scan, by a person reading a terraform diff a year later. And when one of them breaks, the breakage is legible. “The queue became reachable from the corporate VPN” is a sentence that tells you exactly what to reassess, because the model already recorded what was resting on it.

This is also the honest answer to the question of how a threat model stays current. It does not, and it does not need to. What stays current is the set of assumptions, each of which can be revalidated cheaply and independently.

Stop before the taxonomy takes over

Structured prompts — spoofing, tampering, repudiation, information disclosure, denial of service, elevation of privilege — are genuinely useful, in the same way that a checklist is useful during a landing. They stop a room from converging on the one threat everybody finds interesting and missing the four boring ones.

They stop being useful the moment they become an obligation. Walking every prompt across every arrow in a system of any size produces a matrix nobody reads, consumes the session’s energy on cells where the answer is obviously “not applicable”, and trains the participants to associate threat modelling with tedium. The next session is harder to schedule than the last one, and eventually there is no next session.

The discipline is to run the prompts at a resolution matched to the decision at hand. On the two or three flows that cross a real boundary and carry something worth having, go through all of them slowly. Elsewhere, one pass and move on. A model that stops early and gets repeated beats an exhaustive one that happens once.

Cheap enough to redo

Everything above depends on the exercise being cheap. If a threat model costs two weeks and produces a forty-page document, it will be done once, at the point in the project where it is least useful, by whoever has capacity rather than whoever has knowledge.

The cheap version looks like this: an hour, a drawing, five or six people including at least one who will implement it, a note-taker who writes down assumptions and decisions rather than prose, and an explicit list of things the room decided not to address and why. That last list is the most professional part of the output and the part most often omitted. “We accepted that a compromised build agent can sign artefacts, because segregating it costs more than the exposure, and we will revisit if the agent starts handling third-party code” is a real security decision, recorded, with a trigger for reopening it.

What changes when it moves left

A programme that runs modelling at design time and one that runs it at review time produce superficially similar artefacts and completely different outcomes.

At review time, the model’s output is a risk register: a list of things that are wrong, owned by nobody in particular, competing with feature work. At design time, the output is a set of constraints that the implementation simply satisfies, because they were present before the code was. Nobody files a ticket to put the queue in the private subnet; it was never anywhere else.

The signal that a team has made the transition is not that they produce better documents. It is that they start having the argument earlier — someone sketches an architecture and a colleague says “wait, what crosses that line?” before anyone has opened an editor. At that point the practice has stopped being a process and become a habit of thought, which is the only form of it that survives a reorganisation.