jaikishan1
ServiceNow Employee
ServiceNow Employee

Overview

Many organizations using the ServiceNow GRC (Governance, Risk, and Compliance) platform face challenges when customizing the risk assessment component to meet specific business requirements. One common request involves enforcing additional validations that prevent assessment submission until certain fields are completed.

This article outlines a method to implement custom validations using the existing Risk Assessment Validation API. By following the steps provided, customers can enhance out-of-the-box (OOTB) validations to suit their unique use cases.


Out-of-the-Box Validations

By default, ServiceNow provides the following validations during a risk assessment. When these validations fail, an error record is created, highlighted within the assessment, and shown in the error side panel:

  1. Mandatory factors not answered

  2. Residual risk score greater than inherent risk score

  3. Validate risk response mandatory

  4. Validate last state comments

  5. Validate overridden fields and comments

  6. Validate control environment assessment

  7. Validate target risk overall assessment

However, additional custom validations can be implemented to cater to business-specific requirements.


Step-by-Step Guide to Adding Custom Validations

1. Define or Create an Exception Category

Create a new sn_grc_exception record for your validation use case using a background script. Alternatively, you can use an existing exception record if appropriate.

2. Extend the Validation Logic

Navigate to the Script Include:
RiskAssessmentValidationUtils (sys_script_include.do?sys_id=77f6aa4d431e5210db95b0e9bfb8f2b5)

  • Copy the validateSingleRiskAssessment() function from RiskAssessmentValidationUtilsBase.

  • Paste and extend it in your custom Script Include.

  • Within this function, after the existing OOTB validations, invoke a custom function to perform your validations.


3. Pattern for Adding Custom Validations

Use the following code structure to implement your validation logic:

 

javascript
// Add logic to get sourceTable, sourceRecord based on validation use case
var errorPresent = new sn_risk_advanced.RiskAssessmentValidationHelperUtils().getUniqueOpenErrorRecord(
    sourceTable, sourceRecord, fieldName, riskAsmtId, state, exceptionCategory
);

if (!gr.getValue(fieldName) && !errorPresent) {
    // Create error record
    new sn_risk_advanced.RiskAssessmentValidationHelperUtils().createRiskAsmtErrorRecord(
        sourceTable, sourceRecord, fieldName, riskAssessmentId, exceptionCategory, asmtType, description
    );
} else if (!gr.getValue(fieldName) && errorPresent) {
    // Re-open error
    new sn_risk_advanced.RiskAssessmentValidationHelperUtils().changeRiskAsmtErrorRecordState(errorPresent, "1");
} else if (gr.getValue(fieldName) && errorPresent) {
    // Resolve error
    new sn_risk_advanced.RiskAssessmentValidationHelperUtils().changeRiskAsmtErrorRecordState(errorPresent, "2");
}

Replace variables like sourceTable, sourceRecord, and fieldName based on your validation context.


4. Example: Validate Comments for Each Inherent Factor

This example checks that a comment is provided for each factor in the Inherent Assessment:

 

javascript

var exceptionCategory = '178310c1434b4210db95b0e9bfb8f2fd';
var riskAssessmentId = asmt.getUniqueValue();
var gr = new GlideRecord("sn_risk_advanced_risk_assessment_instance_response");

gr.addQuery("assessment_instance_id", riskAssessmentId);
gr.addQuery("factor.sys_class_name", "!=", "sn_risk_advanced_group_factor");
gr.addQuery("assessment_type", "=", "1");
gr.query();

while (gr.next()) {
    var errorPresent = new sn_risk_advanced.RiskAssessmentValidationHelperUtils().getUniqueOpenErrorRecord(
        gr.getTableName(), gr.getUniqueValue(), "additional_comments", riskAssessmentId, "", exceptionCategory
    );

    if (!gr.getValue("additional_comments") && !errorPresent) {
        new sn_risk_advanced.RiskAssessmentValidationHelperUtils().createRiskAsmtErrorRecord(
            gr.getTableName(), gr.getUniqueValue(), "additional_comments", riskAssessmentId, exceptionCategory,
            gr.getValue("assessment_type"), 'Please provide comments for ' + gr.getDisplayValue('factor')
        );
    } else if (!gr.getValue("additional_comments") && errorPresent) {
        new sn_risk_advanced.RiskAssessmentValidationHelperUtils().changeRiskAsmtErrorRecordState(errorPresent, "1");
    } else if (gr.getValue("additional_comments") && errorPresent) {
        new sn_risk_advanced.RiskAssessmentValidationHelperUtils().changeRiskAsmtErrorRecordState(errorPresent, "2");
    }
}

Conclusion

By leveraging the existing validation architecture within ServiceNow GRC, customers can seamlessly integrate additional business-specific rules into the risk assessment process. These enhancements ensure greater control, consistency, and compliance during assessment activities.

A step-by-step walkthrough of this implementation is also provided in the accompanying video.


Comments
Sushma Rudraya1
Tera Contributor

where are you deleting the error records ? this same code keeps generating the error records in open state when we click on validate each time. 

Version history
Last update:
‎06-05-2025 03:54 AM
Updated by: