August 27, 2026
A Practical Guide to Perform Threat Modeling
Designing and implementing a system requires knowledge of what needs protection, who might pose a threat, and how severe such a threat…

By _m1le5
7 min read
Designing and implementing a system requires knowledge of what needs protection, who might pose a threat, and how severe such a threat could be. Without it, it's difficult to manage and make confident statements regarding the security level of any system.
This is why, to build a secure system, there needs to be a detailed threat assessment carried out.
Threat modeling is the process of reasoning about how an adversary could compromise something of value. It does this by identifying realistic attack paths through a system.
To perform a threat assessment properly, we must understand:
- How the system works.
- What it protects.
- What it trusts.
- How an attacker could exploit those trust assumptions.
At its core, threat modelling answers two questions:
- How could an attacker realistically reach a valuable asset?
- Would the existing controls prevent, detect, or hinder them?
There are generally two approaches:
- Threat-centric: Start with known attacker techniques and determine whether they apply to the system (e.g., STRIDE).
- Asset-centric: Start with something valuable and work backwards to determine how an attacker could realistically reach or compromise it.
Both approaches complement each other. In practice, the asset-centric approach is often a good starting point because it naturally focuses the assessment on what matters most to the business.
To begin, first think like an adversary. Identify realistic paths to an objective; whether that is getting hold of valuable data, a critical component, an authentication token, or a privileged account.
Then think like a defender. Determine what prevents, disrupts, or detects those paths.
Attack Chains
Successful attacks rarely occur in a single step. Adversaries typically follow a sequence of actions before achieving an objective such as data theft, corruption, or ransomware deployment.
For example, after obtaining Remote Code Execution (RCE), an attacker may attempt to:
- Establish a Command-and-Control (C2) channel to maintain access
- Download tooling
- Find credentials or other useful information
- Move towards valuable systems
- Exfiltrate data
Controls at any of these stages can make the attack harder.
For example, if command-line tools are restricted, privileged access is tightly controlled, and outbound connections are allow-listed and monitored, the attacker may need to find another way to communicate externally, such as DNS tunnelling.
The attack may still be possible, but it has become harder, slower, and more likely to be detected.
Threat modeling follows the same principle: identify the attack chain and determine where it can realistically be prevented, disrupted, or detected.
Keep It Risk-Based
You are not trying to find every possible attack path. You do not have infinite time, and not every theoretical attack deserves the same attention. You want to identify the attack paths that matter most.
Prioritize based on:
- Which assets have the greatest business value?
- Which attacks would cause the greatest business impact?
- Which attack paths are realistic?
- Which assumptions, if broken, would significantly weaken the system?
These questions help determine where the assessment should focus.
Practical Procedure
- Understand the system.
- Identify valuable assets.
- Identify trust boundaries.
- Identify trust assumptions.
- Build attack paths and validate their assumptions.
- Evaluate existing controls.
- Determine residual risk.
Step 1 — Understand the System
Before looking for threats, understand how the system actually works.
Ask yourself:
- What does the application do?
- What are its major components?
- Where do the valuable assets reside?
- How does data flow through the system?
- What are the entry points?
- Who are the users and system identities?
- What external systems does it depend on?
For example, you should be able to look at an architecture and explain something like:
Internet → API Gateway → Backend Service → Database
You should understand what crosses each connection, which identity is used, and which component makes the security decision.
If you do not understand how the system works, you cannot reliably reason about how it could be attacked.
Once you understand how the system operates, the next question becomes: What would an attacker actually want from it?
Step 2 — Identify the Valuable Assets
Identify what an attacker might want to obtain, manipulate, destroy, or control.
Examples include:
- Customer data
- Authentication tokens
- Service identities
- Secrets
- Financial transaction
- Administrative privileges
Not every asset has to be the attacker's final objective. Some assets are stepping stones.
For example:
Service credential → Database access → Customer data
The credential may not be the attacker's real objective. It is valuable because it enables the next step of the attack.
Once you understand what the attacker wants, or what they need along the way, look at where trust changes throughout the architecture.
Step 3 — Identify the Trust Boundaries
A trust boundary is a point where data, identities, or commands move between components with different levels of trust.
Examples:
- Internet ← → API Gateway
- Gateway ← → Backend
- Backend ← → Database
- Azure DevOps ← → Production
- Internal Service ← → Kafka Event Bus
Trust boundaries are where authentication, authorization, validation, encryption, and access control become security-critical, because information crossing a boundary should not automatically be trusted.
This is where controls such as the following will become important:
- Authentication.
- Authorization.
- Input validation.
- Encryption.
- Network restrictions.
- Access control.
For every boundary, ask:
What crosses this boundary, and why does the receiving side trust it?
Once trust boundaries are identified, determine what assumptions the application makes about the components on either side.
Step 4 — Identify the Trust Assumptions
Every system relies on assumptions.
When you start your car, you trust the ignition system to work.
When you board a plane, you trust that the aircraft systems function correctly and the pilots remain in control.
Applications are no different.
Ask: Which assumptions must remain true for the system to remain secure?
Examples:
- JWTs have already been validated by an upstream component.
- Consumed events from Kafka event producers publish legitimate events.
- Internal services only receive authenticated traffic.
- Azure DevOps pipelines cannot be modified by unauthorized users.
These statements are security assumptions.
Now challenge them.
What happens if this assumption is false?
For example:
"The backend trusts that JWTs have already been validated by the gateway."
Ask:
"Can the backend be reached without going through the gateway?"
If yes, the assumption may no longer be safe.
Many successful attacks do not require breaking a security mechanism; they invalidate an assumption the system depends on.
Once you know what the attacker wants, where trust changes, and what the system assumes, you can start building attack paths.
Step 5– Build Attack Paths & Validate Assumptions
Every attack path starts as a hypothesis.
Start with something valuable and work backwards.
Suppose the attacker's objective is: Steal customer data
Work backwards: Customer data
↓ Database
↓ Need an identity authorized to access the database
↓ Need to compromise a service identity with database permissions used by the API
↓ Need Remote Code Execution (RCE) via the API communicating with the database as that service identity
↓ Need API vulnerability that leads to RCE
↓ Need to find a user-controlled input that can interpreted as executable by the API or backend rendering it.
Now, validate (prove yourself wrong) every step with the word "need" in the attack path.
For each step, ask:
- What must be true?
- Is that assumption actually true?
- Can it be verified?
For example, an attack path that requires Remote Code Execution (RCE) depends on a few conditions:
- There needs to be a server side runtime/ a backend component
- User-controlled input reaching it
- A vulnerability that executes code
If any required precondition is false, that attack path breaks.
So, by decomposing attack paths into prerequisites, you can identify the assumptions an attacker depends on and determine where controls can be introduced to prevent, detect, or disrupt the attack.
Continue validating assumptions until the attacker reaches the objective, or the required assumption no longer holds.
If one attack path fails, ask whether the attacker can reach the same objective another way.
Example:
- Steal credentials from the CI/CD pipeline.
- Abuse excessive permissions.
- Extract secrets from logs.
- Brute-force credentials.
Aways consider different attacker perspectives:
- External attacker
- Compromised employee
- Compromised internal service
Useful questions:
- Can an attacker interact directly with a component without going through a control?
- What would an attacker need to do to defeat an existing control?
- How difficult would that actually be?
The goal is not to list vulnerabilities.
The goal is to determine whether a realistic attack chain exists that reaches something valuable.
Once a realistic attack path has been determined, switch perspectives.
Step 6 — Switch to the Defender's Perspective
Ask: What breaks this identified attack chain?
Look for controls that prevent, detect, delay execution.
Examples include RBAC, mTLS, network segmentation, input validation/sanitization/output encoding, secret management, logging and monitoring, and rate limiting.
Ideally, controls should be layered across multiple areas such as identity, communication, infrastructure, and application security. This way, if something were to slip, you could catch it here and there.
Note that any security control is only as effective as its implementation. For example, simply stating that RBAC exists provides little assurance. If permissions are overly broad, compromising a single account may still provide sufficient access for lateral movement or privilege escalation.
Finally, ask one additional question: Can the intended functionality, or even the security controls themselves, be abused?
Attackers do not always require an exploit. In many cases, legitimate functionality can be abused to achieve an objective in a way the system designer never intended.
The final outcome of threat modelling is an understanding of residual risk, the risk that remains after existing controls have been evaluated.
Not every attack path can be eliminated, so the objective is to determine whether the remaining risk is acceptable to the business.
Final Advice: Weak vs Good Threat Identification
A weak threat model lists vulnerabilities such as:
- SQL Injection
- Cross-Site Scripting
- Broken Authentication
These are simply vulnerability names. By themselves, they provide little insight into how an attacker could realistically achieve an objective.
A good threat model explains:
- What the attacker wants
- How they get there
- Which assumptions make the attack possible
- Which controls exist
- Whether those controls are sufficient
For example, it puts "an attacker exploits a SQL injection vulnerability in the public API, extracts service credentials, authenticates as the backend service, and gains unauthorized access to customer transaction data."
A good threat model tells a coherent story about how an attacker could realistically progress from an initial capability to a valuable objective, and whether the system's defences are capable of stopping them.
With well-constructed threat scenarios, these questions can be answered clearly and consistently.
- Which component or flow is attacked?
- What asset is affected?
- What assumption or dependency makes the attack possible?
- What is the business impact?
- What control breaks the attack path?
Don't think in terms of threats. Think in terms of attacker objectives and dependencies.
During threat modeling, sit in front of an architecture and naturally ask:
- What would an adversary want?
- How would they get it?
- What do they need first?
- Can they actually satisfy those conditions?
- What stops them?
The value of threat modeling comes from this reasoning process. It forces assumptions to become explicit, identifies where trust could fail, and shows which controls actually matter.
Ultimately, the goal is simple: understand the system well enough to understand how it could fail under adversarial conditions, and design the system so that the most important attack paths are prevented, constrained, or detected.