How to enable confidentiality inheritance on GRC tablesSummaryConfidentiality inheritance feature is introduced as part of Utah release.Confidentiality feature allows user to mark a record as confidential, but with this inheritance feature whenever user marks a record as confidential , its related records can be automatically marked as confidential and it is hierarchical.This is achieved through the inheritance of confidential flag from parent record to its related records. Example - As inheritance of confidential flag is hierarchical - Let Risk event, Issue and Remediation tasks be confidentiality enabled tables and confidentiality inheritance configuration is configured between Risk event to Issue and Issue to Remediation task. When Risk event record becomes confidential, Issue record will be automatically marked as confidential, same applies for Issues to Remediation tasks. Let RE1 be record of Risk event , I1 be record of Issue, RT1 be record of Remediation task. RE1 is related to I1 and RT1 is related to I1. When user marks RE1 as confidential , I1 which is directly related to RE1 will be marked as confidential because of inheritance configuration between Risk event and Issue.RT1 will also become confidential because RT1 is related to I1 and there is confidentiality inheritance configuration between Issue and Remediation task tables. So, marking RE1 results in marking I1 and RT1. Terminology Parent table - Any table in GRC. Related table - Table related to parent table through one to many , many to many or scripted relationship. Prerequisites - To use this feature both the parent and related tables should be confidentiality enabled and there must be confidentiality configuration record for each table.There must be business rules and client scripts on parent tables which supports this feature as mentioned in Instructions section. KB to enable confidentiality on GRC tables - KB1497382 Known facts Existing confidential records in the system will not be affected with this new feature.Inheritance of confidential flag takes place when parent tables record becomes confidential either though manual marking or through some scripts.When related records becomes confidential via parent, allowed users and allowed groups of that parent will get access to related records.When parent record becomes confidential, only non-confidential related records will become confidential, if there are any related records which are already confidential they will remain unchanged.Inheritance of confidential flag only works at the point of marking parent record as confidential, once parent record is marked as confidential and saved, changing allowed users/allowed groups on parent will not modify related record's allowed users/groups. Adding new related record to parent confidential record will not result in automatic marking of related record as confidential.When unmarking confidential flag on parent record, related records can be automatically unmarked at the same time.Related records will be unmarked only if the user who is removing confidentiality on parent record has access to related records. Note: This feature is not intended to be used on marking huge number of related records as confidential as it may lead to performance issues.Avoid using this feature on libraries like Entities,Entity types and control objectives, etc. Confidentiality inheritance set up is pre-shipped for the following tables - issue, remediation task, audit task, engagement, policy exception, risk event, observation, evidence request task. But user has to create confidentiality inheritance configuration record, please refer to STEP 3 in instructions.To enable confidentiality inheritance on other GRC tables please follow the below instructions.InstructionsNote: All the below configuration (client scripts/business rules) should be in the same scope as that of the table. Create below business rules and client scripts only on parent table. Ex - If Issue is parent table and Remediation task is related table , then create business rules and client scripts only on Issue table. Step 1 - Business rules a. Type: After insert/update business rule This business rule is used to process inheritance of confidentiality on related records when parent record gets marked as confidential. Name: Can be anything (Suggested name Mark related records as confidential for easy tracking in case of case tasks ) Table : Any table on which confidentiality is enabled The Advanced flag should be turned on and the When field on the business rule should be after, Insert and Update flags should be true. Add the filter conditions as mentioned in the screenshot . In the script in Advanced section, write the below script new sn_grc.GRCSecurityManager().processConfidentialityInheritance(current); STEP 2 - Client scripts These are used for running the logic when removing confidentiality on parent record.Just like inheritance of confidentiality to related records ,while removing confidentiality on parent record, its related records can also be unmarked confidential at the same time. Attaching the below client script which highlights the important fields to select(Table, UI Type, Type, FieldName ) while writing client scripts. a. On change client script for desktop, when confidential flag is unchecked on parent record, a pop-up is shown asking user confirmation to remove confidentiality on related records or to remove confidentiality only on parent record. Name: Can be anything (Suggested name Remove confidentiality popup for easy tracking in case of case tasks ) Table : Any table on which confidentiality is enabled UI Type: Desktop (For showing popup on heisenberg) Type: onChange Field name: Confidential flag on selected table function onChange(control, oldValue, newValue, isLoading, isTemplate) { if (isLoading || newValue === '') { return; } if(newValue == "true" || g_scratchpad.removeChildConfidentiality) { return true; } var ga = new GlideAjax("sn_grc.GRCSecurityManagerAjax"); ga.addParam("sysparm_name", "validateRemoveConfidentialityPopUp"); ga.addParam("sysparm_table", g_form.getTableName()); ga.addParam("sysparm_recordId",g_form.getUniqueValue()); ga.addParam("sysparm_confidentiality_value",newValue); ga.getXMLAnswer(function(answer) { if (answer == "true") { var modal = new GlideModal("sn_grc_remove_confidentiality_confirm"); modal.setTitle(getMessage("Remove confidentiality")); modal.setBackdropStatic(true); modal.render(); } }); } b. On change client script for workspace , when confidential flag is unchecked on parent record, a pop-up is shown asking user confirmation to remove confidentiality on related table records or to remove confidentiality only on parent record. Name: Can be anything (Suggested name Remove confidentiality popup - ws for easy tracking in case of case tasks ) Table : Any table on which confidentiality is enabled UI Type: Mobile/Service portal (For showing popup on workspace) Type: onChange Field name: Confidential flag on selected table function onChange(control, oldValue, newValue, isLoading, isTemplate) { if (isLoading || newValue === '') { return; } if(newValue == "true" || g_scratchpad.removeChildConfidentiality) { return true; } var ga = new GlideAjax("sn_grc.GRCSecurityManagerAjax"); ga.addParam("sysparm_name", "validateRemoveConfidentialityPopUp"); ga.addParam("sysparm_table", g_form.getTableName()); ga.addParam("sysparm_recordId",g_form.getUniqueValue()); ga.addParam("sysparm_confidentiality_value",newValue); ga.getXMLAnswer(function(answer) { if (answer == "true") { showConfirmationModel(); } }); function showConfirmationModel() { var message = getMessage('You can remove confidentiality of this single record or all downstream records with confidential inheritance configured. The option will be saved when you save the record.'); g_modal.confirm(getMessage('Remove confidentiality'), message, "",{ "cancelTitle": "Only this record", "confirmTitle": "Include downstream" }).then( function onSuccess() { g_scratchpad.removeChildConfidentiality="true"; }, function onReject() { g_scratchpad.removeChildConfidentiality="false"; } ); } } c. On save client script , user's choice from pop-up is implemented when user saves the form. Name: Can be anything (Suggested name Remove confidentiality onSave for easy tracking in case of case tasks ) Table : Any table on which confidentiality is enabled UI Type: ALL Type: onSubmit function onSubmit() { var confidentialityField = g_scratchpad.confidentialFlag; if (g_scratchpad.removeChildConfidentiality == "true" && (g_form.getValue(confidentialityField) == "false")) { var ga = new GlideAjax('sn_grc.GRCSecurityManagerAjax'); ga.addParam('sysparm_name', 'removeConfidentialityThroughInheritanceConfig'); ga.addParam('sysparm_recordId', g_form.getUniqueValue()); ga.addParam('sysparm_tableName', g_form.getTableName()); ga.getXML(function(response) { var answer = JSON.parse(response.responseXML.documentElement.getAttribute("answer")); }); } } STEP 3 - Confidentiality inheritance configuration (MUST) Confidentiality inheritance configuration needs to be created between parent and related tables after enabling confidentiality on parent and related tables, and performing above setup on parent table. Navigate to GRC Administration > Confidentiality Configuration 1.Open confidentiality configuration record of parent table. 2.From confidentiality inheritance related list , select NEW. Main table : Auto populated with parent table. Inheriting table: Select related table which should inherit confidentiality from parent . Select relationship type : Select relationship type existing between parent and related table. If relationship type is, 1. One to many - Select reference to main table from inheriting table 2. Many to many - Select relationship table(M2M) existing between parent and related tables.Also select reference to parent table from relationship table. 3. Scripted - Select scripted relationship existing between parent and related tables. Attaching example screenshot of inheritance configuration between issue and remediation task. Optional related list action set up - Confidentiality inheritance works only at the time of marking parent record as confidential. If new related records are added to parent confidential record , they will not be automatically marked as confidential. User can manually mark newly added records or they can make use of below related list action which inherits confidentiality from parent. Name : Can be anything (Suggested Mark confidential via parent) Table : Related table to parent Active, Show insert, Show update, Client, List v2 compatible ,List banner button,List choice should be true/checked. Onclick markConfidentiality() Condition RP.isRelatedList() && new sn_grc.GRCSecurityManager().verifyInherianceConfigBtwParentAndChild(current,parent); Script function markConfidentiality() { var ajax = new GlideAjax('sn_grc.GRCSecurityManagerAjax'); ajax.addParam('sysparm_childIds',g_list.getChecked()); ajax.addParam('sysparm_childTable',g_list.tableName); ajax.addParam('sysparm_parentTable',g_list.parentTable); ajax.addParam('sysparm_relation',g_list.related); ajax.addParam('sysparm_parentSysId',g_form.getUniqueValue()); ajax.addParam('sysparm_name','markRelatedListRecordsConfidential'); ajax.getXMLAnswer(function(answer) { if(answer) g_form.addInfoMessage(JSON.parse(answer)); g_list.refresh(); }); } Note : You can add your own conditions and roles check to the Ui action if required. Example screenshot of related list action on remediation task table.