Threat Modeling with STRIDE: A Practical Walkthrough
Table of Contents

Your team is reviewing checkout before a release. Someone asks whether login is secure, everyone confirms that it is, and the discussion moves on. Meanwhile, the API still accepts a price field that a customer can edit before submitting an order.
That's where threat modeling with STRIDE helps. It gives the team concrete questions to ask about the system, but the useful output isn't a categorized list. It's a maintained diagram, actionable engineering work, and a decision log that explains what you skipped and when to reconsider it.
What Each STRIDE Letter Asks About Your System
STRIDE originated at Microsoft in 1999, when Loren Kohnfelder and Praerit Garg introduced it to make design-stage threat discovery systematic, as described in this ETRI Journal article. Its categories connect security properties to questions engineers can answer about actual components and interactions.
For checkout, asking whether authentication works doesn't establish whether the server protects order integrity. Each question below exposes a different failure.
| Category | Security property | Question to ask | Example threat | Common control |
|---|---|---|---|---|
| Spoofing | Authentication | Can someone pose as a user or service? | Forged JWT accepted by the API | Strong authentication and token validation |
| Tampering | Integrity | Can data change in transit or at rest? | Price field edited in the checkout request | Server-side price calculation and signed payloads |
| Repudiation | Non-repudiation | Can an actor deny an action without evidence? | Admin deletes a record with no audit entry | Tamper-evident, append-only audit logs |
| Information Disclosure | Confidentiality | Can data reach someone not entitled to it? | Stack trace exposes database credentials | Encryption, safe error handling, least exposure |
| Denial of Service | Availability | Can the service be made unavailable? | Unthrottled export endpoint exhausts the database | Rate limits and resource isolation |
| Elevation of Privilege | Authorization | Can someone gain rights they shouldn't have? | User edits a role claim to admin | Server-side authorization checks at every boundary |
Controls need context. Signing a request doesn't make a customer-supplied price authoritative, and an audit log doesn't establish attribution if administrators can rewrite it.
Use the categories as prompts
STRIDE is a threat-enumeration method, not a risk score or proof of security. Comparing threat modeling frameworks helps when you also need business-risk analysis, privacy analysis, or attacker-focused scenarios.
Don't spend the session debating whether a threat belongs under Tampering or Elevation of Privilege. Record the abuse case clearly enough to fix it. The questions, not the acronym, do the work.
How to Draw the Data-Flow Diagram First
Scope determines whether the session produces decisions or an unfinished architecture discussion. For a payments service, include customer checkout, administrative refunds, the payment webhook receiver, and order storage. Identify the provider as an external dependency, not something your team controls.
Use the scope sketch to agree on responsibility before detailing flows. A scope boundary and a trust boundary aren't necessarily the same: components owned by your team can still operate with different privileges.

Draw the system engineers actually operate
Microsoft's secure-by-design guidance connects architecture understanding, threat identification, mitigation, and validation. Bring people who understand both the implementation and the business behavior.
- Define scope and assets. Write the supported use cases and security objectives beside the diagram. For payments, distinguish customer payment data, order integrity, and administrative access. State whether card details reach your service or remain with the provider.
- Draw the element types. Use processes, data stores, external entities, and directed data flows. In diagrams.net, for example, label the checkout API as a process and the orders database as a store. Don't draw every class.
- Mark trust boundaries. Show where identity, privilege, ownership, or execution context changes. Browser-to-API traffic needs different treatment from an authenticated service writing to a shared database.
- Label operational paths. Give arrows meaningful descriptions, such as signed payment event or refund command. Include queues, deployment credentials, telemetry destinations, and emergency administrative access.
- Request architecture and operations review. Ask an architect to challenge component relationships and an on-call engineer to identify recovery paths. A manual database correction during an incident is part of the system, even if it isn't part of the product UI.
Choose review prompts by element
Use this matrix as a starting point for enumeration, not permission to ignore a plausible threat. Yes means review by default; a dash means consider the interaction before deciding applicability.
| DFD element | S | T | R | I | D | E |
|---|---|---|---|---|---|---|
| External entity (user, third-party API) | Yes | - | Yes | - | - | - |
| Process (service, function, API) | Yes | Yes | Yes | Yes | Yes | Yes |
| Data store (database, queue, log) | - | Yes | Yes | Yes | Yes | - |
| Data flow (request, event, webhook) | - | Yes | - | Yes | Yes | - |
For example, review provider identity at the webhook receiver even though Spoofing isn't marked against data flows. The matrix organizes discussion; the receiving process still has to authenticate the sender.
How to Enumerate Threats Against Each Element
Take an element and describe an attacker action, the condition that enables it, and the consequence. Injection is a topic. A customer inserts query syntax into an order-search parameter and reads another customer's orders is an actionable abuse case.
Keep the diagram visible while someone records the worksheet. Otherwise, participants drift into general security advice instead of examining the design.
Turn questions into engineering work
- Select an element. Start with a boundary-crossing flow and its receiving process. Consult the matrix, then consider any additional categories the interaction makes relevant.
- Write an attacker action. For a webhook, consider forgery and replay separately. A valid signature doesn't stop someone from resending a previously valid event.
- Record the location and property. Identify the affected flow, boundary, and security property. Use stable diagram identifiers so renamed services don't break traceability.
- Choose a response. Propose a redesign, a preventive control, or explicit risk acceptance. Describe what the response stops rather than naming a product or library alone.
- Assign accountability. Give the row an implementation owner, a reviewer, and a due date tied to a release or work cycle. A team name helps route work, but the resulting ticket needs a named assignee.
- Explain non-applicability. Record why a category doesn't apply. Distinguish an impossible interaction from an interaction excluded because of an assumption.
A payments worksheet that can become tickets
| DFD element | STRIDE | Abuse case | Mitigation | Owner |
|---|---|---|---|---|
| Checkout API (process) | E | Customer changes order to staff pricing tier | Server-side role check on the pricing endpoint | Payments team |
| Payment provider webhook (data flow) | T | Forged webhook marks an unpaid order as paid | Verify provider signature and use idempotency keys | Backend lead |
| Orders database (data store) | I | Backup snapshot read by a former contractor | Encryption at rest and a restricted IAM role | Platform team |
| Order events queue (data store) | R | Order cancelled with no record of who triggered it | Actor ID on every event and an append-only log | Backend lead |
| Admin portal (external entity) | S | Stolen session used to act as a support agent | MFA and short session lifetime | Security team |
These rows are starting points, not complete specifications. Treat the admin portal as an external entity only when it represents a caller outside the modeled service; model its backend separately if that backend is in scope.
Several controls need qualification. MFA helps protect session issuance but doesn't invalidate an already stolen session, so consider revocation and step-up authentication for refunds. Encryption at rest won't stop a former contractor whose credentials still authorize decryption.
A worksheet row should read like a ticket an engineer can implement without another discovery meeting.
Attach acceptance criteria and verification evidence to the ticket. For the webhook, require rejection of invalid signatures and duplicate-event handling without repeating the payment transition. For backups, demonstrate denied access using the removed contractor's effective permissions.
Rating Threats and Recording What You Skipped
An unranked backlog turns a useful session into a scheduling dispute. Engineers can't distinguish release-blocking design flaws from hardening work, and reviewers keep reopening the same debates.
I recommend a lightweight likelihood-times-impact score as a starting convention. It's an ordering aid, not a probability calculation. Define likelihood using attacker access, prerequisites, and exploitability; define impact using unauthorized money movement, data exposure, operational interruption, and recovery difficulty.
The illustration below is a hypothetical prioritization exercise, not a measured STRIDE outcome. Its simplified bands differ from the example release policy beneath it; choose a policy and apply it consistently.

Set a local response policy
For a worked example, rate likelihood and impact from 1 to 5, multiply them, and use these proposed bands. These are team-defined policy choices, not externally established thresholds.
| Band | Score (likelihood × impact) | Required response | Target window |
|---|---|---|---|
| Critical | 16–25 | Redesign or block the release | Before release |
| High | 10–15 | Preventive control in the current cycle | Current cycle |
| Medium | 5–9 | Control or documented acceptance | Next planning cycle |
| Low | 1–4 | Accept with recorded rationale | Review at next model refresh |
Allow reviewers to override the calculated band with a reason. A contractual obligation or irreversible loss may justify blocking a release even when reviewers assign low likelihood.
Preserve the reasoning behind exclusions
A 2024 descriptive study of threat-modeling assumptions found that only 30% were explicitly documented for threat exclusion and 22% for priority decisions. Those findings concern the study's analyzed assumptions, not a universal rate across engineering teams.
Use an assumption register to make those decisions inspectable:
- Decision and element. Record the excluded, accepted, or deprioritized threat and its diagram identifier.
- Assumption and evidence. State, for example, that the admin portal is reachable only through VPN, with the relevant configuration evidence.
- Attacker capability. Specify whether compromised employee credentials or a malicious tenant are in scope.
- Accountability and expiry. Name the accepting reviewer and review date.
- Reopen trigger. Identify what invalidates the decision, such as public access, a new integration, or changed asset sensitivity.
Practical rule: No accepted or not-applicable decision is complete without an accountable reviewer and a condition for reconsideration.
In regulated environments, this record helps explain why an exclusion was reasonable at the time. Don't turn uncertainty into a permanent exemption.
Keeping the Model Current in Every Pull Request
A threat model isn't finished when someone approves the diagram. If the diagram describes an architecture your engineers no longer operate, careful category assignments won't rescue the review.
Microsoft's architecture threat-modeling guidance starts with assets, boundaries, components, and flows, then requires mitigation documentation and review. The practical implication is that architecture changes must reopen security decisions, not merely update a picture.

Make reopening part of code review
Add explicit triggers to the pull-request template:
- External dependencies. New third-party services, webhook senders, or outbound destinations.
- Asynchronous processing. Queues, consumers, retries, or dead-letter handling.
- Administrative access. Changes to who can invoke privileged operations.
- Deployment context. New execution environments, service identities, or secret access.
- Sensitive assets. Payment records, health information, or other newly handled data classes.
- Expiring decisions. Exceptions that reach their review date or lose supporting evidence.
Use a narrow gate: a changed component that crosses a modeled trust boundary or handles a sensitive asset must link to an approved mitigation or documented exception. Require a security reviewer when the change alters an existing acceptance decision.
Blocking every documentation mismatch creates friction without necessarily reducing risk. Start with sensitive changes, then expand enforcement once component ownership and model identifiers are reliable.
Verify behavior and watch workflow cost
Test authorization directly at the service boundary, not only through the UI. Attempt audit-log alteration, exercise rate limits under load, and verify that a low-privilege identity can't invoke privileged operations. Include failure behavior, such as unavailable identity providers or exhausted downstream capacity.
Track changed-component coverage, mitigation closure, review latency, reopened threats, and incidents linked to unmodeled changes. Don't substitute a universal success-rate claim for those operational measures.
A repository-managed worksheet and CI checks can support this threat modeling process. DevArmor is another option: it generates and refreshes models from tickets, repositories, and service metadata, and applies Policy-as-Code checks to pull requests with optional merge blocking and traceable review outcomes.
Adding Agent and Tool Risks to Your STRIDE Model
Consider a support agent that reads customer tickets, invokes an internal refund tool, and posts summaries to a shared channel. Its diagram needs prompts, retrieved documents, tool calls, memory stores, and agent messages, with explicit trust relationships between them.
AWS's agentic AI development guidance recommends addressing conventional distributed-system threats alongside AI-specific risks. Map those risks to concrete interactions rather than adding a generic AI-risk box.

Extend the worksheet to agent capabilities
- Prompt injection → Tampering. At the retrieval flow, separate untrusted content from instructions and validate tool arguments. Formatting alone isn't a security boundary.
- Excessive agency → Elevation of Privilege. At agent-to-tool calls, use scoped credentials and approval gates for consequential write actions.
- Weak agent identity → Spoofing. Authenticate agent-to-agent messages and verify signatures where messages cross independently operated systems.
- Cross-user memory leakage → Information Disclosure. Partition memory by user or tenant and enforce retention limits.
- Sensitive output → Information Disclosure. Check the output flow with secret scanning, filtering, and destination authorization.
- Unattributed actions → Repudiation. Log agent identity, initiating user, tool arguments, approval evidence, and an input hash without unnecessarily retaining sensitive content.
- Runaway tool calls → Denial of Service. Enforce rate limits, concurrency limits, and per-agent budget caps at the tool or MCP endpoint.
For refund approval design, AgentStack's guidance on risk management for automated customer support provides useful context for deciding which actions need human authorization. Apply those decisions at the tool boundary, not solely in a prompt.
Treat prompt, model, permission, and tool changes as reviewable changes within AI coding security. Re-run relevant abuse tests when those inputs change, and keep credential revocation available independently of the agent.
Start Your First Threat Model This Sprint
Start with a service that handles money, personal data, or administrative access and changes frequently. A stable but rarely touched service won't exercise your maintenance process; an entire platform will overwhelm the first session.
Choose a narrow business operation, such as checkout completion or refund approval. The useful outcome is a reviewable set of decisions, not coverage of every system your company owns.
Run a bounded working session
For a practical starting agenda, I recommend a 60-minute session, with roughly five minutes per selected element. These are facilitation choices, not evidence-based performance targets; reduce the scope if the team needs deeper analysis.
- Invite the right people. Include the architect, a backend engineer, someone from on-call or SRE, and a security reviewer. Name a facilitator and a recorder before the meeting.
- Prepare the artifacts. Draft the DFD and create the worksheet in the team's existing repository or ticketing workflow. Include links to relevant authentication, deployment, and data-handling configuration.
- Follow a bounded path. Review a selected business flow around a receiving trust zone, including its boundary crossings. Don't expand the session into unrelated zones because someone remembers another service.
- Capture unresolved questions. When nobody can answer what happens if a provider retries an event, record an open question with an investigation owner. If analysis depends on an assumed answer, mark that assumption explicitly.
- Leave with assignments. Create tickets for actionable threats and investigation tasks. Confirm that every exclusion has a reason rather than leaving blank cells.
End the meeting with decisions people can execute, not a promise to tidy the worksheet later.
Test the process against actual delivery
As a proposed follow-up cadence, review the worksheet within two weeks. Check that mitigation tickets have named owners, due dates, acceptance criteria, and a reviewer who can assess the evidence.
Don't wait for every finding to close before applying the PR trigger. Use the next relevant change to check whether an engineer can identify the affected diagram element, locate its assumptions, and understand the required control without asking the original participants.
Before everyone leaves, book the first reopen check on the calendar. Give that meeting an owner and a concrete task: compare the model with shipped changes, revisit invalidated assumptions, and decide what must change next.
DevArmor offers continuous threat modeling, in-workflow security design reviews, and implementation verification tied to code changes. Visit DevArmor to explore how maintained STRIDE models, recorded decisions, and pull-request policies can fit into your delivery workflow.
Table of Contents
Subscribe

