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)
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 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?
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 |