Risk Registers for AI Systems
5 min read · updated August 3, 2026
Most risk registers fail because their rows are labels — “model hallucination”, “vendor risk” — and a label cannot be argued with, controlled or detected. A row is useful when it names a mechanism, and a mechanism has a place where you could catch it.
What a register is for
Two audiences, and the second one is why the format matters. The first is you: the register is where a risk goes when you have decided not to fix it yet, so that the decision is recorded rather than forgotten. The second is whoever asks later — an auditor, a customer’s security team, a regulator, or the person who takes over your job — and what they are checking is whether the risk was known and consciously accepted.
The consequence for style is that every row must be specific enough to be wrong. “The model might produce inaccurate output” can never be wrong and therefore says nothing. “A retrieved document containing instructions causes the agent to call the refund tool” is a claim about a mechanism, and somebody can tell you whether the control against it works.
The columns that earn their place
| Column | Description |
|---|---|
| mechanism | What actually happens, in one sentence, in cause-and-effect form. Not a category. If you cannot write it as 'X causes Y', you do not yet understand the risk well enough to control it. |
| precondition | What has to be true for this to be possible at all. This column is what lets you close a row honestly: remove the precondition and the risk is gone rather than mitigated. |
| impact | What it costs if it happens once, in the units the business uses — money, a notifiable incident, a customer, a regulatory finding. One occurrence, not a year of them. |
| likelihood | A frequency band with a period attached: 'more than monthly', 'a few times a year', 'less than annually'. Not a probability to two decimal places, which nobody can justify. |
| control | What reduces it, and whether the control is preventive or merely detective. A register full of detective controls is a register of things you will find out about afterwards. |
| detection | How you would learn it had happened. The column most often left blank, and the one that decides whether an incident is caught in an hour or in a quarter. |
| owner / residual / review | A named person, the level of risk you are consciously accepting after the control, and the date or event that triggers a re-read. |
Eleven rows, filled in
Written for a retrieval-backed assistant with some tool access — the most common shape. Adapt the wording; the point is the level of specificity.
| Mechanism | Description |
|---|---|
| R1 injection via retrieved content | Text inside a retrieved document or an inbound email is treated as instruction, and the model performs an action the user did not ask for. Precondition: the model both reads untrusted content and holds a capability. Control: remove one of the two — this is the never-have-all-three rule. Detection: log every tool call with its triggering context and alert on tool calls with no corresponding user intent. |
| R2 exfiltration by rendered link | Model output contains a markdown image or link whose URL carries conversation content to an attacker-controlled host, and the client renders it automatically. Control: render-side allowlisting of hosts. Detection: outbound request logs from the render surface. |
| R3 cross-tenant retrieval | A retrieval filter is missing or wrong and user A receives content belonging to customer B. Precondition: one index holding multiple tenants. Control: the ACL as a mandatory query filter plus a CI test that asserts isolation. Detection: hard — which is why the control has to be preventive. |
| R4 provider changes the model | An alias resolves to a new version; output format, refusal behaviour or length changes; downstream parsing breaks or quality drops silently. Control: pin versions where possible. Detection: a canary suite run on a schedule, not user reports. |
| R5 provider outage in business hours | The dependency is unavailable and the feature is on the critical path of somebody’s work. Control: a fallback route and a decided degraded behaviour. Detection: availability monitoring on your own calls, not on the vendor’s status page. |
| R6 cost regression from a deploy | A prompt, retrieval or reasoning-setting change multiplies tokens per request; the bill moves before anyone notices. Control: a per-request cost assertion in CI plus a hard per-request ceiling. Detection: daily cost per request, not monthly total. |
| R7 denial of wallet | An unauthenticated or weakly limited endpoint is driven at volume by a third party and consumes budget. Control: authentication, per-key caps and rate limits. Detection: spend rate alerting at a granularity finer than a day. |
| R8 fabricated detail reaches a customer | A confident, well-formatted answer contains an invented policy, price or citation and is sent without review. Control: grounding plus a human read for anything leaving the company. Detection: sampled grading of outbound messages against sources. |
| R9 personal data in logs | Prompts and responses are captured for debugging and retained beyond the period the data itself is allowed. Control: redaction at capture, not at query, with retention enforced by the store. Detection: periodic sampling of the log store for identifiers. |
| R10 unreviewed third-party grant | A staff member authorises an AI application against the corporate mailbox or drive, creating a standing data flow to an unreviewed vendor. Control: restrict who may grant scopes. Detection: the OAuth grant inventory in the shadow-AI sweep, run quarterly. |
| R11 vendor term or model deprecation | The model you depend on is retired, or terms change on notice shorter than your migration takes. Control: a known second-choice model and an abstraction you can swap behind. Detection: vendor change notices routed to a person rather than to a shared mailbox. |
Scoring without inventing precision
Resist numeric scores multiplied together. A likelihood of 0.3 times an impact of 7 produces a 2.1 that looks like knowledge and is not. Use bands, and let the bands do exactly one job: sorting.
LIKELIHOOD often more than monthly
sometimes a few times a year
rare less than annually
IMPACT severe notifiable, contractual breach, or a
customer lost
material a bad day, real money, an apology
minor absorbed by normal operation
Rule, not a matrix:
severe + anything above rare -> preventive control required
before launch
material + often -> preventive control or an
accepted, dated exception
everything else -> detection plus a review dateTwo rows in the list above are the ones that trip most registers. R3 has a low likelihood and a severe impact, and it is detection-resistant — which is precisely the combination that demands a preventive control and a test, not a monitoring plan. R6 is the reverse: frequent, rarely severe, and completely detectable, so a cheap automatic check beats any amount of care.
Review on change, not on a calendar
An annual review produces a document nobody has read in eleven months. Give each row a trigger instead, and let the calendar be the backstop.
- A new capability triggers a re-read. The day the assistant gains tool access, R1 changes from theoretical to live and its control has to exist before the deploy.
- A new data class triggers a re-read. Restricted data entering a flow that previously carried internal data changes the impact column of half the rows at once.
- A new audience triggers a re-read. Internal to customer-facing changes R8 from an annoyance to a severe row.
- Every incident adds a row or edits one. That is what makes the register a live document rather than an artefact of a launch, and it is where the detection column usually gets fixed.
Finally, keep the closed rows with the reason they closed. A row that was closed because a precondition was removed is a useful thing to find later, when somebody proposes re-adding the precondition without knowing why it went.