Risk Register
Identify, score, and mitigate risks on a 5×5 likelihood and impact matrix, track residual risk against controls, and get AI-suggested mitigations in Muin.
The Risk Register is where your organization catalogs, scores, and tracks compliance risks. Each risk is scored on a 5×5 matrix (likelihood × impact), assigned an owner, linked to the controls that mitigate it, and moved through a mitigation workflow to closure or accepted-risk status.
The Risk Management factor is 20% of your overall compliance score — the second-largest factor after framework completion — so keeping this register current directly moves your score.
The 5×5 Scoring Model
Muin uses a simple and widely-adopted likelihood × impact model with both values on a 1–5 scale.
Likelihood (1–5)
| Value | Label | Meaning |
|---|---|---|
| 1 | Rare | <5% chance in the next 12 months |
| 2 | Unlikely | 5–25% chance |
| 3 | Possible | 25–50% chance |
| 4 | Likely | 50–75% chance |
| 5 | Almost certain | >75% chance |
Impact (1–5)
| Value | Label | Meaning |
|---|---|---|
| 1 | Negligible | Minor inconvenience, no data loss, no material cost |
| 2 | Low | Small cost, recoverable, no external notification |
| 3 | Moderate | Notable financial/operational impact, customer notification possible |
| 4 | Major | Significant financial loss, regulatory notification required, reputational damage |
| 5 | Severe | Existential risk — business continuity threat, major regulatory action |
Derived Score and Level
score = likelihood × impact (range: 1–25)
The score is bucketed into a level:
| Score | Level | Typical action |
|---|---|---|
| 20–25 | Critical | Immediate exec escalation + mitigation workflow auto-started |
| 12–19 | High | Mitigation owner assigned, plan due within 30 days |
| 6–11 | Medium | Monitored quarterly, mitigation if cost-effective |
| 2–5 | Low | Logged and tracked, reviewed annually |
| 1 | Minimal | Accepted by default, reviewed annually |
Thresholds are defined in RiskService.get_risk_level — see muin.server/src/services/compliance/risk_service.py.
Residual Risk
The inherent score is the score with no controls applied. The residual score is what remains after a control is applied with some effectiveness:
residual = inherent × (1 − control_effectiveness)
For example, an inherent score of 20 (critical) with a control that’s 75% effective becomes a residual score of 5 (low). Control effectiveness is a per-risk value you set — it’s not magic, just a multiplier — so the register lets you model how much of each risk each mitigation actually buys you.
When a linked control’s test status changes (e.g. from tested to in_progress), Muin recalculates the residual scores of all risks linked to that control. This is JG-4 in the plan — residual auto-updates on control test change, so you never have a register showing low-risk for a risk whose control has silently failed a test.
Creating a Risk
On /compliance/risks, click New Risk. The form asks for:
| Field | Purpose |
|---|---|
| Title | Short descriptor, e.g. “Unencrypted customer PII in exports” |
| Description | Full context for the auditor |
| Category | technical, process, people, financial, regulatory, reputational, or other |
| Likelihood | 1–5 |
| Impact | 1–5 |
| Inherent score | Auto-computed from likelihood × impact (read-only on the form) |
| Owner | Risk owner (a User) — the accountable person |
| Status | open, mitigating, mitigated, accepted, closed |
| Linked controls | Framework controls that mitigate this risk |
Both likelihood and impact are validated to the 1–5 range at the service layer — values outside that range return a 422.
The Heatmap (IS13)
The heatmap view aggregates your register into a 5×5 matrix. Each cell shows the count of risks at that likelihood/impact combination. Click a cell to drill through to the filtered risk list.
Impact →
1 2 3 4 5
┌────┬────┬────┬────┬────┐
1 │ 3 │ 1 │ 0 │ 0 │ 0 │ minimal/low
├────┼────┼────┼────┼────┤
2 │ 5 │ 8 │ 2 │ 1 │ 0 │ low/medium
├────┼────┼────┼────┼────┤
L 3 │ 2 │ 4 │ 7 │ 3 │ 1 │ medium/high
i ├────┼────┼────┼────┼────┤
k 4 │ 0 │ 1 │ 2 │ 2 │ 0 │ high/critical
e ├────┼────┼────┼────┼────┤
l 5 │ 0 │ 0 │ 1 │ 0 │ 0 │ critical
i └────┴────┴────┴────┴────┘
h
o
o
d
Colors shade by level: green for minimal/low, amber for medium, red for high/critical.
The heatmap pulls from GET /compliance/risks/heatmap which returns one row per cell with the aggregate count. The backend-side matrix generator is RiskService.generate_heatmap_matrix — a simple aggregation that’s fast enough to compute on every page load, no caching.
Why Your Heatmap Cell Counts Zero
If a cell you think should have risks shows zero, check three things:
- The risks have
statusother thanclosed— closed risks are excluded from the heatmap by default - The likelihood and impact values are both in the 1–5 range — values outside that range aren’t placed on the matrix (see
generate_heatmap_matrixbounds check) - The filter bar above the heatmap isn’t set to a category or owner that excludes the expected risks
Mitigation Workflow
When a risk’s score crosses the high threshold (≥12) and mitigation_status is NOT_STARTED, Muin automatically:
- Fires a
risk.high_without_mitigationnotification to the risk owner - Starts a
compliance.risk.mitigation_approvalWorkflowInstance(Plan 272k INT-WORKFLOWS) - Creates a
HumanTaskfor the owner to acknowledge and propose mitigation
The workflow walks the owner through: assess root cause → propose mitigation → assign target date → link controls → submit for review → approval → close.
Once the workflow completes and the residual score drops below the high threshold, the alert clears automatically — no manual dismiss.
Accepting a Risk
Sometimes mitigation is uneconomic — the risk is real but the cost of controls exceeds the cost of the residual. Accept the risk:
- On risk detail, click Accept Risk
- Fill in the acceptance justification (required, stored for audit)
- The risk transitions to
acceptedstatus - A
HumanTaskis created for the compliance owner to approve the acceptance
Accepted risks still show in the heatmap (so auditors see them) but they don’t trigger the mitigation workflow or notifications.
Linking Risks to Controls (JG-4)
On risk detail, the Linked Controls section lets you attach one or more framework controls. Each link stores:
- The control’s ID
- An effectiveness value (0.0–1.0) — how much of the risk this control mitigates
When any linked control’s test status changes, Muin recomputes the risk’s residual score using the linked control’s effectiveness. This ensures:
- If a control that was mitigating a risk fails a test → the residual score goes back up → the heatmap lights up red
- If a control gets newly certified → the residual drops → the risk may fall off the high-priority list
This is JG-4 in Plan 272 — the residual-updates-on-control-test link that keeps the register honest.
AI-Assisted Mitigation (JG-5)
The Suggest Mitigation button on any risk detail invokes Bedrock Claude with the risk’s title, description, category, likelihood, impact, and the tenant’s active framework controls. It returns 3–5 concrete mitigation strategies tailored to the risk.
What the AI Does Well
- Translates a plain-English risk description into control-themed mitigations
- References the specific framework controls the tenant already has (so suggestions map to existing work, not new work)
- Flags immediate-escalation when the risk is at or above
score ≥ 15— “Immediate management escalation required” is always the first suggestion for severe risks
What the AI Doesn’t Do
- Create the mitigation for you — the output is a suggestion list, not a committed plan
- Invent controls you don’t have — the citation fence rejects suggestions referencing controls not in your tenant
- Replace the risk owner’s judgment — the owner still chooses which suggestions to accept, adjusts effectiveness values, and signs the mitigation plan
There’s also a rule-based fallback (RiskService.suggest_mitigation static method) that returns category-appropriate templates when the LLM is slow, rate-limited, or returns an unusable response. The UI shows a source badge indicating LLM vs rule-based so you always know which you’re reading.
Risk Summary (/compliance/risks/summary)
The summary endpoint returns aggregate counts by level and status — used by the sparklines on the /compliance Today tab and the mitigation-status donut chart on the risk list page. Handy for quick exec view without drilling through the heatmap.
FAQs
What’s residual risk?
Residual is the risk that remains after controls are applied. Formula: residual = inherent × (1 − control_effectiveness). A control that’s 75% effective reduces the risk by 75%. Residual moves automatically when the linked control’s test status changes (JG-4), so your register reflects reality instead of the score you set six months ago.
Why does my heatmap cell count zero?
Three usual reasons: (1) the risks in that cell are closed (closed risks are excluded from the heatmap), (2) the likelihood or impact value is outside the 1–5 range and therefore not placed on the matrix, (3) a filter is active that excludes those risks. Check each in that order.
How do I close a risk?
Move through: open → mitigating → mitigated (residual has dropped below the threshold you committed to) → closed. Alternatively, accepted is a valid terminal status for risks where mitigation isn’t economic — requires an acceptance justification and compliance owner approval. Closed and accepted risks both remain visible for audit but don’t trigger notifications.
What if the AI mitigation suggestion is wrong?
The suggestion list is never auto-committed — you review and pick what fits. If you disagree with every suggestion, ignore them. The rule-based fallback returns generic category-appropriate ideas if that’s more useful than LLM output. The source badge tells you which you’re reading, and the risk owner is always the accountable decision-maker.
Can a mitigation workflow be restarted?
Yes — if a risk was mitigated and then a control test failure pushes the residual back into the high-threshold zone, the high-without-mitigation predicate fires again and a new workflow instance is started. Prior workflow history is preserved for audit.
Related
- Compliance Health — risk management is 20% of the score
- Compliance Frameworks — link risks to framework controls for JG-4 auto-update
- Incidents — incidents can escalate to new risk register entries
- Workflows platform — the mitigation workflow engine