In post one of this series, we introduced threat modeling and STRIDE. In post two, we built a Data Flow Diagram and used it to surface threats systematically. Now comes the question teams most often skip: what do you actually do with all those threats once you have found them?
A list of threats in a notebook or a whiteboard photo is not a risk register. It does not assign ownership, it does not have a severity, and it has no status. Without those three things, threats get discussed, forgotten, and rediscovered — usually at the worst possible time. A risk register closes that gap.
What is a risk register?
A risk register is a structured table that turns identified threats into tracked work items. Each row is one threat. Each column captures a dimension that matters for decision-making: what the threat is, how bad it would be, how likely it is, who is responsible for fixing it, and whether it has been fixed.
Here is a minimal but complete risk register built from the login-flow example in post one:
| # | Threat | STRIDE | Component | Severity | Likelihood | Mitigation | Owner | Status |
|---|---|---|---|---|---|---|---|---|
| 1 | Credential interception via MITM on login endpoint | T | Login API | Critical | Medium | Enforce HTTPS, enable HSTS | Platform team | Done |
| 2 | JWT stolen from localStorage via XSS | I | Browser client | High | Medium | Migrate to httpOnly cookies; strict CSP | Frontend team | Open |
| 3 | Brute-force on login endpoint | D | Login API | High | High | IP + account rate limiting; CAPTCHA after 5 failures | Platform team | Open |
| 4 | Login error leaks account existence ("user not found" vs "wrong password") | I | Login API | Medium | High | Return generic error regardless of failure reason | Backend team | Done |
| 5 | No audit log for authentication events | R | Auth service | Medium | High | Log login/logout with timestamp, IP, user-agent | Platform team | Open |
| 6 | Standard user accesses admin-only routes | E | API server | Low | Low | Middleware RBAC check on every admin route | Backend team | Done |
Six rows. Eleven minutes of work on top of the DFD we already drew. Three of those six threats are already mitigated — which means whoever owns this system has made conscious, documented decisions about what is done and what is still open. That is the difference between a risk register and a threat list.
Linking diagrams to risk register entries
The power of working in a tool like ThreatTree is that threats do not exist in isolation — each one is anchored to a specific element in a diagram. A threat identified on the Login API process traces back to that process node in the DFD. A threat on the Session token data flow links to that specific arrow in the diagram.
That linkage does three things for you:
- Traceability: when a developer asks "why do we need to implement httpOnly cookies?", you can navigate from the risk register row directly to the DFD element and the reasoning behind it.
- Scope control: when the system changes — a new service is added, an existing flow is rerouted — you can see exactly which risk register entries are affected by that change.
- Completeness checking: if a DFD element has no associated risk register entries, that is a signal it has not been threat-modeled yet, not a signal it is safe.
Key principle: a threat with no diagram anchor is a threat without context. A risk register row with no diagram link is a floating assertion that is hard to validate, update, or hand off.
Prioritising: what to fix first
Not all threats are equal, and not all mitigations need to ship in the same sprint. Prioritisation in a risk register combines two dimensions: severity (how bad the impact would be) and likelihood (how probable exploitation is given your threat landscape).
ThreatTree uses a four-tier severity model — Critical, High, Medium, Low — which maps roughly to the CVSS base score bands (9.0–10, 7.0–8.9, 4.0–6.9, 0.1–3.9). To prioritise, filter by severity descending, then break ties by likelihood. The result is a work queue, not just a list.
What "accepted" means and when to use it
Not every threat has a mitigation that is worth implementing. A Low-severity threat on a system with no sensitive data and no regulatory exposure may be legitimately accepted — meaning the organisation has reviewed the risk and decided the cost of mitigation exceeds the cost of the risk materialising. Accepted risks should be documented with a rationale and an owner, not silently dropped. In ThreatTree, a risk can be set to Accepted with a justification note, which keeps it visible without cluttering the active work queue.
Sharing and collaboration
A risk register that lives in one person's head, or in a spreadsheet no one else knows about, is not a risk register — it is a personal document. Effective threat modeling is a team sport. The DFD session itself should include the engineer who owns the system, a product or business stakeholder, and a security reviewer. The risk register should be accessible to anyone who needs to act on it.
In ThreatTree, a Forest — the container that holds your Attack Trees, DFDs, and risk register together — can be shared with collaborators. Teammates can view diagrams, comment on threats, and update mitigation status without needing to ask someone to email them a snapshot.
PDF report generation
At some point, your threat model needs to leave ThreatTree and land in front of a stakeholder who does not use ThreatTree — an auditor, a customer's security team, a board member asking for evidence of your security posture.
ThreatTree's PDF export (available on Pro and Enterprise plans) generates a self-contained report from a Forest that includes:
- A cover page with the Forest name, owner, and date
- An executive summary with threat counts and severity breakdown
- All Attack Tree and DFD diagrams, rendered at full fidelity
- Cross-reference tables linking each diagram element to its risk register rows
- The complete risk register with severity, likelihood, mitigation, owner, and status
The report is designed to be handed to someone who has never seen ThreatTree and still fully understand the threat model — what the system does, what the risks are, and what is being done about them.
Closing the loop: threat modeling as a living process
The biggest mistake teams make after their first threat modeling session is treating it as a one-time audit. Systems change — new features are added, integrations are wired up, infrastructure is migrated. Each change is a potential new trust boundary, a new data flow, a new attack surface. A threat model that is not updated is a threat model that is wrong.
The loop looks like this:
The goal is not perfection on the first pass. The goal is a living document that improves over time: threats get mitigated, new ones are added as the system evolves, and the risk register becomes an accurate reflection of your current security posture rather than a historical artifact from a session two years ago.
Practical cadence: revisit the threat model at every architecture review, every time a new external integration is added, and at least once per quarter for any system handling sensitive data. The first session takes the longest — subsequent updates are incremental.