<< All versions
Skill v1.0.1
Automated scan100/100serac-labs/serac/grc-compliance
+3 new, ~1 modified
──Details
PublishedMay 14, 2026 at 08:43 PM
Content Hashsha256:e98389770b9bf69f...
Git SHAb565cce09350
Bump Typepatch
──Files
Files (1 file, 11.4 KB)
SKILL.md11.4 KBactive
SKILL.md · 456 lines · 11.4 KB
version: "1.0.1" name: grc-compliance description: Build ServiceNow GRC — sn_compliance_policy lifecycle, sn_compliance_control tests, sn_risk_risk assessment with inherent/residual scoring, audit engagements, and findings remediation. license: Apache-2.0 compatibility: Designed for Snow-Code and ServiceNow development metadata: author: groeimetai version: "1.0.0" category: servicenow tools:
- snow_query_table
- snow_execute_script_with_output
- snow_audit_compliance
- snow_assess_risk
GRC & Compliance for ServiceNow
GRC (Governance, Risk, Compliance) manages organizational policies, risks, and regulatory compliance.
GRC Architecture
Policy (sn_compliance_policy)└── Policy Statements└── Controls (sn_compliance_control)└── Control Tests└── Test ResultsRisk (sn_risk_risk)├── Risk Assessment└── Risk Response
Key Tables
| Table | Purpose | |
|---|---|---|
sn_compliance_policy | Compliance policies | |
sn_compliance_control | Controls | |
sn_compliance_control_test | Control tests | |
sn_risk_risk | Risk records | |
sn_audit_engagement | Audit engagements |
Policies (ES5)
Create Policy
javascript
// Create compliance policy (ES5 ONLY!)var policy = new GlideRecord("sn_compliance_policy")policy.initialize()// Basic infopolicy.setValue("name", "Information Security Policy")policy.setValue("description", "Enterprise information security requirements")policy.setValue("short_description", "InfoSec Policy")// Classificationpolicy.setValue("category", "security")policy.setValue("type", "corporate")// Ownerpolicy.setValue("owner", policyOwnerSysId)policy.setValue("owning_group", securityTeamSysId)// Statuspolicy.setValue("state", "draft")// Datespolicy.setValue("effective_date", "2024-01-01")policy.setValue("review_date", "2025-01-01")policy.insert()
Policy Lifecycle
javascript
// Transition policy state (ES5 ONLY!)function transitionPolicy(policySysId, newState, notes) {var policy = new GlideRecord("sn_compliance_policy")if (!policy.get(policySysId)) {return { success: false, message: "Policy not found" }}var validTransitions = {draft: ["review", "retired"],review: ["approved", "draft"],approved: ["published", "draft"],published: ["review", "retired"],retired: ["draft"],}var currentState = policy.getValue("state")if (!validTransitions[currentState] || validTransitions[currentState].indexOf(newState) === -1) {return { success: false, message: "Invalid transition" }}policy.setValue("state", newState)if (newState === "published") {policy.setValue("published_date", new GlideDateTime())}if (notes) {policy.work_notes = notes}policy.update()return { success: true, state: newState }}
Controls (ES5)
Create Control
javascript
// Create compliance control (ES5 ONLY!)var control = new GlideRecord("sn_compliance_control")control.initialize()// Basic infocontrol.setValue("name", "Access Control Review")control.setValue("description", "Quarterly review of user access rights")control.setValue("short_description", "Access Review Control")// Link to policycontrol.setValue("policy", policySysId)// Classificationcontrol.setValue("type", "detective") // preventive, detective, correctivecontrol.setValue("category", "access_control")control.setValue("frequency", "quarterly")// Ownercontrol.setValue("owner", controlOwnerSysId)// Testingcontrol.setValue("test_frequency", "quarterly")control.setValue("test_type", "manual")// Statuscontrol.setValue("state", "draft")control.insert()
Control Testing
javascript
// Create control test (ES5 ONLY!)function createControlTest(controlSysId, testData) {var test = new GlideRecord("sn_compliance_control_test")test.initialize()test.setValue("control", controlSysId)test.setValue("name", testData.name)test.setValue("description", testData.description)// Test detailstest.setValue("test_type", testData.type) // design, operatingtest.setValue("planned_start", testData.plannedStart)test.setValue("planned_end", testData.plannedEnd)// Assignmenttest.setValue("assigned_to", testData.tester)// Statustest.setValue("state", "open")return test.insert()}// Record test resultfunction recordTestResult(testSysId, result) {var test = new GlideRecord("sn_compliance_control_test")if (!test.get(testSysId)) {return false}test.setValue("state", "closed")test.setValue("result", result.outcome) // pass, fail, not_testedtest.setValue("actual_end", new GlideDateTime())test.setValue("findings", result.findings)test.setValue("evidence", result.evidence)// If failed, create issueif (result.outcome === "fail") {createComplianceIssue(test, result)}test.update()return true}
Risk Management (ES5)
Create Risk
javascript
// Create risk record (ES5 ONLY!)var risk = new GlideRecord("sn_risk_risk")risk.initialize()// Basic inforisk.setValue("name", "Data Breach Risk")risk.setValue("description", "Risk of unauthorized access to customer data")risk.setValue("short_description", "Data Breach")// Classificationrisk.setValue("category", "security")risk.setValue("subcategory", "data_protection")// Risk assessmentrisk.setValue("inherent_likelihood", 3) // 1-5 scalerisk.setValue("inherent_impact", 5) // 1-5 scale// Inherent risk = likelihood x impact// Controls that mitigate this riskrisk.setValue("controls", controlSysIds) // Comma-separated// Residual risk (after controls)risk.setValue("residual_likelihood", 2)risk.setValue("residual_impact", 5)// Ownerrisk.setValue("owner", riskOwnerSysId)// Statusrisk.setValue("state", "assess")risk.insert()
Risk Assessment
javascript
// Calculate risk score (ES5 ONLY!)function calculateRiskScore(likelihood, impact) {var score = likelihood * impactvar rating = "low"if (score >= 20) {rating = "critical"} else if (score >= 12) {rating = "high"} else if (score >= 6) {rating = "medium"}return {score: score,rating: rating,}}// Assess risk and update record (ES5 ONLY!)function assessRisk(riskSysId, assessment) {var risk = new GlideRecord("sn_risk_risk")if (!risk.get(riskSysId)) {return false}// Update inherent riskrisk.setValue("inherent_likelihood", assessment.inherentLikelihood)risk.setValue("inherent_impact", assessment.inherentImpact)var inherentScore = calculateRiskScore(assessment.inherentLikelihood, assessment.inherentImpact)risk.setValue("inherent_risk_score", inherentScore.score)risk.setValue("inherent_risk_rating", inherentScore.rating)// Update residual riskrisk.setValue("residual_likelihood", assessment.residualLikelihood)risk.setValue("residual_impact", assessment.residualImpact)var residualScore = calculateRiskScore(assessment.residualLikelihood, assessment.residualImpact)risk.setValue("residual_risk_score", residualScore.score)risk.setValue("residual_risk_rating", residualScore.rating)// Assessment metadatarisk.setValue("assessed_date", new GlideDateTime())risk.setValue("assessed_by", gs.getUserID())risk.setValue("state", "monitor")risk.update()return true}
Audits (ES5)
Create Audit Engagement
javascript
// Create audit engagement (ES5 ONLY!)var audit = new GlideRecord("sn_audit_engagement")audit.initialize()audit.setValue("name", "Q1 2024 SOX Audit")audit.setValue("description", "Quarterly SOX compliance audit")audit.setValue("type", "compliance")// Datesaudit.setValue("planned_start", "2024-01-15")audit.setValue("planned_end", "2024-02-15")// Scopeaudit.setValue("scope", "Financial controls, access management")// Teamaudit.setValue("lead_auditor", auditorSysId)audit.setValue("audit_team", auditTeamSysId)// Statusaudit.setValue("state", "planning")audit.insert()
Audit Findings
javascript
// Create audit finding (ES5 ONLY!)function createAuditFinding(auditSysId, findingData) {var finding = new GlideRecord("sn_audit_finding")finding.initialize()finding.setValue("engagement", auditSysId)finding.setValue("title", findingData.title)finding.setValue("description", findingData.description)// Severityfinding.setValue("severity", findingData.severity) // critical, high, medium, low// Related controlif (findingData.control) {finding.setValue("control", findingData.control)}// Recommendationfinding.setValue("recommendation", findingData.recommendation)// Owner for remediationfinding.setValue("owner", findingData.owner)// Due date for remediationfinding.setValue("due_date", findingData.dueDate)finding.setValue("state", "open")return finding.insert()}
Compliance Reporting (ES5)
Compliance Dashboard Data
javascript
// Get compliance summary (ES5 ONLY!)function getComplianceSummary() {var summary = {policies: { total: 0, published: 0, review_needed: 0 },controls: { total: 0, effective: 0, failed: 0 },risks: { critical: 0, high: 0, medium: 0, low: 0 },audits: { open: 0, findings: 0 },}// Policiesvar ga = new GlideAggregate("sn_compliance_policy")ga.addAggregate("COUNT")ga.groupBy("state")ga.query()while (ga.next()) {var count = parseInt(ga.getAggregate("COUNT"), 10)summary.policies.total += countif (ga.getValue("state") === "published") {summary.policies.published = count}}// Risks by ratingga = new GlideAggregate("sn_risk_risk")ga.addQuery("active", true)ga.addAggregate("COUNT")ga.groupBy("residual_risk_rating")ga.query()while (ga.next()) {var rating = ga.getValue("residual_risk_rating")var riskCount = parseInt(ga.getAggregate("COUNT"), 10)if (summary.risks.hasOwnProperty(rating)) {summary.risks[rating] = riskCount}}return summary}
MCP Tool Integration
Available Tools
| Tool | Purpose | |
|---|---|---|
snow_query_table | Query GRC tables | |
snow_execute_script_with_output | Test GRC scripts | |
snow_audit_compliance | Run compliance audits | |
snow_assess_risk | Risk assessment |
Example Workflow
javascript
// 1. Query active policiesawait snow_query_table({table: "sn_compliance_policy",query: "state=published",fields: "name,category,effective_date,review_date",})// 2. Find high risksawait snow_query_table({table: "sn_risk_risk",query: "residual_risk_rating=high^ORresidual_risk_rating=critical",fields: "name,category,residual_risk_score,owner",})// 3. Get compliance summaryawait snow_execute_script_with_output({script: `var summary = getComplianceSummary();gs.info(JSON.stringify(summary));`,})
Best Practices
- Clear Ownership - Assign policy/control/risk owners
- Regular Reviews - Schedule periodic assessments
- Evidence Collection - Document control effectiveness
- Risk Quantification - Use consistent scoring
- Audit Trail - Track all changes
- Automation - Automate testing where possible
- Reporting - Regular compliance dashboards
- ES5 Only - No modern JavaScript syntax