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.
When you’d use this
- A risk came up in a meeting and you need it written down, scored and owned before it is forgotten.
- The board asks which part of the organization is carrying the most risk, and you need a defensible answer.
- A vendor’s assessment is about to expire and you want to know before they are already unassessed.
- You need to show an auditor that a risk was tracked to closure rather than quietly dropped.
Three screens share this register: the register itself at /compliance/risks, the Risk Radar roll-up at /compliance/risk-radar, and Third-Party Risk at /compliance/third-party.
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 |
Each risk’s level is shown on its row in Compliance > Risk Register and updates when you change its likelihood or impact.
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.
The Risk Radar (organization-wide)
The Risk Radar scores each part of the organization from the risks already on the register, so you can see where exposure sits without reading every row.
- Go to Sidebar → Compliance → Risks & Incidents → Risk Radar (organization-wide).
- Two tiles sit at the top: Domains assessed (with “of N watch domains”) and Not assessed.
- The table reads Part of the organization · Score · Trend · Risks · Findings.
- A domain with no risks on record shows Not assessed, never a zero. An unassessed domain is not a clean one, and the page refuses to render it as one.
- Trend compares the last two assessed scores in the domain’s history.
- Click Show the evidence on a finding to open the evidence drawer, or Open the record to go to the underlying risk.
- Click Export the board section to build the board-pack section from what is currently on screen.
The score for a domain is built from that domain’s open compliance risks: the share that are critical or high pulls it down, and overdue items subtract further, capped. A domain with no risks returns no score at all.
Risk register at the top right takes you back to the register itself to add or edit the rows the radar reads.
Third-Party Risk
Third-Party Risk is the vendor-facing view of the same discipline: who is high risk, and whose assessment is about to run out.
- Go to Sidebar → Compliance → Obligations → Third-Party Risk.
- Five tiles count the portfolio: Total Vendors, Critical Risk, High Risk, Medium Risk, Low Risk.
- Two tabs split the work:
- High-Risk Vendors: a card per vendor, narrowed by the Filter by risk level select (All Risk Levels, Critical, High, Medium, Low). Click a card to open that vendor’s record.
- Expiring Assessments: assessments expiring in the next 90 days, each showing its expiry date and status.
- A banner counts “N vendor assessment(s) pending review” when any are waiting.
- Add Vendor takes you to vendor onboarding. There is no vendor form on this screen.
What it affects
- Rows you add to the register change the Risk Radar score for their domain, and the Risk Management factor of your compliance score.
- A control test failure moves residual risk, which can re-open a mitigation workflow.
- Vendor risk levels shown here come from the vendor record, so re-assessing a vendor changes this screen.
- Export the board section produces a document from the findings on screen; findings that cite nothing are left out and the page says how many.
When it goes wrong
| What you see | What it means | How to clear it |
|---|---|---|
| “No part of the organization has been assessed yet” | No domain has any risks on record, so no score can be computed. Every domain reads Not assessed, which is honest rather than reassuring. | Add risks to the register. The radar fills in as rows arrive. |
| “We could not load the radar” | The service did not answer. | Click Try again. |
| “We could not load the findings for this part of the organization.” | The domain scored, but its findings list failed to load. | Press See the findings again. |
| “This domain has a score but no individual findings on record yet.” | The score came from risks that have produced no findings. | Nothing is broken. Work the risks on the register. |
| “N of M findings could not be traced to their records.” | Those findings are listed and marked, and deliberately not counted as checked. | Fix the underlying records so the citation resolves. |
| “We could not build the board section. Nothing was sent anywhere; try again.” | The export failed. Nothing was delivered to anyone. | Try again. |
| “No high-risk vendors yet” | No vendor has been assessed at a high score. | Assess your vendors. Unassessed is not low risk. |
| “No expiring assessments” | Nothing is expiring in the next 90 days. | Nothing to do. |
Next step
- Third-party and vendor scorecards: the vendor side of the same assessment.
- Compliance Health: how risk feeds the score.
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