Restricting Access – ACL vs. Before Query Business Rule

How To Prohibit Access When most ServiceNow Admins think about granting or restricting access, the first thing that comes to mind is ACL (Access Control Rule) configuration. And usually, they would be correct. ACL’s are …

before query business rule for access

Buy The "ServiceNow Developer's Manual" Now

We've packed over a decade of ServiceNow Development advice, into a single e-book.

Buy It Now

How To Prohibit Access

When most ServiceNow Admins think about granting or restricting access, the first thing that comes to mind is ACL (Access Control Rule) configuration.

And usually, they would be correct. ACL’s are the preferred way to allow access to data in ServiceNow for in-memory caching and performance reasons.

Due to performance related issues that have been reported, we do not recommend using Before / Query business rules on large tables. Use them sparingly and use ACL’s whenever possible.

A Before / Query business rule is more infrequently used, but has a lot of power in the system. But due to the negative performance a poorly constructed Before / Query business rule can have on your environment, make sure you understand the performance implications before building out your own custom Before / Query business rules.

ACL’s are cached but business rules run each time a table is accessed.

The next time you’re debugging an ACL and cannot seem to find the answer there, check out the business rules that are executing before the query runs, and see if your access related issues lies there instead.

When learning new features in the ServiceNow platform, it can be super helpful to see what comes out of box. As you know it’s written by ServiceNow, the code will be clean and properly written.

Below, we’ll review an out of box business rule that runs before a table is queried by an end user.

 

Creating A Before Query Business Rule

before query script incident

Script:

restrictIncidents();

function restrictIncidents() {
if (!gs.hasRole(“itil”) && !gs.hasRole(“sn_incident_read”) && gs.isInteractive()) {
//Do NOT restrict Incidents if SPM premium plugin is active AND user has the service_viewer role.
if (GlidePluginManager.isActive(‘com.snc.spm’) && gs.hasRole(‘service_viewer’))
return;
var u = gs.getUserID();
current.addQuery(“caller_id”, u).addOrCondition(“opened_by”, u).addOrCondition(“watch_list”, “CONTAINS”, u);
}
}

The above business rule ships with every ServiceNow instance.

You can find it by searching for ‘incident query’ on the business rule table.

It prohibits access to only allow end users to see a limited set of incident records. I think that most customers still have this business rule activated, or they’ve had to modify it slightly.

Timing

Timing is everything in life AND in ServiceNow. Milliseconds matter and it’s crucial to understand exactly when different processes are triggered. It separates the good from the great.

A before query business rule, is executed, before the query runs whenever a user is attempting to access rows in a table (data).

Think about this Before / Query concept for a minute, if this is your first time seeing this.

A user is in ServiceNow and they select a list view to see incidents, for example. Before the user is able to see a single incident record, ServiceNow finds all of the Before / Query business rules, and executes them, from lowest order number to highest order number.

What is returned as true from this query, is shown or exposed to the end user who is trying to access the data.

This is done with by building a query and returning select records, and then showing these records.

The important line in this before business rule is:

current.addQuery(“caller_id”, u).addOrCondition(“opened_by”, u).addOrCondition(“watch_list”, “CONTAINS”, u);

This essentially states the following in English terms:

If the current user trying to access the record matches the Caller ID, Opened By or is on the Watch List, let them see the record. This can obviously be modified to your needs, especially if you have custom fields, etc.

For all other records, don’t allow them access.

So this before query business rule makes sense as an out of box configuration on the incident table.

For ITIL users, this business rule is skipped, as you can see on the previous lines. This is covered by skipping the query build in the IF Statement.

Performance

ACL’s are cached and Before / Query business rules are run each time data is attempted to be accessed.

When you create an ACL in ServiceNow, they can be cached and are stored in local memory for a faster retrieval.

However when you run a business rule, these can’t be stored in-memory, so they are executed constantly. Every time the table is attempted to be accessed – the query is run. This can cause a strain on your database if you have thousands of users attempting to access the same data repeatedly. This type of database strain is just unnecessary, especially when it can be accomplished with a much better design using in-memory caching (with ACL’s, which is out of box).

When considering performance in ServiceNow, don’t always do “what works” for one user. Make sure that you’re building out your solution so it scales for your organization size. 

When you do decide to use a Before / Query business rule, try to make it as simple as possible, and make sure that it’s used on a smaller table. 

Say that you have an incident table with a million records. You absolutely do not want to run a Before / Query business rule here, because each time you do so, you are putting tremendous and unneccessary strain on your database – further slowing the system down. 

Certain GlideRecord query operators have larger performance impacts on your database than others. The CONTAINS operator for example has a larger performance impact on your database query than just a simple matching query.

Troubleshooting access related issues increases with the more Before / Query business rules your organization decides to implement. And because scripts can call other scripts, it can become difficult quickly to understand how access is being prohibited. 

Use a Before / Query business rule, only when necessary – use ACL’s for access restriction instead.

 

ACL’s For Restricting Access – The Preferred Method

ACL’s should be your first “go to” solution when trying to restrict access to certain records in ServiceNow. 

ServiceNow has changed over the years, as initially, all data was open to all users. You then had to lock data down with an ACL. Now the opposite is true, and this has been the case for more than 10 years. All data is locked down and access is prohibited.

ServiceNow Admin’s have to open and grant access to records and fields with ACL’s.

The previously mentioned business rule can, instead, be attained by creating an ACL on the incident table. I’m honestly not 100% certain why one would choose a Before / Query business rule OVER an ACL at this point, for restricting access – if you can come up with a solid reason that is performant, do let us know below. Before / Query business rules can be used for other features than just restricting access, so that’s probably why ServiceNow still allows this functionality.

It’s unclear that if ServiceNow was to “redo” this business rule, if they’d instead just convert it to an ACL instead. This business rule was written in 2005 by Fred Luddy (Founder of ServiceNow). And as the platform has changed and matured over the years, so have the solutions that are implemented to acheive certain results. Many platform related performance issues have changed in the last 16 years. It is likely that Before / Query business rules would be removed and that all access related behavior would be managed entirely with ACL’s. 

While restricting access with a Before / Query business rule is not our first go to, give it a try and see what you’re able to accomplish with them.

Does your company use Before / Query business rules?

Let us know why or why not below.



What Do You Think About This Article?

0 0 votes
Article Rating
Subscribe
Notify of
guest
2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
José Bennedicte
José Bennedicte
2 years ago

Do you have any data to support your claim that query BR’s are less performant than read ACL’s? Thinking in terms of lists, which is where most people start, applying a ‘simple’ filter behind the scenes before fetching records seems far more efficient than pulling back everything then evaluating conditions for each record returned via ACL’s.
Even the SN docs site mentions it;
“Before Query business rules run before access control lists (ACLs) and perform better in general. This is true especially when you limit the returned results to those users in service provider (SP) environments who have access to several domains in the system.”

Jack
Jack
1 year ago

Around 2020, I was told by SN staff that Before Queries are better performing as they run on the DB and not on the app server.

2
0
Would love your thoughts, please comment.x
()
x