How to configure GRC User hierarchy access control for custom tablesSummaryIn GRC: Profiles app version 14.x.x, we are introducing a framework which helps us enable user hierarchy access control on any table in servicenow instance. We are also shipping user hierarchy access control pre-configured on some of out of the box GRC tables which underneath uses the same framework mentioned. User hierarchy of a user means anyone who belongs to management chain above the user including the user i.e user, user's manager, user's manager's manager so on till the top of hierarchy. If the access control has been setup for a table in such a way that only the assignee/approver/owner etc are allowed to read the record, in that case the manager chain of user in question would not have access to the record. If the use case is that apart from the assignee/approver/owner etc. their manager hierarchy should also be able to access the record, in that case the User hierarchy access control comes into the picture and the framework helps us achieve that.Instructions Create 3 new fields in the table on which user hierarchy access control has to be configured namely User hierarchy 1, User hierarchy 2, and User hierarchy status. If the User hierarchy has to be enabled only for one field instead of two, you can skip creating User hierarchy 2 field. User hierarchy 1 and User hierarchy 2 fields are reference type fields referencing table User hierarchy[sn_grc_user_hierarchy]. User hierarchy status field is a string field having two choices labeled Processed(value = "1") and Awaiting Processing(value="2").Create an additional read ACL on the table. The requires role should have the roles which are required to have read access to the table. These roles will vary table to table. The condition be same as the one in example screenshot. The dot walked hierarchy field from User hierarchy 1 should CONTAIN ME OR the dot walked hierarchy field from User hierarchy should CONTAIN ME. Example ACL The script of ACL should be : new sn_grc.UserHierarchyUtils().userHierarchyAccessControlEnabledForTable("<table name eg. sn_risk_risk>"); 3. There has to be a daily scheduled job per application scope (eg. sn_grc(GRC profiles scope), sn_risk(GRC: Risk management) scope etc.) which will trigger user hierarchy processing(calculation) events for all the tables in those app scope. All the records for which user hierarchy status field has value Awaiting processing, the user hierarchy for the fields for which we have configured it to be calculated, have to be updated in User hierarchy 1 and User hierarchy field 2. These scheduled jobs take care of this process. If there is an existing such scheduled job in the application scope of your table(either preshipped or created by you), you can skip creating this scheduled job. But if it is not present, you should create a scheduled job[sysauto_script] namely "Trigger user hierarchy processing events for <Application name> scope tables". The job triggers events for each table whose script action would process records in a BATCHED fashion. Example Scheduled job Script code: var events = new sn_grc.UserHierarchyUtils().triggerEventsForUserHierarchyProcessingInScope("<app scope eg. sn_risk>"); for(var eventIndex in events){ var event = events[eventIndex]; gs.eventQueue(event.eventName, null, event.parm1, null, event.queue); } 4. There has to be an event registry record per application scope which is being triggered by the scheduled job configured above. If you skipped creating the scheduled job in step 3, you must already be having this event registry record as well and hence you can skip this step too. Else create an event registry record like the below example. 5. Write a script action for the event registry we created in step 4 namely “Process <scope> tables for user hierarchy”. Example script action Script action code var retrigger = new sn_grc.UserHierarchyUtils().processRecordsForUserHierarchy(event.parm1); if(retrigger){ gs.eventQueue(event.name, null, event.parm1, null, event.queue); } 6. Create a record in User Hierarchy configuration table[sn_grc_user_hierarchy_configuration] for the table on which you are configuring user hierarchy feature. Choose the table, User reference fields in the table on which configuring(User reference field 1 and User reference field 2 for eg. assignee, owner, approver etc. These are the fields which hold a reference to sys_user table. The management hierarchy of users present in these fields have to be given access to the record), User hierarchy reference fields in the table(User hierarchy field 1 and User hierarchy field 2. These are the fields we created in step 1.), User hierarchy status field in the table(User hierarchy status. The field we created in step 1), and the event to be triggered by the daily scheduled job running to process user hierarchy which was created for the scope of the concerned table. We created this event in step 4. Example record: Note that in above example, we have configured only User reference field 1 because we want to enable user hierarchy access control only for one user reference field. 7. Create a before business rule on the table which should run on INSERT/UPDATE. This business rule changes the User hierarchy status of the record to “Awaiting processing” and raises an event to update the user hierarchy quickly rather than waiting for the JOB to run(If you do not want this to happen, you can skip triggering this event). This event is raised only for updates that are done by the user interactively. If you want the event to be raised for all kind of updates including updates via script etc as well(this might cause performance issues in case of bulk updates), you can do so by removing the condition gs.isInteractive(). Example Business rule Business rule condition new sn_grc.UserHierarchyUtils().recordHierarchyStatusHasToBeChanged(current) Business rule script (function executeRule(current, previous /*null when async*/) { new sn_grc.UserHierarchyUtils().changeRecordUserHierarchyStatusToAwaitingProcessing(current); if(gs.isInteractive() && current.operation() == "update"){ gs.eventQueue("sn_risk.update_risk_record_user_hier",current); } })(current, previous); NOTE: In place of “sn_risk.update_risk_record_user_hier”, put your own event name which we will created in next step. 8. Create an event in event registry namely “Update_<table name>_record_user_hier” for the concerned table. This event will be triggered by the business rule on the table which we created in step 7. Example event registry record 9. Create a script action for the event we created in step 7 namely “Update <Table name> record user hier”. Example script action Script: new sn_grc.UserHierarchyUtils().processRecordForUserHierarchy(current);