Written by
Halkwinds Editorial Team
Halkwinds Research & Editorial

Engineering Security by Design: Threat Modelling Basics
How to integrate threat modelling into the engineering process — STRIDE, attack trees, and the practical ceremonies that surface real risks.
Most security incidents are not the result of a novel zero-day or a nation-state adversary. They come from ordinary design decisions that nobody scrutinised: an internal API that trusts its caller, a token that never expires, a queue that anyone on the network can write to. Threat modelling is the discipline of finding those decisions before they ship — and it is one of the highest-leverage security investments an engineering team can make. This article is a practical guide for engineering managers who want to embed threat modelling into their delivery process without turning it into a bureaucratic checkpoint. We'll cover STRIDE, attack trees, tooling like the Microsoft Threat Modeling Tool and OWASP resources, and the lightweight ceremonies that surface real risk.
- Background / Why This Matters
- Core Concepts and Architecture
- Implementation Strategy
- Scaling and Operational Considerations
- Common Mistakes / What to Avoid
- Frequently Asked Questions
- Conclusion
Background / Why This Matters
"Security by design" is a phrase that gets repeated in compliance decks until it loses meaning. In practice it means one thing: security requirements and threats are considered during design, not bolted on after code review or — worse — after an incident. Threat modelling is the concrete practice that makes security by design real.
The economic argument is well established. Fixing a design flaw during architecture is far cheaper than fixing it in production, where you're dealing with data migrations, coordinated deployments, customer communication, and possibly breach notification. Research from the software engineering community has consistently suggested that defects caught earlier cost dramatically less to remediate — and security defects are especially expensive because they carry regulatory and reputational tails.
For an engineering manager, there are three specific pain points threat modelling addresses:
- Security feels like someone else's job. Without a structured practice, developers assume the security team owns risk, and the security team assumes developers understand the system. Threat modelling forces a shared conversation.
- Pen tests come too late. An annual penetration test finds problems weeks or months after the design is frozen. Threat modelling shifts that discovery left, into design reviews.
- You can't prioritise what you can't see. Teams drown in vulnerability scanner output because they have no model of what actually matters. A threat model gives you a map of your real attack surface.
Takeaway: Threat modelling is not a security-team activity you outsource. It is an engineering activity that produces a shared understanding of how your system can be attacked — and it belongs in your design process alongside API contracts and data models.
Core Concepts and Architecture
At its heart, threat modelling answers four questions, popularised by Adam Shostack and adopted by OWASP:
- What are we building? (Usually a data flow diagram.)
- What can go wrong? (Systematic threat enumeration.)
- What are we going to do about it? (Mitigations.)
- Did we do a good enough job? (Review and validation.)
Data Flow Diagrams and Trust Boundaries
You cannot reason about threats without a model. A data flow diagram (DFD) shows external entities, processes, data stores, and the flows between them. The most important element is the trust boundary — the line where the level of trust changes, such as between the public internet and your API gateway, or between your application and a third-party payment provider. Most interesting threats live on trust boundaries.
STRIDE
STRIDE is Microsoft's mnemonic for six threat categories. It is the most widely used enumeration framework because it maps cleanly onto DFD elements.
| Letter | Threat | Property violated | Example |
|---|---|---|---|
| S | Spoofing | Authentication | Attacker impersonates a legitimate user or service |
| T | Tampering | Integrity | Modifying data in transit or at rest |
| R | Repudiation | Non-repudiation | A user denies performing an action, no audit trail exists |
| I | Information Disclosure | Confidentiality | Leaking PII through an over-permissive API response |
| D | Denial of Service | Availability | Unbounded query exhausting the database |
| E | Elevation of Privilege | Authorization | A standard user reaching an admin endpoint |
You apply STRIDE element by element: for each process, data store, and flow, ask which of the six categories apply. A data store, for instance, is naturally exposed to Tampering, Information Disclosure, and Denial of Service, but not Spoofing.
Attack Trees
Where STRIDE is broad and systematic, attack trees are deep and goal-oriented. You place an attacker's objective at the root — say, "exfiltrate customer credit card data" — and decompose it into the sub-goals and steps required to achieve it. Branches are joined with AND/OR logic. Attack trees are excellent for high-value assets and for communicating risk to non-technical stakeholders, because they read like a story.
Choosing a Method
| Approach | Best for | Effort |
|---|---|---|
| STRIDE per element | Systematic coverage of a new service or feature | Medium |
| Attack trees | Deep analysis of one critical asset or scenario | High |
| OWASP Application Threat Modeling / lightweight card-based games | Team learning and fast iteration | Low |
Takeaway: Start with a DFD and trust boundaries, use STRIDE for breadth, and reach for attack trees when a specific high-value asset justifies deeper analysis. Don't treat these as competing — they complement each other.
Implementation Strategy
The failure mode for threat modelling is turning it into a heavyweight, once-a-year document nobody reads. The goal is a repeatable, lightweight ceremony that fits inside your existing delivery cadence.
1. Pick the right trigger
Threat model when the design changes materially, not on a fixed calendar. Good triggers include: a new service, a new trust boundary (a new third-party integration), a change to authentication or authorization, or handling a new class of sensitive data. Tie the ceremony to your existing design review or RFC process.
2. Run a focused session
A good threat modelling session for a single feature runs 60–90 minutes with four to six people: the feature's engineers, a product owner, and ideally someone with security depth. Agenda:
- Draw or review the DFD on a shared whiteboard (Miro, Excalidraw, or a diagram in the repo).
- Mark trust boundaries in a bright colour.
- Walk each element through STRIDE, capturing threats as you go.
- Rank threats and assign mitigations as tickets.
3. Use tooling to lower friction
The Microsoft Threat Modeling Tool is free and generates STRIDE-based threats automatically from a DFD you draw — a good starting point for teams new to the practice. OWASP Threat Dragon is an open-source alternative that stores models as JSON alongside your code, which makes it version-controllable and reviewable in pull requests. The OWASP Threat Modeling Cheat Sheet and the pytm library (threat models as Python code) are useful when you want the model to live in the repo and evolve with the system.
4. Turn threats into tracked work
A threat model that doesn't produce backlog items is theatre. Every accepted threat should result in one of three outcomes: a mitigation ticket, an accepted-risk decision recorded with a named owner, or a "won't fix" with justification. Link these back to the model so the trail is auditable.
When Halkwinds builds custom applications and cloud infrastructure for clients, we embed exactly this loop into the delivery workflow — threat models are stored in the repository next to the architecture decision records, so security reasoning is versioned alongside the code it protects.
Takeaway: Trigger on design change, timebox the session, use free tooling like the Microsoft Threat Modeling Tool or OWASP Threat Dragon, and convert every threat into a tracked decision.
Scaling and Operational Considerations
A single team can adopt threat modelling in a week. Scaling it across an engineering organisation is where most managers struggle.
Build champions, not gatekeepers
You will not have enough security specialists to attend every session, and you shouldn't try. The scalable model is a security champions programme: one engineer per team receives deeper training and facilitates threat modelling for their squad. The central security function trains, provides templates, and audits a sample of models rather than reviewing every one. This keeps threat modelling in the hands of the people who know the system best.
Templates and reusable threat libraries
Most teams re-derive the same threats: JWT handling, S3 bucket permissions, SQL injection, SSRF in outbound requests. Build a reusable threat library — a checklist of "threats we always consider for a web API" — so sessions focus energy on what's genuinely new. OWASP's Application Security Verification Standard (ASVS) is an excellent backbone for these libraries.
Living models and drift
Systems change; models rot. Two practices keep models alive: storing them as code (Threat Dragon JSON or pytm) so they diff in pull requests, and adding a "threat model reviewed?" checkbox to significant PR and RFC templates. The model should be a living artefact, not a PDF in a wiki graveyard.
Connect to detection and response
Threats you decide not to fully mitigate should feed your monitoring. If you accept the risk of credential stuffing but rely on rate limiting and alerting, that alert belongs in your observability stack. This closes the loop between design-time threat modelling and runtime security operations.
Takeaway: Scale through champions and reusable threat libraries, keep models in version control so they stay current, and wire un-mitigated threats into your monitoring so the model has operational consequences.
Common Mistakes / What to Avoid
- Boiling the ocean. Trying to threat model an entire monolith in one sitting produces exhaustion and nothing actionable. Scope to a feature, a service, or a single data flow.
Explore Further