Use this when you need to systematically identify threats to a system -- when designing a new architecture, onboarding onto a client's system, preparing for a security review, or responding to a risk assessment request. Goes beyond feature-level security review to model threats across an entire system.
Related skills: Use
/system-diagramfor architecture input. Use/security-reviewfor per-feature deep dives on high-risk components. Use/adr-generatefor security architecture decisions. Use/architecture-discoveryfor domain boundary analysis.
Process
Step 1: Gather system context
Ask the user for:
- Architecture diagram or description (or run
/system-diagramto generate one) - Data flows -- what data moves where, in what format, over what protocols
- Trust boundaries -- where do privilege levels change?
- Authentication and authorization mechanisms
- External integrations (third-party APIs, SaaS dependencies, payment processors)
- Data sensitivity classification (PII, PHI, financial, public, internal)
- LLM and agent surface: any model calls, RAG pipelines, tool-calling agents, system prompts, vector stores, or multi-model routing. Note what reaches the model (user input, retrieved documents, tool outputs) and what the model can do (which tools, which scopes, which side effects).
If the user provides a description rather than a diagram, sketch a component list with data flows before proceeding.
Step 2: Identify trust boundaries
Map every point where data crosses a trust boundary:
- Client to server -- browser/mobile app to backend API
- Service to service -- internal microservice communication
- Internal to external -- calls to third-party APIs, webhooks
- User to admin -- privilege escalation boundaries
- Encrypted to unencrypted -- TLS termination points, decryption for processing
- Network zones -- public internet, DMZ, private subnet, database tier
Document each boundary with: source, destination, protocol, authentication method, data sensitivity.
Step 3: Apply STRIDE per component
For each component that sits on or crosses a trust boundary, analyze six threat categories:
| Category | Question |
|---|---|
| Spoofing | Can an attacker impersonate a legitimate user, service, or component? |
| Tampering | Can data be modified in transit or at rest without detection? |
| Repudiation | Can a user or system deny performing an action with no way to prove otherwise? |
| Information Disclosure | Can data leak through error messages, logs, side channels, or unauthorized access? |
| Denial of Service | Can the component be overwhelmed, starved of resources, or made unavailable? |
| Elevation of Privilege | Can an attacker gain higher permissions than intended? |
Be specific about attack vectors. Not "the API could be attacked" but "an unauthenticated user could enumerate valid user IDs via timing differences in the login response."
Step 3b: Add the LLM and agent trust-boundary layer
If the system calls an LLM, runs a RAG pipeline, or hosts a tool-calling agent, STRIDE on the web app is not enough. An LLM cannot architecturally separate instructions from data: everything arrives as one token stream, so any untrusted text that reaches the model can act as an instruction. Model this layer explicitly using the 2026 OWASP Top 10 for LLM Applications and the parallel OWASP Top 10 for Agentic Systems.
For each model or agent on a trust boundary, work through these threat classes:
| Class | Question | Maps to STRIDE |
|---|---|---|
| Prompt injection (LLM01, still #1) | Can untrusted input (user text, a retrieved document, a tool result, a webpage the agent fetched) carry instructions the model will follow? | Tampering, Elevation of Privilege |
| System prompt leakage (new in 2026) | Can the system prompt, hidden rules, or embedded secrets be exfiltrated through crafted queries? | Information Disclosure |
| Vector and embedding weaknesses (new in 2026) | Can the vector store be poisoned, or can embeddings leak source data or be inverted? | Tampering, Information Disclosure |
| RAG pipeline poisoning | Can an attacker write content into a source the retriever trusts (a wiki, a ticket, a shared doc) so it surfaces as grounding and steers output? | Tampering |
| Agent goal hijack (Agentic Systems) | Prompt injection multiplied by excessive autonomy and tool access: can hijacked instructions trigger real side effects (send mail, move money, delete data, call an API) through the agent's tools? | Elevation of Privilege, Tampering |
| Tool permission scope | Is each tool the agent can call scoped to least privilege, with a human-in-the-loop gate on destructive or irreversible actions? | Elevation of Privilege |
Treat every input that reaches the model as untrusted instruction surface, not just the obvious user prompt. Retrieved documents, tool outputs, fetched web pages, and prior-turn content all qualify. Roll the threats you find here into the same matrix in Step 4, tagged with their OWASP class in the description so reviewers can trace the lineage.
Step 4: Generate the threat matrix
Produce a table covering every identified threat:
| Threat ID | STRIDE Category | Affected Component | Threat Description | Likelihood (1-5) | Impact (1-5) | Risk Score (L x I) | Existing Controls | Residual Risk |
|---|---|---|---|---|---|---|---|---|
| T-001 | {{category}} | {{component}} | {{specific_attack_vector}} | {{1-5}} | {{1-5}} | {{score}} | {{current_controls}} | {{low/medium/high/critical}} |
Scoring guidance:
- Likelihood: 1 = requires nation-state capability, 5 = script kiddie with public tools
- Impact: 1 = minor inconvenience, 5 = regulatory action, mass data breach, business shutdown
- Risk score: multiply likelihood by impact. Critical >= 20, High >= 12, Medium >= 6, Low < 6
Step 5: Produce prioritized mitigations
For each threat rated high or critical, recommend a mitigation:
| Threat ID | Recommended Control | Control Type | Implementation Effort | Priority |
|---|---|---|---|---|
| T-001 | {{specific_control}} | Preventive / Detective / Corrective | S / M / L | {{P1-P4}} |
Every mitigation must be actionable -- include enough detail that an engineer could estimate and plan the work. "Implement rate limiting" is too vague. "Add per-IP rate limiting at the API gateway (100 req/min for unauthenticated, 1000 req/min for authenticated) with 429 responses and alerting at 80% threshold" is actionable.
Step 6: Annotate the data flow diagram
Mark the system diagram (or component list) with:
- Trust boundary lines (dashed borders around zones)
- Threat entry points (numbered, referencing threat IDs)
- Highest-risk components (highlighted)
- Data sensitivity labels at each flow
If starting from a text description, produce a labeled component diagram in Mermaid or ASCII.
Step 7: Review
Ask the user:
- Are there components or integrations we missed?
- Does the team have threat intelligence -- known attack patterns against similar systems?
- Are there compliance requirements that mandate specific controls (PCI-DSS, HIPAA, SOC 2)?
- What's the team's current security posture -- mature security practice or greenfield?
- Which threats feel most realistic given the organization's exposure?
- If the system uses an LLM or agent: are all instruction-bearing inputs (retrieval sources, tool outputs, fetched pages) accounted for, and is every tool the agent can call scoped to least privilege?
Output location
Deliver the threat model as a markdown document. Suggested filename: threat-model-{{system-name}}-{{date}}.md. Store in the project's security documentation directory or deliver directly to the requesting team.
Example Output
Input
- System description: Meridian Health's new patient portal — React SPA frontend, Node.js/Express API gateway, three internal microservices (appointments, records, billing), PostgreSQL databases per service, and a Stripe integration for copay collection. Auth via Auth0 with JWT tokens passed between services.
- Data sensitivity: PHI (diagnosis history, medication records), PII (name, DOB, SSN for insurance), and payment card data routed through Stripe
- Trust boundaries: Public internet → API gateway, API gateway → internal microservices over private VPC, Auth0 (external IdP) → API gateway, billing service → Stripe API (outbound)
- Compliance requirements: HIPAA, PCI-DSS SAQ-A
- Security posture: Greenfield build, small engineering team, no dedicated security staff
Output (abbreviated)
Threat Model: Meridian Health Patient Portal
Date: 2025-01-14 Scope: Patient-facing portal including SPA, API gateway, three microservices, Auth0 IdP, and Stripe payment integration Classification: CONFIDENTIAL — Contains PHI system architecture details
System Component Inventory
| Component | Zone | Data Handled | Auth Mechanism |
|---|---|---|---|
| React SPA | Public internet (client) | Session tokens, form input | Auth0 PKCE flow |
| API Gateway (Node/Express) | DMZ | JWTs, all PHI in transit | Auth0 JWT validation |
| Appointments Service | Private VPC | Appointment records, PHI | Internal JWT (forwarded) |
| Records Service | Private VPC | Diagnosis, medication, lab results | Internal JWT (forwarded) |
| Billing Service | Private VPC | Copay amounts, insurance IDs | Internal JWT (forwarded) |
| Auth0 (external) | External SaaS | Credentials, session state | OAuth 2.0 / PKCE |
| Stripe (external) | External SaaS | Card data (tokenized) | Stripe API key |
| PostgreSQL (×3) | Database tier | PHI at rest, financial records | Service account credentials |
Trust Boundary Map
| Boundary ID | Source | Destination | Protocol | Auth Method | Data Sensitivity |
|---|---|---|---|---|---|
| TB-01 | Browser (public) | API Gateway | HTTPS/TLS 1.3 | Auth0 JWT (Bearer) | PHI, PII |
| TB-02 | API Gateway | Appointments / Records / Billing | HTTPS (internal) | Forwarded JWT (unvalidated per-service?) | PHI |
| TB-03 | API Gateway | Auth0 | HTTPS | Client credentials + PKCE | Credentials |
| TB-04 | Billing Service | Stripe | HTTPS | Stripe secret key (env var) | PCI card tokens |
| TB-05 | Microservices | PostgreSQL instances | TCP/TLS | Service account password | PHI at rest |
| TB-06 | Any service | CloudWatch / logging | HTTPS | IAM role | Potential PHI in logs |
STRIDE Threat Matrix
| Threat ID | STRIDE | Affected Component | Threat Description | Likelihood | Impact | Risk Score | Existing Controls | Residual Risk |
|---|---|---|---|---|---|---|---|---|
| T-001 | Spoofing | API Gateway (TB-01) | Attacker presents a forged or expired JWT — if the gateway only checks signature but not exp or aud claims, any previously valid token grants access indefinitely | 4 | 5 | 20 — Critical | Auth0 signature validation | HIGH — claim validation unconfirmed |
| T-002 | Elevation of Privilege | Records Service (TB-02) | API gateway forwards JWTs to microservices but individual services perform no independent authorization check; a compromised appointments service could call records endpoints with a patient JWT and retrieve any patient's full medical history | 3 | 5 | 15 — High | VPC network isolation | HIGH |
| T-003 | Information Disclosure | Logging pipeline (TB-06) | Node.js exception handlers log full request bodies on validation errors; a malformed request to the records endpoint could cause PHI (medication list, diagnosis codes) to appear in CloudWatch in plaintext | 4 | 4 | 16 — High | None confirmed | HIGH |
| T-004 | Information Disclosure | Stripe integration (TB-04) | Stripe secret key stored as plaintext environment variable; if any microservice achieves RCE or if env vars are exposed via a /debug or /health endpoint, the key leaks — enabling fraudulent charges against all stored payment methods | 3 | 5 | 15 — High | Stripe key scoped to billing service only | HIGH |
| T-005 | Denial of Service | API Gateway | No rate limiting on unauthenticated endpoints (login, password reset, appointment availability lookup); attacker can enumerate valid patient email addresses via timing differences in the login 401 response (~50ms delta observed) and exhaust appointment slot lookups | 5 | 3 | 15 — High | None | HIGH |
| T-006 | Tampering | PostgreSQL — Records DB (TB-05) | All three microservices use the same PostgreSQL service account with broad CRUD on all tables; a vulnerability in the appointments service could be used to modify records or billing data — no row-level security enforced | 3 | 5 | 15 — High | VPC isolation, no public DB exposure | HIGH |
| T-007 | Repudiation | All services | No centralized audit log for PHI access; a malicious insider or compromised session could read hundreds of patient records with no forensic trail — violates HIPAA §164.312(b) audit controls | 4 | 4 | 16 — High | CloudWatch application logs (incomplete) | HIGH |
| T-008 | Spoofing | Auth0 integration | Auth0 tenant misconfiguration (e.g., allowing social login providers without MFA) could let attacker register a Google account matching a patient's email and gain portal access | 2 | 5 | 10 — Medium | Auth0 managed | MEDIUM |
| T-009 | Information Disclosure | React SPA | JWT stored in localStorage rather than httpOnly cookie; any XSS vulnerability in the SPA (including third-party npm package compromise) can exfiltrate the token and impersonate the patient | 3 | 4 | 12 — High | Content Security Policy (status unknown) | HIGH |
| T-010 | Denial of Service | Records Service | No pagination or query size limits on the records endpoint; an authenticated patient (or attacker with a valid token) can request full record history in a single call, causing memory exhaustion on the service pod | 3 | 3 | 9 — Medium | Kubernetes resource limits (unconfirmed) | MEDIUM |
Prioritized Mitigations (High + Critical)
| Threat ID | Recommended Control | Control Type | Effort | Priority |
|---|---|---|---|---|
| T-001 | In the API gateway JWT middleware, enforce validation of exp, iat, aud (must equal https://portal.meridianhealth.com), and iss (must equal Auth0 tenant URL) on every request. Reject tokens with clock skew > 5 minutes. Add unit tests covering expired and wrong-audience tokens. | Preventive | S | P1 |
| T-002 | Each microservice must independently validate the JWT and enforce its own authorization rules — appointments service may only access appointment-scoped claims; records service must verify the sub claim matches the requested patient ID. Implement a shared internal auth middleware library to standardize this across all three services. | Preventive | M | P1 |
| T-003 | Audit all catch blocks and Express error handlers; redact PHI fields (defined by an allowlist of safe-to-log fields) before writing to CloudWatch. Adopt a structured logging library (e.g., pino) with a PHI scrubbing transform. Run a one-time scan of existing CloudWatch log groups and delete or restrict access to any group containing PHI. | Preventive + Corrective | M | P1 |
| T-007 | Implement a dedicated HIPAA audit log stream: every read/write of PHI must emit a structured event containing { timestamp, userId, patientId, resourceType, action, sourceIp } to an append-only log store (CloudWatch log group |