A blog post by Niko Sääski, IAM Consultant at Appmore
Have you ever tried checking if a user has a specific role in ServiceNow, only to get a false result even though you’re certain the user has that role? The issue might stem from an undocumented difference between gs.getUser().hasRole()
and gs.hasRole()
. In this article, we walk through a simple test scenario to show why only one of these methods correctly detects elevated roles and why this nuance can cause serious confusion for developers working with role-based access in ServiceNow.
Why ServiceNow elevated roles don’t show up in role checks
When checking user roles in ServiceNow, it’s easy to assume that all role-checking methods behave the same way. However, that is not the case when it comes to elevated roles. A common source of confusion is that gs.getUser().hasRole()
returns false for roles that are elevated even if the user clearly has the role assigned.
This happens because elevated roles are only active during a session when the user has explicitly elevated their privileges. The method gs.getUser().hasRole()
checks the roles on the user record itself, while gs.hasRole()
reflects the roles active in the current session. This subtle distinction is undocumented and can lead to unexpected behavior in scripts.
Demo: How to test elevated role behavior in ServiceNow
1. Start by creating an elevated role. In this demo I’ll create a role called demo_elevated_role.
2. Assign the role to yourself. Take note of the name and the sys_id of the role for validation.
3. Let’s validate that the role is found by a test script. At this point the role is not elevated.
4. Elevate the role
5. Now that the role is elevated, let’s check again. Pay attention to the differences between gs.getUser().hasRole()
and gs.hasRole()
Only gs.hasRole()
correctly reports that the user has the elevated role!
Discrepancy between documentation and reality
At the time of writing this (2025-05-26), the ServiceNow API documentation doesn’t mention anything about the elevated role check for either method. Links to the API docs: GlideUser.hasRole, GlideSystem.hasRole.
This seemed confusing to me, so I asked ServiceNow about it. Here’s the answer I got:
“Just wanted to follow up, our developer reviewed and confirmed that gs.hasRole() checks against the roles for the user in the current session, and gs.getUser().hasRole() checks against the roles for the user record and not the current session (so if there are some dynamic roles assigned for the user, like an elevated role, these are not checked against this API).”
“The advantage of gs.hasRole() is to check if the user’s current session includes any elevated roles. The advantage of gs.getUser().hasRole() is to check the user’s base roles and ignore any elevated roles that are only available for the current session.”
I don’t exactly see what advantage the latter part brings. From my perspective, it just looks like something to cause unnecessary headaches for developers, especially since the API documentation does not describe this behaviour.
I tested this in Yokohama (glide-yokohama-12-18-2024__patch1a-03-25-2025) both in global and scoped apps. No difference between global and scoped behaviour.
My takeaway from this? I’ll be using gs.hasRole()
from now on.
Script to verify role elevation in ServiceNow
Replace the role name and sys_id if you want to re-use the same script:
check_role_elevation();
function check_role_elevation() {
var log = [];
log.push('ROLE ELEVATION CHECK IN SCOPED APP');
log.push('\ngs.getUser().hasRole(): ' + gs.getUser().hasRole('x_leno_role_demo_a.scoped_elevated_role'));
log.push('\ngs.hasRole(): ' + gs.hasRole('x_leno_role_demo_a.scoped_elevated_role'));
var user_has_role_gr = new GlideRecord('sys_user_has_role');
user_has_role_gr.addQuery('user', gs.getUserID());
user_has_role_gr.addQuery('role', '0bcb71f087b92a502c49a75d3fbb35b8'); //x_leno_role_demo_a.scoped_elevated_role
user_has_role_gr.addQuery('state', 'active');
user_has_role_gr.query();
log.push('\nquery `sys_user_has_role` table, user has the role assigned: ' + user_has_role_gr.hasNext());
gs.info('\n' + log.join('\n'));
}
Final thoughts
Understanding the difference between gs.getUser().hasRole()
and gs.hasRole()
is important when working with elevated roles in ServiceNow. While both methods appear similar, only gs.hasRole()
takes into account the roles that are currently active in the user’s session, including any elevated roles. This can have a direct impact on how access is managed in scoped or global applications.
For role checks involving elevated privileges, gs.hasRole()
is the more reliable option. Relying on gs.getUser().hasRole()
in these cases may lead to incorrect results, especially since elevated roles are session-based and not reflected in the user record.
Until the official documentation is updated to clarify this behavior, it is good practice to keep this distinction in mind when designing and debugging access logic in ServiceNow.
Thank you for reading. I hope this example helps others avoid confusion and build more accurate role checks in their ServiceNow implementations.
Niko Sääski
Appmore