Restricting Access to Incident Records based on Role and Business Service

RakshithaM
Tera Contributor

Hi All,

 

I have a requirement to restrict access to particular incident records based on Role and Business service.

The incidents created from "Payroll Issues" record producer must be visible only for the users having Role- ( payroll + itil ) and having Business service as "Payroll Issues". 

And the " itil " role users must not be able to see this record in incident record list and it must be restricted.

 

But the below code in ACL isn't working as per requirement. Can someone guide me where I need to correct. Thanks in advance.

 

Incident Read ACL:

 

Screenshot 2025-09-11 183253.png

 

 

 

 

Script:

 

(function() {

    var salaryBS = '27d3f35cc0a8000b001df42d019a418f';     //sys_id of "payroll issues" Business service

 

    if (current.business_service != salaryBS) {

        return gs.hasRole('itil');

    }

 

    if (current.business_service == salaryBS) {

        return gs.hasRole('itil') && gs.hasRole('payroll_issue');

    }

 

    return false;

})();

 

 

 

3 REPLIES 3

RaghavSh
Kilo Patron

So there are other ACLS on incident table which are providing the a access.

Explanation: Your code seems fine and if you do some logging, you will get correct logs.

Now the issue here is , if any other "Read" table level ACL on incident is providing access to ITIL role, this ACL will not work as expected because the other ACL has provided the access. The simple rule to remember is , if there are 2 or more table level ACLs on a table, user need to pass only 1 to get access.

 

Try query BR for your requirement.


Raghav
MVP 2023

svirkar420
Tera Expert

Hi @RakshithaM , 

Since OOTB ACL's on the incident table already allow access to itil role, the additional ACL you wrote won’t restrict visibility. This happens because if a user passes any one ACL at the table level, they get access.

To bypass this use the below ACL code to bypass the existing ACL and check for both roles and only if that proves true it will show the record else not.

(function() {
var payrollBS = '27d3f35cc0a8000b001df42d019a418f';
if (current.business_service == payrollBS) {
return gs.hasRole('itil') && gs.hasRole('payroll_issue');
}
return true;
})();

Also, Please mark this solution as accepted and helpful as it will be helpful for other users and readers as well.

Best Regards.

Saurabh V.

Ankur Bawiskar
Tera Patron
Tera Patron

@RakshithaM 

I assume your payroll users have payroll custom role

why not update the OOTB query business rule to handle this and also create fresh table.None READ ACL?

Something like this

1) ACL table.None -> give payroll role there

2) update query BR

restrictIncidents();
function restrictIncidents() {
    if (!gs.hasRole("itil") && !gs.hasRole("sn_incident_read") && gs.isInteractive()) {
        // Existing exceptions
        if (gs.hasRole('service_viewer'))
            return;
        if (GlidePluginManager.isActive('sn_fsm_itsm_mng') && gs.hasRole('wm_ext_agent'))
            return;
        if (GlidePluginManager.isActive('com.sn_hamp') && gs.hasRole('sn_hamp.ham_user'))
            return;
        if (GlidePluginManager.isActive('com.sn_ot_inc_mgmt') && gs.hasRole("sn_ot_incident_read"))
            return;
        if (gs.hasRole("sn_sow_srm.srm_responder"))
            return;

        var u = gs.getUserID();

        current.addQuery("caller_id", u).addOrCondition("opened_by", u).addOrCondition("watch_list", "CONTAINS", u);
    } else if (gs.hasRole('itil')) {
        // Additional condition to restrict Payroll Issues incidents to payroll+itil users with matching business service

        // If user does NOT have payroll role, exclude Payroll Issues business service incidents
        if (!gs.hasRole('payroll')) {
            current.addQuery('business_service.name', '!=', 'Payroll Issues');
        } else {
            // User has payroll and itil - restrict to only Payroll Issues incidents
            // Show incidents that are:
            // - Not from Payroll Issues record producer (if you can identify those incidents), or
            // - Have business_service = Payroll Issues
            // You may need a flag or source field to identify Payroll Issues record producer incidents

            // Assuming incidents have u_record_producer_source field set as 'Payroll Issues' for such records
            var pq = current.addQuery('business_service.name', '!=', 'Payroll Issues');
            pq.addOrCondition('u_record_producer_source', 'Payroll Issues');
        }
    }
}

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader