Guide · Risk Management · SharePoint
One SharePoint List, three frameworks. A practical build guide — with the full column schema, conditional formatting JSON you can paste in directly, Power Automate flows for review reminders and risk alerts, and the views auditors expect to see.
No GRC platform required. No annual licence. Built on what you already own — and owned by you, not locked into a vendor's export format.
Most organisations start their risk register in Excel. It works for the first audit cycle. By the second, the problems compound: no real-time collaboration, no version control that tracks who changed what and when, no automated reminders when reviews are overdue, no way to give different risk owners visibility of their items without sending them the whole workbook.
SharePoint Lists solve all of this without adding a new platform. If you're already on Microsoft 365, the List is included in your licence. You get version history, item-level permissions, calculated columns, conditional formatting, Power Automate integration, and views that different stakeholders can filter to their scope — all within the same tool your team uses every day.
The tradeoff is a little more setup effort upfront. This guide covers that setup in full so you don't have to figure it out trial and error.
ISO 27001, ISO 27701, and ISO 42001 each have their own risk assessment requirements. ISO 27001 Clause 6.1.2 requires you to identify information security risks. ISO 27701 extends that to privacy risks. ISO 42001 adds AI-specific risk assessment including model risk, shadow AI, and transparency obligations.
The temptation is to run three separate registers. Don't. A single integrated register with a Framework column (ISMS / PIMS / AIMS) is the correct answer for three reasons:
The Framework column lets any auditor filter to their scope. The same scoring methodology applies across all three. This is the structure the guide builds.
Build each column exactly as specified. The column type matters — calculated columns won't work if the source columns are the wrong type, and Power Automate flows reference internal column names.
| Column name | SharePoint type | Notes |
|---|---|---|
| Risk ID | Single line of text | Format: RISK-001. Set as the Title column or add alongside it. |
| Framework | Choice | Options: ISMS, PIMS, AIMS. Allow multiple — some risks span frameworks. |
| Category | Choice | Use the taxonomy from the scoring guide (Access & Identity, Shadow AI, etc.) |
| Risk Title | Single line of text | Short name, 5–10 words. Auditors scan this column first. |
| Risk Description | Multiple lines of text | Describe the threat, the mechanism, and the affected asset. 2–4 sentences. |
| Threat Source | Single line of text | E.g. External threat actor, Departing employee, Vendor change. |
| Affected Asset / Process | Single line of text | Be specific — "Microsoft 365 tenant" not "IT systems". |
| Inherent Likelihood | Number | Scale 1–5. Score before any controls are applied. |
| Inherent Impact | Number | Scale 1–5. Financial + operational + regulatory + reputational. |
| Inherent Score | Calculated | Formula: =[Inherent Likelihood]*[Inherent Impact] |
| Inherent Level | Calculated | Formula: =IF([Inherent Score]>=20,"Critical",IF([Inherent Score]>=15,"High",IF([Inherent Score]>=7,"Medium","Low"))) |
| Treatment | Choice | Options: Mitigate, Transfer, Avoid, Accept |
| Treatment Rationale | Multiple lines of text | Why this treatment? What controls specifically? Auditors read this. |
| Linked SoA Controls | Multiple lines of text | Reference SoA control IDs, e.g. A.5.15, A.5.16, A.8.2. One per line. |
| Residual Likelihood | Number | Scale 1–5. Score after controls are operating. |
| Residual Impact | Number | Scale 1–5. |
| Residual Score | Calculated | Formula: =[Residual Likelihood]*[Residual Impact] |
| Residual Level | Calculated | Formula: =IF([Residual Score]>=20,"Critical",IF([Residual Score]>=15,"High",IF([Residual Score]>=7,"Medium","Low"))) |
| Risk Owner | Person or Group | Single person. This drives Power Automate reminders. |
| Next Review Date | Date and Time | Drive this from Residual Level: Critical/High = +30 days, Medium = +90 days, Low = +365 days. |
| Last Reviewed | Date and Time | Updated manually or via a flow when status changes. |
| Status | Choice | Options: Identified, In Progress, Mitigated, Accepted, Transferred, Closed |
| Change Notes | Multiple lines of text | Append notes when scoring or treatment changes. Manual audit trail. |
Calculated column note: SharePoint calculated columns use a formula syntax similar to Excel but with some differences — wrap column names in square brackets, not quotes. Test each calculated column with a sample entry immediately after creating it.
Apply these directly in SharePoint via Column settings → Format this column → Advanced mode. Paste the JSON, save, and the column renders colour-coded badges automatically.
Renders Critical (red), High (orange), Medium (amber), Low (green) as pill badges. Apply to both the Residual Level and Inherent Level columns.
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"style": {
"display": "inline-block",
"padding": "4px 12px",
"border-radius": "20px",
"font-weight": "700",
"font-size": "0.78rem",
"text-transform": "uppercase",
"letter-spacing": "0.5px",
"color": "white",
"background-color": "=if([$ResidualLevel] == 'Critical', '#b91c1c', if([$ResidualLevel] == 'High', '#c2410c', if([$ResidualLevel] == 'Medium', '#b45309', '#15803d')))"
},
"txtContent": "[$ResidualLevel]"
} For the Inherent Level column, replace [$ResidualLevel] with [$InherentLevel] in both the background-color formula and txtContent.
Colour-codes each status value so the register's overall health is visible at a glance.
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"style": {
"display": "inline-block",
"padding": "4px 12px",
"border-radius": "20px",
"font-weight": "600",
"font-size": "0.78rem",
"color": "white",
"background-color": "=if([$Status] == 'Identified', '#6366f1', if([$Status] == 'In Progress', '#0284c7', if([$Status] == 'Mitigated', '#15803d', if([$Status] == 'Accepted', '#b45309', if([$Status] == 'Transferred', '#7c3aed', '#64748b')))))"
},
"txtContent": "[$Status]"
} Distinguishes treatment types visually — useful when reviewing the register distribution (too many Accepted risks in a single category is an audit flag).
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"style": {
"display": "inline-block",
"padding": "4px 12px",
"border-radius": "20px",
"font-weight": "600",
"font-size": "0.78rem",
"color": "white",
"background-color": "=if([$Treatment] == 'Mitigate', '#1d4ed8', if([$Treatment] == 'Transfer', '#7c3aed', if([$Treatment] == 'Avoid', '#0f766e', '#92400e')))"
},
"txtContent": "[$Treatment]"
} Turns the Next Review Date red when it's in the past and the risk isn't Closed or Mitigated. Makes overdue reviews impossible to miss.
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"style": {
"display": "inline-block",
"padding": "4px 10px",
"border-radius": "6px",
"font-weight": "=if(toDateString([$NextReviewDate]) < toDateString(now()) && [$Status] != 'Mitigated' && [$Status] != 'Closed', '700', '400')",
"color": "=if(toDateString([$NextReviewDate]) < toDateString(now()) && [$Status] != 'Mitigated' && [$Status] != 'Closed', 'white', '#0f172a')",
"background-color": "=if(toDateString([$NextReviewDate]) < toDateString(now()) && [$Status] != 'Mitigated' && [$Status] != 'Closed', '#b91c1c', 'transparent')"
},
"txtContent": "=toDateString([$NextReviewDate])"
} Each view serves a different purpose. Build all five and pin the most-used ones to the page. Go to View options → Create new view for each.
The default view. All columns visible. Sort by Residual Score descending so Critical risks always appear at the top. This is the view you use during risk committee meetings.
Sort: Residual Score (desc) → Framework (asc)
Set view type to Board. Group by Residual Level. Four lanes: Critical, High, Medium, Low. Drag items between lanes to update status during a risk workshop. Visually compelling for management presentations.
Group column: Residual Level
Group by Framework. ISMS / PIMS / AIMS collapse groups. Use this view when preparing audit evidence packs for a single-framework audit — collapse the other two groups and screenshot only the relevant one.
Group by: Framework → Sort by Residual Score (desc)
Filter: Risk Owner is equal to [Me]. Shows each person only their own risks. Share this view URL directly with risk owners. Combine with the Power Automate reminder flow so owners receive a link that lands them here.
Filter: Risk Owner = [Me]
Filter: Next Review Date is less than [Today] AND Status is not equal to Mitigated AND Status is not equal to Closed. Run this view at the start of every risk committee meeting as the standing agenda item for stale risks.
Filter: Next Review Date < [Today] AND Status ≠ Mitigated/Closed
Set view type to Board. Group by Status. Four active lanes: Identified → In Progress → Mitigated → Accepted. Shows your treatment pipeline at a glance. Risks sitting in Identified for more than 30 days need a conversation.
Group column: Status
Three flows that convert a static list into a managed risk programme. Build each in Power Automate → Create → Automated cloud flow (for the first two) or Scheduled cloud flow (for the third). All use the SharePoint connector.
Trigger: Scheduled · Runs daily at 8 AM
NextReviewDate le '[utcNow(addDays(7))]' and NextReviewDate ge '[utcNow()]' and Status ne 'Mitigated' and Status ne 'Closed'RiskOwner.Email dynamic value). Subject: Risk review due in 7 days — [Risk ID] [Risk Title]. Body: include Risk ID, Framework, Residual Level, Next Review Date, and a direct link to the list item.Tip: Add a condition before the email step: only send if Residual Level is not equal to "Low" — this suppresses noise for annual low-risk reviews that don't need 7-day advance notice.
Trigger: Automated · When a new item is created or modified in the list
ResidualLevel is equal to "Critical" OR ResidualLevel is equal to "High"⚠️ [Residual Level] risk logged — [Risk ID]: [Risk Title] · Framework: [Framework] · Owner: [Risk Owner] · Next Review: [Next Review Date] with a link to the item.Tip: Add a second condition inside the Yes branch to check if the Status is "Identified" — this prevents the flow from firing every time someone edits a description on an existing High risk.
Trigger: Scheduled · Runs every Monday at 7 AM
NextReviewDate lt '[utcNow()]' and Status ne 'Mitigated' and Status ne 'Closed' and Status ne 'Accepted'[count] overdue risk reviews — action required. Include a link to the Overdue Reviews view.Tip: Run this flow manually for the first time before scheduling it. "Get items" filter queries in SharePoint use OData syntax — test against your actual column internal names (visible in List Settings → Columns → click the column name and read the URL).
Having a risk register is necessary but not sufficient. These are the specific things ISO 27001 auditors check during sampling — and the most common gaps we see.
The single most common gap in risk registers we review. If your register only shows residual scores, auditors cannot verify that you understand the actual risk landscape. ISO/IEC 27005 is explicit that risk assessment includes identifying the risk before controls — the inherent score. A register that jumps straight to residual looks like the scores were chosen to justify existing controls rather than assess actual risk.
The audit trail that connects the risk register to the Statement of Applicability is what auditors follow during sampling. A risk with no Linked SoA Controls reference, or a SoA control with no risk driving its inclusion, both raise findings. The linkage proves the ISMS is genuinely integrated rather than two separate documents.
SharePoint's built-in version history covers this automatically — every edit is timestamped and attributed. What auditors check for is that the register has actually changed over time. A register with a single version entry from twelve months ago, or one where all items have "Mitigated" status and no review dates, signals that it was created for audit and then abandoned.
If a risk is above your stated risk acceptance threshold and the Treatment is "Accept", auditors expect to see documented management sign-off. Add a Risk Acceptance Sign-off column (multi-line text) or a SharePoint approval workflow for accepted risks. A risk above threshold with no documented acceptance rationale is a major nonconformity.
If you've also built your Statement of Applicability as a SharePoint List (the recommended approach for the same reasons this guide covers), link the two explicitly.
The cleanest implementation uses a Lookup column in each direction:
This bidirectional reference is what lets auditors follow the trail in either direction — from a risk to the controls treating it, or from a control back to the risks that justify its inclusion. It's the evidence that your management system is genuinely integrated, not a collection of independent documents.
Yes — and it's the correct answer. A Framework column (ISMS / PIMS / AIMS) lets each auditor filter to their scope. Many risks span frameworks legitimately. A single register with appropriate categorisation is what integrated management system auditors expect to see.
Yes, and this is one of the most common gaps we see in registers we review. Auditors want inherent risk (before controls) scored explicitly. Without it, they cannot verify you understand the actual risk landscape rather than working backwards from the controls you already have.
ISO 27001 Clause 8.2 requires reviews at planned intervals and when significant changes occur. In practice: Critical and High residual risks monthly, Medium quarterly, Low annually. The Next Review Date column and Power Automate reminder flow operationalise this without manual tracking.
Documented management sign-off is required. A risk above your stated acceptance threshold with Treatment set to "Accept" but no documented rationale or approver is a major nonconformity. Add a Risk Acceptance Sign-off column, or build a SharePoint approval workflow that captures the approver and date automatically.
Related services
We can deploy the full risk register — SharePoint List, column schema, conditional formatting, Power Automate flows, and pre-populated with example risks across your target frameworks — as part of a scoping engagement or standalone. A 30-minute call will tell you what your register currently covers and what auditors would flag.
Hi! I’m the Compliance365 AI. I can help you work out which security or privacy framework you need, explain what’s involved, and answer questions about ISO 27001, SOC 2, Essential Eight, and more.
What can I help you with today?