Security Threat Model Skill
Produce a complete STRIDE-based threat model for a service or feature. A threat model is not a list of things that could go wrong — it is a structured analysis of attackers, assets, boundaries, and controls that lets an engineering team make informed, documented security decisions.
A good threat model is specific enough that a new engineer can understand what is being protected, why each control exists, and what risk the team has accepted.
Required Inputs
Ask for these if not already provided:
- Service name and description — what the service does, who uses it
- Architecture overview — components, dependencies, data flows (a diagram description or ASCII diagram is fine)
- Deployment environment — cloud provider, VPC/network topology, where it runs (Kubernetes, ECS, VMs, serverless)
- Data sensitivity — what data does this service handle? PII, payment data, credentials, internal-only?
- Existing controls — authentication method, encryption in transit/at rest, current WAF/firewall, existing security scanning
- Trust levels — who are the principals? (anonymous public, authenticated users, internal services, admins)
Output Format
Security Threat Model: [Service Name]
Service: [Name] | Team: [Team name]
Author: [Name] | Reviewed by: [Security lead / peer]
Date: [Date] | Next review: [Date — recommend 6 months or after major architecture change]
Classification: [Internal / Confidential]
1. Overview
[2–3 sentences describing the service, its role in the system, and the scope of this threat model. State what is in scope and what is explicitly out of scope.]
In scope:
- [Component or data flow]
- [Component or data flow]
Out of scope:
- [e.g. Third-party payment processor internals]
- [e.g. Corporate network / end-user devices]
2. Asset Register
Assets are the things worth protecting — data, capabilities, and reputational value.
| Asset |
Description |
Sensitivity |
Owner |
| [e.g. User PII] |
Names, email addresses, profile data |
High — GDPR-regulated |
[Team] |
| [e.g. API credentials] |
Service-to-service auth tokens |
Critical |
[Team] |
| [e.g. Session tokens] |
User authentication state |
High |
[Team] |
| [e.g. Audit logs] |
Record of user and admin actions |
Medium |
[Team] |
| [e.g. Service availability] |
Uptime of the [X] endpoint |
Medium |
[Team] |
Data classification key:
- Critical — Credential material; exposure enables direct system compromise
- High — PII, financial data, health data; regulated or high reputational impact
- Medium — Internal configuration, non-sensitive business data
- Low — Public information, anonymised data
3. Trust Boundaries and Architecture
Trust boundaries are the lines that separate zones with different trust levels. Threats often occur when data or requests cross a boundary.
┌─────────────────────────────────────────────────────────────────┐
│ INTERNET (Untrusted) │
│ │
│ [Public User] [Bot / Attacker] │
└──────────────────────────────┬──────────────────────────────────┘
│ HTTPS
─ ─ ─ ─ ─ ─ ─│─ ─ ─ ─ ─ ─ ─ ─
Trust Boundary: Public → DMZ
─ ─ ─ ─ ─ ─ ─│─ ─ ─ ─ ─ ─ ─ ─
▼
┌──────────────────────────────────────────────────────────────────┐
│ DMZ / Edge Layer │
│ ┌────────────┐ ┌──────────────┐ │
│ │ WAF / CDN │────▶│ API Gateway │ │
│ └────────────┘ └──────┬───────┘ │
└──────────────────────────────┼───────────────────────────────────┘
─ ─ ─ ─ ─ ─ ─│─ ─ ─ ─ ─ ─ ─ ─
Trust Boundary: Edge → Application VPC
─ ─ ─ ─ ─ ─ ─│─ ─ ─ ─ ─ ─ ─ ─
▼
┌──────────────────────────────────────────────────────────────────┐
│ Application VPC (Private) │
│ ┌──────────────┐ ┌────────────┐ ┌──────────────────┐ │
│ │ [Service A] │────▶│ [Service B]│────▶│ [Database] │ │
│ └──────────────┘ └────────────┘ └──────────────────┘ │
│ ▲ │
│ │ │
│ ┌──────────────┐ │ │
│ │ Admin (IAM) │─────────────┘ │
└──────────────────────────────────────────────────────────────────┘
Trust Boundaries identified:
| Boundary |
From |
To |
Auth mechanism |
Encrypted |
| TB-1 |
Public internet |
API Gateway |
[JWT / OAuth / API key] |
TLS 1.2+ |
| TB-2 |
API Gateway |
Service A |
[mTLS / internal JWT / IAM role] |
[Yes/No] |
| TB-3 |
Service A |
Database |
[Connection string + IAM / username+password] |
[Yes/No] |
| TB-4 |
Admin |
Service B |
[IAM role / VPN + MFA] |
TLS |
4. STRIDE Threat Analysis
STRIDE is a threat classification framework. For each significant component, enumerate threats in each category.
STRIDE key:
- S — Spoofing: Impersonating another user, service, or system
- T — Tampering: Modifying data or code without authorisation
- R — Repudiation: Denying an action occurred; insufficient audit trail
- I — Information Disclosure: Exposing data to unauthorised parties
- D — Denial of Service: Making the service unavailable
- E — Elevation of Privilege: Gaining capabilities beyond what is authorised
Component: [API Gateway / Auth Layer]
| ID |
Category |
Threat |
Attack vector |
Existing control |
| T-001 |
S |
Attacker forges a JWT token to authenticate as another user |
Weak signing key or algorithm confusion (alg:none) |
[e.g. RS256 with key rotation / none] |
| T-002 |
S |
Attacker replays a stolen session token |
Theft via XSS or network sniff |
[e.g. Token expiry + refresh rotation] |
| T-003 |
T |
Attacker modifies request headers to bypass tenant isolation |
Missing validation of tenant ID header |
[e.g. Server-side tenant resolution / none] |
| T-004 |
R |
No audit trail for admin authentication events |
Logging not configured for auth failures |
[e.g. CloudTrail enabled / none] |
| T-005 |
I |
Auth error messages reveal whether an email exists |
Verbose error responses |
[e.g. Normalised error responses / none] |
| T-006 |
D |
Credential stuffing exhausts rate limits and blocks legitimate users |
Automated login attempts |
[e.g. Rate limiting per IP + CAPTCHA / none] |
| T-007 |
E |
Compromised low-privilege token used to call admin endpoint |
Missing role check on admin routes |
[e.g. RBAC middleware on all routes / none] |
Component: [Application Service / Business Logic]
| ID |
Category |
Threat |
Attack vector |
Existing control |
| T-008 |
T |
SQL/NoSQL injection via unsanitised user input |
Unparameterised queries |
[e.g. ORM with parameterised queries / none] |
| T-009 |
T |
Mass assignment — attacker sets fields they should not (e.g. isAdmin: true) |
API accepts extra fields without allowlist |
[e.g. Input validation / none] |
| T-010 |
I |
Insecure direct object reference — user accesses another user's resource |
Missing ownership check on resource ID |
[e.g. Ownership middleware / none] |
| T-011 |
I |
Sensitive data in application logs (PII, tokens) |
Over-logging in debug mode |
[e.g. Log scrubbing / none] |
| T-012 |
D |
Unprotected expensive endpoint triggers large DB scan |
No pagination or query cost limit |
[e.g. Pagination enforced / none] |
| T-013 |
R |
Business-critical state changes not logged |
No audit event on [operation] |
[e.g. Audit log table / none] |
Component: [Database]
| ID |
Category |
Threat |
Attack vector |
Existing control |
| T-014 |
I |
Database exposed to internet (misconfigured security group) |
Direct connection from outside VPC |
[e.g. No public IP, security group restricts to app subnet] |
| T-015 |
I |
Backup snapshots not encrypted or accessible to wrong accounts |
Unencrypted snapshot, public S3 |
[e.g. Encrypted snapshots, private S3 bucket] |
| T-016 |
T |
Privilege escalation via DB account with excessive permissions |
App uses a superuser DB account |
[e.g. Least-privilege DB role per service / none] |
| T-017 |
D |
Runaway query or bulk delete causes data loss or outage |
No query timeout or soft-delete |
[e.g. Statement timeout, soft-delete on critical tables / none] |
Component: [Internal Service-to-Service Communication]
| ID |
Category |
Threat |
Attack vector |
Existing control |
| T-018 |
S |
Rogue internal service impersonates a trusted service |
No mutual authentication between services |
[e.g. mTLS / service mesh / none] |
| T-019 |
I |
Internal traffic sniffed on shared network |
Unencrypted service-to-service calls |
[e.g. Service mesh with TLS / none] |
| T-020 |
E |
Compromised internal service calls privileged endpoints |
No scoping on internal tokens |
[e.g. Scoped service tokens / none] |
5. Risk Register
Score each threat: Likelihood (1–5) × Impact (1–5) = Risk Score (1–25)
Priority bands: Critical (20–25) | High (12–19) | Medium (6–11) | Low (1–5)
| ID |
Threat summary |
Likelihood |
Impact |
Score |
Priority |
Status |
| T-001 |
JWT forgery — auth bypass |
2 |
5 |
10 |
Medium |
[Open / Mitigated / Accepted] |
| T-002 |
Session token replay |
3 |
4 |
12 |
High |
[Open / Mitigated / Accepted] |
| T-007 |
Privilege escalation via missing role check |
3 |
5 |
15 |
High |
[Open / Mitigated / Accepted] |
| T-008 |
SQL injection |
2 |
5 |
10 |
Medium |
[Open / Mitigated / Accepted] |
| T-010 |
IDOR — cross-user data access |
3 |
4 |
12 |
High |
[Open / Mitigated / Accepted] |
| T-014 |
Database exposed to internet |
1 |
5 |
5 |
Low |
[Open / Mitigated / Accepted] |
| T-018 |
Rogue internal service impersonation |
2 |
4 |
8 |
Medium |
[Open / Mitigated / Accepted] |
6. Mitigations Table
For every Open threat with priority Medium or above, define a specific mitigation.
| ID |
Threat |
Mitigation |
Owner |
Target date |
Ticket |
| T-002 |
Session token replay |
Implement token rotation on refresh — invalidate old token server-side immediately |
[Engineer name] |
[Date] |
[JIRA-123] |
| T-007 |
Privilege escalation |
Add RBAC middleware to all /admin/* routes; write integration test for role boundary |
[Engineer name] |
[Date] |
[JIRA-124] |
| T-010 |
IDOR |
Add ownership assertion to all resource-fetching service methods; add to code review checklist |
[Engineer name] |
[Date] |
[JIRA-125] |
| T-011 |
PII in logs |
Audit logging calls for PII fields; add scrubbing to logger middleware |
[Engineer name] |
[Date] |
[JIRA-126] |
| T-018 |
Rogue service impersonation |
Enable mTLS via service mesh or issue scoped service tokens per service |
[Engineer name] |
[Date] |
[JIRA-127] |
7. Accepted Risks
Accepted risks are threats the team has decided not to mitigate right now. Every accepted risk must have a named owner and a review date.
| ID |
Threat |
Reason for acceptance |
Risk owner |
Review date |
| T-014 |
Database public exposure |
Database has no public IP assigned; control already in place — accepted as low likelihood |
[Name] |
[Date] |
| [ID] |
[Threat] |
[Reason — e.g. "Effort exceeds risk at current scale; re-evaluate at 10× traffic"] |
[Name] |
[Date] |
8. Security Controls Summary
| Control |
Type |
Covers threats |
Implemented |
| JWT RS256 with 15-min expiry |
Preventive |
T-001, T-002 |
[Yes / Partial / No] |
| RBAC middleware on all routes |
Preventive |
T-007, T-020 |
[Yes / Partial / No] |
| Parameterised queries (ORM) |
Preventive |
T-008 |
[Yes / Partial / No] |
| Rate limiting (100 req/min per IP) |
Preventive |
T-006, T-012 |
[Yes / Partial / No] |
| CloudTrail / audit logging |
Detective |
T-004, T-013 |
[Yes / Partial / No] |
| Automated SAST in CI pipeline |
Detective |
T-008, T-009 |
[Yes / Partial / No] |
| Encrypted backups + private S3 |
Preventive |
T-015 |
[Yes / Partial / No] |
| Least-privilege DB role |
Preventive |
T-016 |
[Yes / Partial / No] |
| Incident response runbook |
Corrective |
All |
[Yes / Partial / No] |
9. Review Cadence
| Trigger |
Action |
| Every 6 months |
Full threat model review — update risk scores, close mitigated items |
| Major architecture change |
Update trust boundary diagram and re-run STRIDE for new components |
| Security incident |
Review relevant threats; add any newly discovered vectors |
| New data classification |
Add assets to register; assess whether new STRIDE categories apply |
| Third-party dependency added |
Assess supply chain threats for the new dependency |
Next scheduled review: [Date]
Review owner: [Name / Security lead]
Quality Checks
1---2name: security-threat-model-63description: Write a STRIDE-based threat model for a service or feature. Use when asked to produce a threat model, document security risks, identify attack vectors, assess a service's security posture, or prepare for a security design review. Produces a structured threat model covering assets, trust boundaries, STRIDE threat enumeration per component, risk scores, mitigation controls, and residual risk sign-off.4---5
6# Security Threat Model Skill
7
8Produce a complete STRIDE-based threat model for a service or feature. A threat model is not a list of things that could go wrong — it is a structured analysis of attackers, assets, boundaries, and controls that lets an engineering team make informed, documented security decisions.
9
10A good threat model is specific enough that a new engineer can understand what is being protected, why each control exists, and what risk the team has accepted.
11
12## Required Inputs
13
14Ask for these if not already provided:
15- **Service name and description** — what the service does, who uses it
16- **Architecture overview** — components, dependencies, data flows (a diagram description or ASCII diagram is fine)
17- **Deployment environment** — cloud provider, VPC/network topology, where it runs (Kubernetes, ECS, VMs, serverless)
18- **Data sensitivity** — what data does this service handle? PII, payment data, credentials, internal-only?
19- **Existing controls** — authentication method, encryption in transit/at rest, current WAF/firewall, existing security scanning
20- **Trust levels** — who are the principals? (anonymous public, authenticated users, internal services, admins)
21
22## Output Format
23
24---
25
26# Security Threat Model: [Service Name]
27
28**Service:** [Name] | **Team:** [Team name]
29**Author:** [Name] | **Reviewed by:** [Security lead / peer]
30**Date:** [Date] | **Next review:** [Date — recommend 6 months or after major architecture change]
31**Classification:** [Internal / Confidential]
32
33---
34
35## 1. Overview
36
37[2–3 sentences describing the service, its role in the system, and the scope of this threat model. State what is in scope and what is explicitly out of scope.]
38
39**In scope:**
40- [Component or data flow]
41- [Component or data flow]
42
43**Out of scope:**
44- [e.g. Third-party payment processor internals]
45- [e.g. Corporate network / end-user devices]
46
47---
48
49## 2. Asset Register
50
51Assets are the things worth protecting — data, capabilities, and reputational value.
52
53| Asset | Description | Sensitivity | Owner |
54|---|---|---|---|
55| [e.g. User PII] | Names, email addresses, profile data | High — GDPR-regulated | [Team] |
56| [e.g. API credentials] | Service-to-service auth tokens | Critical | [Team] |
57| [e.g. Session tokens] | User authentication state | High | [Team] |
58| [e.g. Audit logs] | Record of user and admin actions | Medium | [Team] |
59| [e.g. Service availability] | Uptime of the [X] endpoint | Medium | [Team] |
60
61**Data classification key:**
62- **Critical** — Credential material; exposure enables direct system compromise
63- **High** — PII, financial data, health data; regulated or high reputational impact
64- **Medium** — Internal configuration, non-sensitive business data
65- **Low** — Public information, anonymised data
66
67---
68
69## 3. Trust Boundaries and Architecture
70
71Trust boundaries are the lines that separate zones with different trust levels. Threats often occur when data or requests cross a boundary.
72
73```
74 ┌─────────────────────────────────────────────────────────────────┐
75 │ INTERNET (Untrusted) │
76 │ │
77 │ [Public User] [Bot / Attacker] │
78 └──────────────────────────────┬──────────────────────────────────┘
79 │ HTTPS
80 ─ ─ ─ ─ ─ ─ ─│─ ─ ─ ─ ─ ─ ─ ─
81 Trust Boundary: Public → DMZ
82 ─ ─ ─ ─ ─ ─ ─│─ ─ ─ ─ ─ ─ ─ ─
83 ▼
84 ┌──────────────────────────────────────────────────────────────────┐
85 │ DMZ / Edge Layer │
86 │ ┌────────────┐ ┌──────────────┐ │
87 │ │ WAF / CDN │────▶│ API Gateway │ │
88 │ └────────────┘ └──────┬───────┘ │
89 └──────────────────────────────┼───────────────────────────────────┘
90 ─ ─ ─ ─ ─ ─ ─│─ ─ ─ ─ ─ ─ ─ ─
91 Trust Boundary: Edge → Application VPC
92 ─ ─ ─ ─ ─ ─ ─│─ ─ ─ ─ ─ ─ ─ ─
93 ▼
94 ┌──────────────────────────────────────────────────────────────────┐
95 │ Application VPC (Private) │
96 │ ┌──────────────┐ ┌────────────┐ ┌──────────────────┐ │
97 │ │ [Service A] │────▶│ [Service B]│────▶│ [Database] │ │
98 │ └──────────────┘ └────────────┘ └──────────────────┘ │
99 │ ▲ │
100 │ │ │
101 │ ┌──────────────┐ │ │
102 │ │ Admin (IAM) │─────────────┘ │
103 └──────────────────────────────────────────────────────────────────┘
104```
105
106**Trust Boundaries identified:**
107
108| Boundary | From | To | Auth mechanism | Encrypted |
109|---|---|---|---|---|
110| TB-1 | Public internet | API Gateway | [JWT / OAuth / API key] | TLS 1.2+ |
111| TB-2 | API Gateway | Service A | [mTLS / internal JWT / IAM role] | [Yes/No] |
112| TB-3 | Service A | Database | [Connection string + IAM / username+password] | [Yes/No] |
113| TB-4 | Admin | Service B | [IAM role / VPN + MFA] | TLS |
114
115---
116
117## 4. STRIDE Threat Analysis
118
119STRIDE is a threat classification framework. For each significant component, enumerate threats in each category.
120
121**STRIDE key:**
122- **S** — Spoofing: Impersonating another user, service, or system
123- **T** — Tampering: Modifying data or code without authorisation
124- **R** — Repudiation: Denying an action occurred; insufficient audit trail
125- **I** — Information Disclosure: Exposing data to unauthorised parties
126- **D** — Denial of Service: Making the service unavailable
127- **E** — Elevation of Privilege: Gaining capabilities beyond what is authorised
128
129### Component: [API Gateway / Auth Layer]
130
131| ID | Category | Threat | Attack vector | Existing control |
132|---|---|---|---|---|
133| T-001 | S | Attacker forges a JWT token to authenticate as another user | Weak signing key or algorithm confusion (alg:none) | [e.g. RS256 with key rotation / none] |
134| T-002 | S | Attacker replays a stolen session token | Theft via XSS or network sniff | [e.g. Token expiry + refresh rotation] |
135| T-003 | T | Attacker modifies request headers to bypass tenant isolation | Missing validation of tenant ID header | [e.g. Server-side tenant resolution / none] |
136| T-004 | R | No audit trail for admin authentication events | Logging not configured for auth failures | [e.g. CloudTrail enabled / none] |
137| T-005 | I | Auth error messages reveal whether an email exists | Verbose error responses | [e.g. Normalised error responses / none] |
138| T-006 | D | Credential stuffing exhausts rate limits and blocks legitimate users | Automated login attempts | [e.g. Rate limiting per IP + CAPTCHA / none] |
139| T-007 | E | Compromised low-privilege token used to call admin endpoint | Missing role check on admin routes | [e.g. RBAC middleware on all routes / none] |
140
141### Component: [Application Service / Business Logic]
142
143| ID | Category | Threat | Attack vector | Existing control |
144|---|---|---|---|---|
145| T-008 | T | SQL/NoSQL injection via unsanitised user input | Unparameterised queries | [e.g. ORM with parameterised queries / none] |
146| T-009 | T | Mass assignment — attacker sets fields they should not (e.g. `isAdmin: true`) | API accepts extra fields without allowlist | [e.g. Input validation / none] |
147| T-010 | I | Insecure direct object reference — user accesses another user's resource | Missing ownership check on resource ID | [e.g. Ownership middleware / none] |
148| T-011 | I | Sensitive data in application logs (PII, tokens) | Over-logging in debug mode | [e.g. Log scrubbing / none] |
149| T-012 | D | Unprotected expensive endpoint triggers large DB scan | No pagination or query cost limit | [e.g. Pagination enforced / none] |
150| T-013 | R | Business-critical state changes not logged | No audit event on [operation] | [e.g. Audit log table / none] |
151
152### Component: [Database]
153
154| ID | Category | Threat | Attack vector | Existing control |
155|---|---|---|---|---|
156| T-014 | I | Database exposed to internet (misconfigured security group) | Direct connection from outside VPC | [e.g. No public IP, security group restricts to app subnet] |
157| T-015 | I | Backup snapshots not encrypted or accessible to wrong accounts | Unencrypted snapshot, public S3 | [e.g. Encrypted snapshots, private S3 bucket] |
158| T-016 | T | Privilege escalation via DB account with excessive permissions | App uses a superuser DB account | [e.g. Least-privilege DB role per service / none] |
159| T-017 | D | Runaway query or bulk delete causes data loss or outage | No query timeout or soft-delete | [e.g. Statement timeout, soft-delete on critical tables / none] |
160
161### Component: [Internal Service-to-Service Communication]
162
163| ID | Category | Threat | Attack vector | Existing control |
164|---|---|---|---|---|
165| T-018 | S | Rogue internal service impersonates a trusted service | No mutual authentication between services | [e.g. mTLS / service mesh / none] |
166| T-019 | I | Internal traffic sniffed on shared network | Unencrypted service-to-service calls | [e.g. Service mesh with TLS / none] |
167| T-020 | E | Compromised internal service calls privileged endpoints | No scoping on internal tokens | [e.g. Scoped service tokens / none] |
168
169---
170
171## 5. Risk Register
172
173Score each threat: **Likelihood (1–5)** × **Impact (1–5)** = **Risk Score (1–25)**
174
175Priority bands: Critical (20–25) | High (12–19) | Medium (6–11) | Low (1–5)
176
177| ID | Threat summary | Likelihood | Impact | Score | Priority | Status |
178|---|---|---|---|---|---|---|
179| T-001 | JWT forgery — auth bypass | 2 | 5 | 10 | Medium | [Open / Mitigated / Accepted] |
180| T-002 | Session token replay | 3 | 4 | 12 | High | [Open / Mitigated / Accepted] |
181| T-007 | Privilege escalation via missing role check | 3 | 5 | 15 | High | [Open / Mitigated / Accepted] |
182| T-008 | SQL injection | 2 | 5 | 10 | Medium | [Open / Mitigated / Accepted] |
183| T-010 | IDOR — cross-user data access | 3 | 4 | 12 | High | [Open / Mitigated / Accepted] |
184| T-014 | Database exposed to internet | 1 | 5 | 5 | Low | [Open / Mitigated / Accepted] |
185| T-018 | Rogue internal service impersonation | 2 | 4 | 8 | Medium | [Open / Mitigated / Accepted] |
186
187---
188
189## 6. Mitigations Table
190
191For every Open threat with priority Medium or above, define a specific mitigation.
192
193| ID | Threat | Mitigation | Owner | Target date | Ticket |
194|---|---|---|---|---|---|
195| T-002 | Session token replay | Implement token rotation on refresh — invalidate old token server-side immediately | [Engineer name] | [Date] | [JIRA-123] |
196| T-007 | Privilege escalation | Add RBAC middleware to all `/admin/*` routes; write integration test for role boundary | [Engineer name] | [Date] | [JIRA-124] |
197| T-010 | IDOR | Add ownership assertion to all resource-fetching service methods; add to code review checklist | [Engineer name] | [Date] | [JIRA-125] |
198| T-011 | PII in logs | Audit logging calls for PII fields; add scrubbing to logger middleware | [Engineer name] | [Date] | [JIRA-126] |
199| T-018 | Rogue service impersonation | Enable mTLS via service mesh or issue scoped service tokens per service | [Engineer name] | [Date] | [JIRA-127] |
200
201---
202
203## 7. Accepted Risks
204
205Accepted risks are threats the team has decided not to mitigate right now. Every accepted risk must have a named owner and a review date.
206
207| ID | Threat | Reason for acceptance | Risk owner | Review date |
208|---|---|---|---|---|
209| T-014 | Database public exposure | Database has no public IP assigned; control already in place — accepted as low likelihood | [Name] | [Date] |
210| [ID] | [Threat] | [Reason — e.g. "Effort exceeds risk at current scale; re-evaluate at 10× traffic"] | [Name] | [Date] |
211
212---
213
214## 8. Security Controls Summary
215
216| Control | Type | Covers threats | Implemented |
217|---|---|---|---|
218| JWT RS256 with 15-min expiry | Preventive | T-001, T-002 | [Yes / Partial / No] |
219| RBAC middleware on all routes | Preventive | T-007, T-020 | [Yes / Partial / No] |
220| Parameterised queries (ORM) | Preventive | T-008 | [Yes / Partial / No] |
221| Rate limiting (100 req/min per IP) | Preventive | T-006, T-012 | [Yes / Partial / No] |
222| CloudTrail / audit logging | Detective | T-004, T-013 | [Yes / Partial / No] |
223| Automated SAST in CI pipeline | Detective | T-008, T-009 | [Yes / Partial / No] |
224| Encrypted backups + private S3 | Preventive | T-015 | [Yes / Partial / No] |
225| Least-privilege DB role | Preventive | T-016 | [Yes / Partial / No] |
226| Incident response runbook | Corrective | All | [Yes / Partial / No] |
227
228---
229
230## 9. Review Cadence
231
232| Trigger | Action |
233|---|---|
234| Every 6 months | Full threat model review — update risk scores, close mitigated items |
235| Major architecture change | Update trust boundary diagram and re-run STRIDE for new components |
236| Security incident | Review relevant threats; add any newly discovered vectors |
237| New data classification | Add assets to register; assess whether new STRIDE categories apply |
238| Third-party dependency added | Assess supply chain threats for the new dependency |
239
240**Next scheduled review:** [Date]
241**Review owner:** [Name / Security lead]
242
243---
244
245## Quality Checks
246
247- [ ] Every trust boundary is named and its authentication mechanism is specified — not left as "TBD"
248- [ ] Every Critical and High risk in the risk register has a mitigation with a named owner and a target date
249- [ ] Every accepted risk has a named risk owner and a review date — no unowned accepted risks
250- [ ] The asset register includes data sensitivity levels and at least one entry for credential material
251- [ ] STRIDE analysis covers all major components — not just the API layer
252- [ ] Mitigation actions are specific enough to become a ticket (not "improve security")
253- [ ] The ASCII trust boundary diagram matches the architecture description provided