How to override OOB Incident Read/Write ACLs for Group-Based restrictions?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday
Hi Community,
I need to restrict Incident visibility and edit access based on assignment groups, but my custom security rules are being completely bypassed by Out-of-the-Box (OOB) ACLs.
The Requirement:
- Visibility & Write Access: Users must only be able to see and update incidents assigned to their own Support Group(s).
- Exemptions: Users with the admin role, incident_manager role, or anyone in the Service Desk group must remain exempt and be able to see/edit all incidents.
What I Have Done:
I created a custom Read ACL and a custom Write ACL on the incident table (row-level) executing this conditional logic.
The Problem:
Regular itil users can still see and write to all incidents. Because ServiceNow evaluates ACLs using an OR relationship across table-level rules, the OOB incident ACLs (which grant global access to the itil and sn_incident_write roles) evaluate to True first. My custom restrictive ACLs are effectively ignored.
My Questions:
- What is the standard practice for overriding or adjusting the OOB itil incident ACLs without completely breaking core platform functionality or causing future upgrade issues?
- If I utilize a Before Query Business Rule to handle the read restriction smoothly, what is the best way to handle the Write restriction without causing data inconsistencies?
Any advice, structural patterns, or script architecture pointers would be highly appreciated!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday
Hello @mahithaanap ,
The behavior you're seeing is expected because of how ServiceNow evaluates ACLs.
The ootb incident ACLs grant access to users with roles like itil and sn_incident_write. Since ACL evaluation is if any applicable ACL grants access, adding another restrictive ACL doesn't override the OOB one, it simply becomes another ACL in the evaluation chain.
Another pattern you can use is to introduce a custom role (for ex, one granted only to support group members) and align the ACL strategy around that role instead of relying on the itil role.
Overall, I would avoid using a Before Update Business Rule as the primary security. Record access should ideally be enforced through ACLs, with Business Rules used only for additional business validations.
If my response helped mark as helpful and accept the solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday - last edited yesterday
Hi @mahithaanap,
You can use Security Data Filter (SDF) for this.
Elevate to security_admin when creating SDF.
Set the table as incident.
Condition will be Assignment group is javascript:gs.getUser().isMemberOf(current.assignment_group);
(Try Assignment Group is (dynamic) One of my Groups if possible for Condition)
Make a custom security attribute for your exceptions.
Mode will be Filter unless security condition is met.
Please Accept this response as Solution if it assisted you with your question & Mark this response as Helpful.
Kind Regards,
Ehab Pilloor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday
Hi @mahithaanap
Standard practice is to use a BR and pair it with ACL rules to enforce exemptions.
Try this:
- Create Before Query BR
- Name: Restrict Incident by Group
- Table: Incident
- When: Before
- Query: Checked
(function executeRule(current, previous /*null when async*/) {
if (gs.hasRole('admin') || gs.hasRole('incident_manager') || gs.getUser().isMemberOf('Service Desk')) // Exempt admins, incident_managers, and Service Desk members
{
return;
}
var myGroupsArray = gs.getUser().getMyGroups();
var qc = current.addQuery('assignment_group', 'IN', myGroupsArray);
// qc.addOrCondition('assignment_group', 'ISEMPTY');
})(current, previous);
- Create Table-Level ACLs
- Type: record
- Operation: write
- Name: incident (Table-level)
- Condition: None
answer = false;
if (gs.hasRole('admin') || gs.hasRole('incident_manager') || gs.getUser().isMemberOf('Service Desk')) // Exempt users with admin, incident_manager, or Service Desk group
{
answer = true;
}
else if (current.assignment_group && gs.getUser().isMemberOf(current.assignment_group.getDisplayValue()))
{
answer = true;
}
Regards
Tanushree Maiti
ServiceNow Technical Architect
LinkedIn: https://www.linkedin.com/in/tanushreemaiti
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yesterday
Hello @mahithaanap , If you are sure that you want to block all users except the ones mentioned, you can create a couple of "Deny Unless" ACLs (Read and Write) instead of "Allow If" ACLs and verify.
- ensure Admin overriedes is checked
- Use below query in the script section:
answer = false;
if (gs.hasRole('incident_manager') || current.assignment_group.nil()) {
answer = true;
} else {
if (gs.getUser().isMemberOf(current.assignment_group)) {
answer = true;
}
}
P.S: I hope you are aware that users will see the following message at the bottom of the list when they query records that are hidden due to ACLs: "Number of rows removed from this list by Security constraints:"
Regards,
Nishant