How to restrict instance metric records based on read access to tables?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎04-16-2024 08:34 AM
I have a requirement to restrict the records on metric instance table based on the user's read access to other tables i.e. incident, sc_req_item, sc_task, etc. Kindly help with below code which I am using in a before query business rule on metric_instance table but it doesn't work as expected.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎04-16-2024 09:38 AM
HI @syedtufailahmed
- The current object in a Business Rule represents the current record being processed. When you use current.table, you’re accessing the value of the ‘table’ field on the metric_instance record, which should contain the name of the table this metric instance is related to (e.g., ‘incident’).
- The issue with the current code is that tableGr.query(); if(tableGr.canRead()){ does not effectively check the user’s permission on the dynamically referenced table because GlideRecord.query() immediately followed by canRead() doesn’t iterate over records to check read access for a specific table dynamically. The canRead() method checks if the current user has read access to the tableGr record itself, not to all records in the table referenced by table.
Solution
For a Before Query Business Rule that dynamically restricts records based on user read permissions to related tables, consider using GlideRecord to loop over tables and Security Rules instead of direct scripting checks. Due to ServiceNow security model complexities (like ACLs), the optimal way might be to use a combination of scripted checks for known tables and default fallbacks for general cases.
That said, an important thing to remember is that for a complex system like ServiceNow, direct scripting might not cover all cases smoothly (e.g., dealing with cross-scope access issues, handling table hierarchies, or specific ACL conditions). Always test thoroughly.
(function restrictBasedOnUserAccess() {
// Define an array of tables you specifically want to include in your check
var tablesToCheck = ['incident', 'sc_task', 'sc_req_item'];
var userHasAccess = false;
for (var i = 0; i < tablesToCheck.length; i++) {
var tempGR = new GlideRecord(tablesToCheck[i]);
if (tempGR.canRead()) { // If user can read any record in one of the specified tables
userHasAccess = true;
break;
}
}
if (!userHasAccess) {
// If the user doesn’t have access to any of the specified tables, restrict this query entirely
current.setAbortAction(true);
}
// Note: This script doesn’t specifically filter metric_instance records by each table, instead, it’s an all-or-nothing check.
// Customizing further could lead to privacy concerns or complex ACLs evaluations.
})();
Please Mark this Helpful and Accepted Solution. If this Helps you to understand. This will help both the community and me..
- Keep Learning ‌‌
Thanks & Regards
Deepak Sharma

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎04-16-2024 10:06 AM
Hi @syedtufailahmed ,
Can you try below script this may works for you.
var table = current.table;
if(table == 'incident' || table == 'sc_req_item' || table == 'sc_task'){
var tableGr = new GlideRecord(table);
tableGr.query();
if(tableGr.canRead()){
//current.addQuery('table', table); your code here
}else{
current.setAbortAction(true);
}
}
Please reach me out if you need anything.
Please mark my answer correct and helpful if this works for you
Thanks and Regards
Sarthak