The gs.hasRole() method is deceptively simple but has a critical gotcha that breaks most developers' first implementation: users with the admin role always return true for any role check, regardless of whether they actually have that specific role. This admin bypass behavior is intentional but often undesired in business logic where you need to differentiate between actual role holders and admins who can do everything. Most security and workflow bugs stem from not accounting for this behavior.

When to use this

  • In Business Rules to conditionally set field values based on user permissions
  • In Script Includes when building role-aware utility functions
  • In scheduled jobs to filter processing based on the job runner's roles
  • When you need simple boolean role checks without querying user tables

When NOT to use this

  • Don't use in client scripts β€” roles aren't available client-side, use GlideAjax instead
  • Don't use when you need to know which specific roles a user has β€” query sys_user_has_role instead
  • Don't use for complex role hierarchy checks β€” use gs.hasRoleExactly() or role inheritance queries
  • Don't use in ACLs β€” they have their own role checking syntax and context

Key behaviors and gotchas

  • Users with admin role return true for any role check β€” this breaks exclusive role logic
  • Role names are case-sensitive β€” gs.hasRole('ITIL') fails if the role is itil
  • Method checks inherited roles through role hierarchy β€” child roles return true for parent role checks
  • Returns false for non-existent roles instead of throwing an error
  • Performance is fast β€” roles are cached per session, no database hit per call
  • Domain separation affects role visibility β€” users only see roles in their domain scope
⚠️

Never rely on gs.hasRole() for security boundaries in custom applications. Admin users bypass all role checks, and the method doesn't distinguish between directly assigned roles versus inherited ones. For security-critical logic, explicitly check both the specific role AND exclude admin users, or query sys_user_has_role directly.

Free Newsletter

Enjoying this? Get one deep-dive per week.

Join 1,000+ ServiceNow pros β€” scripts, GlideRecord patterns, Flow Designer techniques, and career moves. Free.

No spam Β· Unsubscribe anytime