Preventing Security Leakage with Query Business Rules on Child Tables in ServiceNow
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 hours ago
Use Case
Sensitive catalog items (like User Offboarding) should only be visible to certain groups — HR, Finance, IT Helpdesk, and the Management team.
For example:
HR needs to view RITMs and Catalog Tasks for User Offboarding.
Finance only needs to view finance-related tasks.
IT Helpdesk needs IT-specific tasks.
Management team needs oversight visibility.
All these records live under child tables (sc_req_item, sc_task) but extend the Task table.
The requirement is: Restrict access so only the right groups can see RITMs and Tasks for User Offboarding.
Problem Statement
If you try to handle this restriction directly on child tables:
Unauthorized users can still sneak a peek by personalizing list layouts.
If you write the Query BR wrongly, even admins get blocked — this breaks Flows, background scripts, and system processes.
In Flow Designer or workflows, queries on restricted RITMs/Tasks may fail if they run under a restricted admin context.
So, a Query BR written only on child tables = security leakage + functional errors.
Solution
Step 1: Write the Query BR on the Parent Table (task)
By placing the Query BR on task, the restriction cascades down to all child tables (sc_req_item, sc_task) and ensures a consistent rule.
Step 2: Exclude Admin Role from the Restriction
Flows, workflows, and background jobs often run as admin. If you block admin with your query rule, those automations will fail.
So add a condition:
!gs.hasRole('admin');
Step 3: Restrict Records by Group Membership and Catalog Item
Use system properties to store:
The restricted catalog item sys_id (e.g., User Offboarding).
Allowed group sys_ids (HR, Finance, IT Helpdesk, Management).
Check the current user’s membership before applying the query filter.
Sample Query Business Rule Script
(function executeRule(current, previous) {
// Get restricted catalog item sys_id from system property
var restrictedCatItem = gs.getProperty('user.offboarding.sysid');
// Get current user
var user = gs.getUser();
// Load allowed group sys_ids from system properties
var hrGroup = gs.getProperty('hr.group');
var financeGroup = gs.getProperty('finance.group');
var itHelpdeskGroup = gs.getProperty('ithelpdesk.group.sysid');
var managementTeamGroup = gs.getProperty('management.team');
// Exclude admins to prevent flow/workflow failures
if (gs.hasRole('admin')) {
return;
}
// Check if user belongs to allowed groups
var isAllowed = user.isMemberOf(hrGroup) ||
user.isMemberOf(financeGroup) ||
user.isMemberOf(itHelpdeskGroup) ||
user.isMemberOf(managementTeamGroup);
// Apply restriction if user is not in any allowed group
if (!isAllowed) {
current.addEncodedQuery(
'sys_class_name=sc_req_item^' +
'ORsys_class_name=sc_task^' +
'ref_sc_req_item.cat_item!=' + restrictedCatItem + '^' +
'ORref_sc_req_item.cat_itemISEMPTY^' +
'ref_sc_task.cat_item!=' + restrictedCatItem + '^' +
'ORref_sc_task.cat_itemISEMPTY'
);
}
})(current, previous);
Result of Encoded Query:
Key Benefits
- Restriction is enforced at the Task level, so it covers all child tables.
- Prevents data leakage in list views and references.
- Excluding admins keeps Flows, Workflows, and background jobs running smoothly.
- System properties make it flexible (no hardcoding sys_ids or group names).