GRC Risk Event Summarization
SkillDev toolsSummarize risk events with impact assessment, affected controls, contributing factors, and recommended mitigation actions
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the GRC Risk Event Summarization skill
What this skill tells your AI
The instructions your AI receives, as published by happy-technologies-llc/happy-platform-skills in skills/grc/risk-event-summarization/SKILL.md and read by ahel’s review.
Overview
This skill generates comprehensive summaries of risk events in ServiceNow GRC, providing stakeholders with a complete picture of what happened, why it happened, what was affected, and what should be done in response.
Key capabilities:
- Event Context: Aggregate risk event details including timeline, category, and triggering conditions
- Impact Assessment: Quantify financial, operational, reputational, and regulatory impact of risk events
- Control Analysis: Identify which controls failed, were bypassed, or were absent when the event occurred
- Contributing Factor Analysis: Determine root causes and contributing factors leading to the event
- Mitigation Recommendations: Generate prioritized mitigation actions based on event severity and control gaps
- Trend Detection: Identify patterns across related risk events to surface systemic issues
When to use:
- After a risk event materializes and stakeholders need a structured briefing
- During risk committee meetings requiring event summaries
- When building a risk event register or loss event database
- For regulatory reporting on operational risk events
- When conducting post-event reviews or lessons-learned sessions
Prerequisites
- Roles:
sn_grc.manager,sn_risk.manager, oradmin - Plugins:
com.sn_grc,com.sn_risk,com.sn_compliance - Access: Read access to
sn_risk_event,sn_grc_risk,sn_compliance_control,sn_grc_issue,sn_grc_profile - Knowledge: Understanding of organizational risk taxonomy and event categorization standards
Key GRC Tables
| Table | Purpose | Key Fields |
|---|---|---|
sn_risk_event | Risk events / loss events | number, short_description, state, category, event_date, impact, likelihood, financial_impact, risk, profile |
sn_grc_risk | Associated risk records | number, risk_score, residual_risk, inherent_risk, treatment, state, category |
sn_compliance_control | Controls that should have mitigated the event | number, state, effectiveness, test_result, control_objective, owner |
sn_grc_issue | Issues generated from events | number, state, priority, risk_rating, source |
sn_risk_definition | Risk definitions and categories | number, short_description, risk_type, category |
sn_grc_profile | Entity profiles | number, profile_type, applies_to |
Procedure
Step 1: Retrieve Risk Event Details
Fetch the target risk event with full context fields.
Using MCP (Claude Code/Desktop):
Tool: SN-Get-Record
Parameters:
table_name: sn_risk_event
sys_id: [EVENT_SYS_ID]
fields: sys_id,number,short_description,description,state,category,subcategory,event_date,discovered_date,impact,likelihood,financial_impact,operational_impact,reputational_impact,regulatory_impact,risk,profile,assigned_to,assignment_group,root_cause,contributing_factors,sys_created_on
Using REST API:
GET /api/now/table/sn_risk_event?sysparm_query=number=[EVENT_NUMBER]&sysparm_fields=sys_id,number,short_description,description,state,category,subcategory,event_date,discovered_date,impact,likelihood,financial_impact,operational_impact,reputational_impact,regulatory_impact,risk,profile,assigned_to,root_cause,contributing_factors&sysparm_limit=1&sysparm_display_value=all
Step 2: Gather Associated Risk Context
Pull the risk record linked to the event to understand the broader risk landscape.
Using MCP:
Tool: SN-Query-Table
Parameters:
table_name: sn_grc_risk
query: sys_id=[event_risk_sys_id]
fields: sys_id,number,short_description,risk_score,state,treatment,residual_risk,inherent_risk,category,owner,risk_appetite,risk_tolerance
limit: 1
For all risks under the same profile:
Tool: SN-Query-Table
Parameters:
table_name: sn_grc_risk
query: profile=[event_profile_sys_id]^active=true
fields: sys_id,number,short_description,risk_score,residual_risk,inherent_risk,treatment,category
limit: 25
Using REST API:
GET /api/now/table/sn_grc_risk?sysparm_query=profile=[profile_sys_id]^active=true&sysparm_fields=sys_id,number,short_description,risk_score,residual_risk,inherent_risk,treatment,category&sysparm_limit=25&sysparm_display_value=all
Step 3: Identify Affected Controls
Query controls linked to the risk profile to determine which should have prevented the event.
Using MCP:
Tool: SN-Query-Table
Parameters:
table_name: sn_compliance_control
query: profile=[event_profile_sys_id]^active=true
fields: sys_id,number,short_description,state,control_objective,owner,effectiveness,test_result,test_date
limit: 50
Using REST API:
GET /api/now/table/sn_compliance_control?sysparm_query=profile=[profile_sys_id]^active=true&sysparm_fields=sys_id,number,short_description,state,control_objective,owner,effectiveness,test_result,test_date&sysparm_limit=50&sysparm_display_value=all
Step 4: Retrieve Work Notes and Investigation History
Pull investigation notes to capture analyst findings and contributing factor analysis.
Using MCP:
Tool: SN-Query-Table
Parameters:
table_name: sys_journal_field
query: name=sn_risk_event^element_id=[EVENT_SYS_ID]^element=work_notes^ORDERBYDESCsys_created_on
fields: value,sys_created_on,sys_created_by
limit: 25
Using REST API:
GET /api/now/table/sys_journal_field?sysparm_query=name=sn_risk_event^element_id=[event_sys_id]^element=work_notes^ORDERBYDESCsys_created_on&sysparm_fields=value,sys_created_on,sys_created_by&sysparm_limit=25
Step 5: Check for Related Issues and Historical Events
Identify GRC issues spawned from the event and similar past events.
Using MCP:
Tool: SN-Query-Table
Parameters:
table_name: sn_grc_issue
query: source_record=[EVENT_SYS_ID]^ORprofile=[event_profile_sys_id]
fields: sys_id,number,short_description,state,priority,risk_rating,source,sys_created_on
limit: 20
For historical pattern analysis:
Tool: SN-Query-Table
Parameters:
table_name: sn_risk_event
query: category=[event_category]^sys_id!=[EVENT_SYS_ID]^event_date>=javascript:gs.daysAgo(365)^ORDERBYDESCevent_date
fields: sys_id,number,short_description,category,event_date,financial_impact,state
limit: 25
Step 6: Generate Comprehensive Risk Event Summary
Using MCP:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var eventNumber = 'RE0001234'; // Replace with target event
var gr = new GlideRecord('sn_risk_event');
gr.addQuery('number', eventNumber);
gr.query();
if (!gr.next()) { gs.info('Event not found'); return; }
var summary = {
event: {
number: gr.number.toString(),
title: gr.short_description.toString(),
description: gr.description.toString(),
state: gr.state.getDisplayValue(),
category: gr.category.getDisplayValue(),
event_date: gr.event_date.getDisplayValue(),
discovered_date: gr.discovered_date.getDisplayValue(),
detection_lag_days: 0
},
impact_assessment: {
overall_impact: gr.impact.getDisplayValue(),
financial: gr.financial_impact.toString() || 'Not quantified',
operational: gr.operational_impact.getDisplayValue() || 'Not assessed',
reputational: gr.reputational_impact.getDisplayValue() || 'Not assessed',
regulatory: gr.regulatory_impact.getDisplayValue() || 'Not assessed'
},
affected_controls: [],
contributing_factors: [],
related_issues: [],
historical_pattern: { similar_events_12mo: 0, total_financial_loss: 0 },
mitigation_recommendations: []
};
// Detection lag
if (gr.event_date.toString() && gr.discovered_date.toString()) {
var evtDate = new GlideDateTime(gr.event_date.toString());
var discDate = new GlideDateTime(gr.discovered_date.toString());
summary.event.detection_lag_days = parseInt(gs.dateDiff(evtDate.toString(), discDate.toString(), true)) || 0;
}
// Contributing factors from record
if (gr.root_cause.toString()) summary.contributing_factors.push('Root Cause: ' + gr.root_cause.toString());
if (gr.contributing_factors.toString()) summary.contributing_factors.push('Factors: ' + gr.contributing_factors.toString());
var profileId = gr.profile.toString();
// Affected controls
var ctrl = new GlideRecord('sn_compliance_control');
ctrl.addQuery('profile', profileId);
ctrl.addQuery('active', true);
ctrl.query();
while (ctrl.next()) {
var ctrlStatus = ctrl.state.getDisplayValue();
var wasEffective = (ctrlStatus == 'Compliant' || ctrlStatus == 'Passed');
summary.affected_controls.push({
control: ctrl.number.toString(),
title: ctrl.short_description.toString(),
state: ctrlStatus,
effectiveness: ctrl.effectiveness.getDisplayValue(),
prevented_event: wasEffective,
owner: ctrl.owner.getDisplayValue()
});
if (!wasEffective) {
summary.contributing_factors.push('Control failure: ' + ctrl.number.toString() + ' (' + ctrlStatus + ')');
}
}
// Related issues
var issue = new GlideRecord('sn_grc_issue');
issue.addQuery('profile', profileId);
issue.addQuery('active', true);
issue.query();
while (issue.next()) {
summary.related_issues.push({
number: issue.number.toString(),
title: issue.short_description.toString(),
priority: issue.priority.getDisplayValue(),
state: issue.state.getDisplayValue()
});
}
// Historical pattern
var hist = new GlideRecord('sn_risk_event');
hist.addQuery('category', gr.category.toString());
hist.addQuery('sys_id', '!=', gr.sys_id.toString());
hist.addQuery('event_date', '>=', gs.daysAgo(365));
hist.query();
while (hist.next()) {
summary.historical_pattern.similar_events_12mo++;
summary.historical_pattern.total_financial_loss += parseFloat(hist.financial_impact.toString()) || 0;
}
// Generate mitigation recommendations
var failedControls = summary.affected_controls.filter(function(c) { return !c.prevented_event; });
if (failedControls.length > 0) {
summary.mitigation_recommendations.push('IMMEDIATE: Remediate ' + failedControls.length + ' failed controls identified during event analysis');
}
if (summary.event.detection_lag_days > 7) {
summary.mitigation_recommendations.push('SHORT-TERM: Improve detection capabilities - ' + summary.event.detection_lag_days + ' day detection lag exceeds acceptable threshold');
}
if (summary.historical_pattern.similar_events_12mo >= 3) {
summary.mitigation_recommendations.push('STRATEGIC: Investigate systemic root cause - ' + summary.historical_pattern.similar_events_12mo + ' similar events in past 12 months indicates pattern');
}
summary.mitigation_recommendations.push('ONGOING: Update risk assessment to reflect materialized event and adjust residual risk scores');
gs.info('RISK EVENT SUMMARY:\n' + JSON.stringify(summary, null, 2));
description: "GRC: Generate comprehensive risk event summary with impact assessment"
Step 7: Generate Executive Narrative
Using MCP:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var narrative = [];
narrative.push('=== RISK EVENT EXECUTIVE SUMMARY ===');
narrative.push('');
var agg = new GlideAggregate('sn_risk_event');
agg.addQuery('event_date', '>=', gs.daysAgo(90));
agg.addAggregate('COUNT');
agg.groupBy('category');
agg.query();
narrative.push('RISK EVENTS - LAST 90 DAYS BY CATEGORY:');
while (agg.next()) {
narrative.push(' ' + agg.category.getDisplayValue() + ': ' + agg.getAggregate('COUNT') + ' events');
}
narrative.push('');
// Top events by financial impact
narrative.push('TOP EVENTS BY FINANCIAL IMPACT:');
var top = new GlideRecord('sn_risk_event');
top.addQuery('event_date', '>=', gs.daysAgo(90));
top.addNotNullQuery('financial_impact');
top.orderByDesc('financial_impact');
top.setLimit(5);
top.query();
var idx = 1;
while (top.next()) {
narrative.push(' ' + idx + '. ' + top.number + ' - ' + top.short_description);
narrative.push(' Financial Impact: $' + top.financial_impact + ' | Category: ' + top.category.getDisplayValue());
idx++;
}
gs.info(narrative.join('\n'));
description: "GRC: Generate quarterly risk event narrative for leadership"
Tool Usage
| Operation | MCP Tool | REST Endpoint |
|---|---|---|
| Read Event | SN-Get-Record | GET /api/now/table/sn_risk_event/{sys_id} |
| Query Events | SN-Query-Table | GET /api/now/table/sn_risk_event |
| Query Controls | SN-Query-Table | GET /api/now/table/sn_compliance_control |
| Query Risks | SN-Query-Table | GET /api/now/table/sn_grc_risk |
| Aggregate Analysis | SN-Execute-Background-Script | POST /api/now/table/sys_trigger |
| Search Events | SN-Natural-Language-Search | N/A |
Best Practices
- Timeliness: Generate summaries within 24 hours of event discovery while details are fresh
- Quantify Impact: Always attempt to quantify financial impact, even as an estimate with confidence range
- Root Cause Depth: Distinguish between immediate causes and systemic contributing factors
- Control Mapping: Explicitly identify which controls should have prevented or detected the event
- Historical Context: Include trend data to distinguish one-off events from systemic patterns
- Actionable Recommendations: Every summary should end with specific, assignable mitigation actions
- Regulatory Awareness: Flag events that may trigger regulatory notification requirements
Troubleshooting
Risk Event Table Not Found
Symptom: sn_risk_event returns no results or table not found
Cause: The risk event table name may differ across ServiceNow versions; some use sn_risk_event while others use sn_grc_loss_event
Solution:
Tool: SN-Discover-Table-Schema
Parameters:
table_name: sn_risk_event
If not found, search for tables containing "risk_event" or "loss_event" in sys_db_object.
Financial Impact Field Empty
Symptom: Financial impact data is consistently null despite events having known costs
Cause: Financial impact may be tracked in a related loss record rather than on the event itself
Solution: Check for related tables like sn_risk_loss or custom financial impact assessment records linked via reference fields.
No Controls Linked to Event Profile
Symptom: Control analysis returns empty results for the event profile
Cause: The event may not be linked to a GRC profile, or controls use a different relationship path
Solution: Check the item field on the event instead of profile, or query sn_grc_m2m_item_profile for the relationship mapping.
Examples
Example 1: Operational Risk Event Summary
Scenario: System outage event RE0002345 affecting payment processing
- Event: Unplanned outage of payment gateway, 4-hour duration
- Detection Lag: 15 minutes (automated monitoring alert)
- Financial Impact: $180,000 in lost transaction revenue
- Failed Controls: 2 -- disaster recovery test (not tested in 14 months), capacity monitoring threshold (set too high)
- Contributing Factors: Infrastructure change without proper testing, single point of failure in payment routing
- Similar Events (12 months): 2 prior events totaling $95,000
- Recommendations: Update DR testing schedule, lower capacity thresholds, implement redundant payment routing
Example 2: Compliance Risk Event Summary
Scenario: Data breach event RE0003001 involving customer PII exposure
- Event: Unauthorized access to customer database via compromised service account
- Detection Lag: 12 days (flagged by external security researcher)
- Records Affected: 15,000 customer records
- Regulatory Impact: GDPR Article 33 notification required within 72 hours
- Failed Controls: 3 -- privileged access review, service account rotation, database activity monitoring
- Recommendations: Immediate credential rotation, deploy database activity monitoring, establish 72-hour notification procedure
Related Skills
grc/issue-summarization- Summarize GRC issues generated from risk eventsgrc/risk-assessment-summarization- Broader risk assessment contextgrc/suggest-remediation-tasks- Generate remediation tasks for event-related control gapsgrc/regulatory-alert-analysis- Identify regulatory implications of risk eventsgrc/control-objective-management- Manage controls affected by events
Signals
- GitHub stars
- 37
- Forks
- 13
- Last commit
- Jul 2026
Advanced
- Catalog kind
- skill
- Gateway key
risk-event-summarization- Source
- github.com/happy-technologies-llc/happy-platform-skills