Key takeaways
- Model meaningful changes, not every ticket.
- Focus on assets, trust boundaries, abuse paths, and failure states.
- Convert threats into owned controls and executable tests.
- Schedule reviews on triggers: new identity, new vendor, new async money path.
- Keep the model next to the service docs so incidents can update it.
Model decisions while they are still cheap
The best time to discover that a refund workflow can be replayed is before three services and a queue depend on it. Threat modeling is a structured design conversation that makes hidden security assumptions visible while changing them is inexpensive.
It should not become a diagram ceremony. The output is a set of decisions: what must be protected, who or what can influence it, how the system could be abused, which control changes that path, and how the team will verify the control.
If the session produces only a slide, it failed. If it produces a named owner, a backlog item, and a test idea, it succeeded—even if the whiteboard photo is ugly.
Use four questions
Begin with the smallest useful system view and ask four questions. What are we building? What can go wrong? What will we do about it? How will we know the mitigation works? This keeps the exercise grounded in delivery and creates a direct bridge from design to tests.
You do not need STRIDE on the first pass. Frameworks help when the room is stuck. They hinder when the room spends the hour classifying instead of deciding. Start with assets and abuse; add a mnemonic only if coverage is thin.
Time-box the first pass to thirty or forty-five minutes. A shorter habit that happens on real changes beats a quarterly offsite that nobody can schedule twice.
- Name high-value assets and consequential operations.
- Draw data flows and first- and second-order trust boundaries.
- Describe plausible abuse and failure paths.
- Assign a control, owner, test, and review trigger.
Do not ignore partial failure
Distributed-system threats frequently live between success and failure. A request times out after a payment succeeds, a worker retries after its acknowledgement is lost, a policy service becomes unavailable, or a signing key rotates unevenly. Ask what an attacker gains by deliberately causing each component to be slow, unavailable, duplicated, or stale.
This is where idempotency, replay prevention, fail-closed behaviour, durable state transitions, and reconciliation controls emerge as security requirements rather than reliability afterthoughts.
Write the unhappy path in the model: “payment captured, fulfillment not recorded.” Then ask who can trigger that state on purpose and what the system does when it sees the same request twice. Many “logic bugs” are unmodeled retries.
A compact example: checkout and refund
Consider a checkout service that captures a payment, enqueues fulfillment, and later accepts a refund request from a signed-in customer. Assets include payment instruments, order state, and the ledger. Trust boundaries include the browser, the API, the payment provider, and the worker that reads the queue.
Abuse and failure paths worth naming: replay of a captured refund, a customer who changes the order identifier, a worker that processes a message twice, a webhook the provider retries, and a policy lookup that fails open so refunds succeed during an outage.
Controls then become specific: server-side order ownership, idempotency keys stored with the ledger, fail-closed refunds when policy is unavailable, and a reconciliation job that treats provider truth as the audit source. Each control should have a test the team can run without a workshop.
Choose review triggers
Continuous threat modeling does not mean meeting continuously. Define triggers that justify revisiting the model: a new external integration, a new data classification, a privilege boundary change, a public endpoint, a major authentication change, or a material incident. Smaller changes can use a pull-request security prompt.
Publish the trigger list in the service README. New teammates should not have to guess whether “adding a partner webhook” is a modeling event. It is.
After an incident, the first documentation update should be the model, not only the ticket. The missed assumption is the institutional memory. If it lives only in Slack, the next team will rediscover it the hard way.
- New identity or authorization model.
- New third-party or cross-tenant data flow.
- New asynchronous or retryable transaction.
- Material change to secrets, keys, or payment handling.
- Incident showing an assumption was wrong.
Make the model operational
Store the model beside the architecture or service documentation, not in a forgotten workshop folder. Link threats to backlog items and tests. Give accepted risks an owner and expiry. During incident review, update the model with the newly learned path. A living model becomes institutional memory; a static diagram becomes decoration.
Accepted risk is not a failure of the exercise. An undocumented accepted risk is. Write the residual exposure, the compensating control, who lives with it, and when it will be revisited.
If your organization uses a thinking pad or architecture decision record, attach the four answers there. Tools matter less than the habit of answering in writing where the next on-call engineer will look.
How to run the room
Invite the people who will implement and operate the change: a developer, someone who owns the data, and—if the change crosses a trust boundary—an AppSec or champion. More than six people usually turns the session into a status meeting.
Start with a single diagram of now-plus-change, not a complete enterprise landscape. Time-box “what can go wrong” so the group spends equal time on “what we will do.” End by reading back owners and test ideas. If nobody can repeat the top three threats, the notes are not done.
Facilitators should punish jargon, not curiosity. “Confused deputy” can be restated as “this service will act on a tenant ID it did not authenticate.” The second sentence is the one that becomes a control.
Put it into practice
Build threat-modeling judgement
Use Thinking Pad to capture assets, boundaries, abuse cases, controls, and reviewable engineering decisions beside the work.
Start practicing