Scope and assets at risk
Write what's being reviewed and what assets this change could put at risk: user PII, payment data, authentication tokens, intellectual property, infrastructure credentials. Naming the assets creates the frame for the threat model — every threat is relevant only insofar as it threatens an asset.
Attack surface
Write every point where the system accepts input from an untrusted source: HTTP endpoints, file upload handlers, OAuth callbacks, webhooks, mobile app inputs, third-party API responses. The attack surface is not the same as the feature surface — it's the set of points an attacker could manipulate.
Threats
For each attack surface point: what threats apply? Use STRIDE as a structure if useful: Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege. Write the threats that are relevant to each attack surface point. Don't try to enumerate every possible threat — focus on the plausible ones for your threat model.
Controls
For each threat: what controls are in place? Authentication, input validation, rate limiting, encryption at rest, encryption in transit, audit logging, access control. For each control: is it implemented, partially implemented, or absent? Mark each honestly.
Residual risks and action items
Write the threats that aren't fully controlled — either because controls are absent, partially implemented, or accepted by design. For each residual risk: severity, likelihood, and disposition (mitigate, accept, transfer). For risks being mitigated: write the action items, owner, and date.