Security and Restricting Access · Topic 3 of 4

Scripting Security with GlideSystem

ServiceNow CAD: script security with GlideSystem, using gs.hasRole, gs.getUserID and gs.getUser().isMemberOf in ACL scripts and business rules.

  • 4 min
In a nutshell
  • gs methods run on the server; g_user runs in the browser and is not security.
  • gs.hasRole() returns true for admins as well.
  • gs.getUserID() returns a sys id, so compare it with reference fields to sys_user.

What it is

GlideSystem is the server side gs object. Several of its methods tell a script who the current user is and what they hold: their sys id, their roles and, through the user object, their groups.

Developers use these methods when a role or a condition alone cannot express the rule. The usual places are the Script field of an ACL, a business rule, and a script include called by either.

ACL or business rulegs methodswho is the userCompare with recordowner, group, roleanswer true or false

How it works

The methods to know

MethodReturns
gs.hasRole('role')true if the current user has the role; users with admin also return true
gs.getUserID()sys id of the current user
gs.getUserName()user name (user_name field) of the current user
gs.getUser()a GlideUser object for the current user
gs.getUser().isMemberOf('group')true if the user belongs to the group
gs.getUser().hasRole('role')role check on the user object
gs.isInteractive()true when the session is an interactive user session

Note that gs.hasRole() passes for admins, because admin passes role checks. If the requirement must exclude admins, the script needs a different check.

Scripts inside an ACL

An ACL script decides the rule by setting the variable answer. The script runs only after the role and condition parts of the same rule have passed, and current is the record being checked.

// write ACL on x_acme_travel_request
answer = current.requested_for == gs.getUserID() ||
    gs.hasRole('x_acme_travel.approver');

Keep ACL scripts short. They run for every record and field checked, so a slow query inside an ACL script slows every list.

Scripts inside business rules

A business rule can enforce a rule that ACLs do not express well, such as blocking a save. A before business rule can stop the transaction with current.setAbortAction(true) and show a message with gs.addErrorMessage().

if (!gs.getUser().isMemberOf('Travel Approvers')) {
    gs.addErrorMessage('Only approvers can approve requests.');
    current.setAbortAction(true);
}

A query business rule can add a filter so users only see their own rows, for example current.addQuery('requested_for', gs.getUserID()). It limits what lists return but is not a replacement for a read ACL.

Server checks versus client checks

The client has a similar object, g_user, with methods such as g_user.hasRole(). It is useful for showing or hiding a button or field in the browser. It is not security, because anything in the browser can be bypassed.

NeedWhere it belongs
Decide if a user may read or write a recordACL with a gs based script
Block a save that breaks a ruleBefore business rule with setAbortAction
Show a field only to a role on the formClient script or UI policy with g_user
Filter lists to the user's own rowsQuery business rule

Records queried in scripts

A plain GlideRecord query in a server script does not apply ACLs. Use GlideRecordSecure, or check gr.canRead() and gr.canWrite(), when the script must respect the current user's access.

GlideRecordno ACL checkGlideRecordSecureenforces ACLscanRead canWritecheck one record

How the exam asks about this

  • "Allow edits when the logged in user is the record's Requested for." An ACL script comparing the field with gs.getUserID().
  • "Check if the user is in the Travel Approvers group on the server." gs.getUser().isMemberOf('Travel Approvers').
  • "A server script must return only records the user is allowed to read." Use GlideRecordSecure.

What to remember for the exam

  • gs methods run on the server; g_user runs in the browser and is not security.
  • gs.hasRole() returns true for admins as well.
  • gs.getUserID() returns a sys id, so compare it with reference fields to sys_user.
  • Group membership is checked through gs.getUser().isMemberOf().
  • ACL scripts set answer; they run after the rule's role and condition pass.
  • Plain GlideRecord ignores ACLs; GlideRecordSecure enforces them.
Watch out

Comparing a reference field with gs.getUserName() fails, because a reference field stores a sys id. Use gs.getUserID() for reference comparisons.

Common mistakes

Checking roles in a client script and calling it secure. The browser can be bypassed. The rule must also be enforced by an ACL or business rule on the server.

Forgetting that admins pass gs.hasRole. A test as admin shows the rule passing for any role name. Impersonate a normal user to see the real result.

Using GlideRecord where ACLs should apply. A script include called from the client with plain GlideRecord can return records the user cannot open. Use GlideRecordSecure in that case.

Check yourself

  • Which method returns the current user's sys id on the server?

    gs.getUserID(), which is the value to compare with reference fields that point to sys_user.

  • How does a script check group membership on the server?

    Call gs.getUser().isMemberOf() with the group name; it returns true when the current user is a member.

  • Why is g_user.hasRole() not enough to protect data?

    It runs in the browser, which the user can bypass, so the server must also enforce the rule with an ACL or business rule.

Topic 3 of 4 in Security and Restricting Access

Test yourself on Security and Restricting Access

The full ServiceNow CAD question bank has 600 questions, with timed practice exams and an explanation for every answer.

This study guide is independent and is not affiliated with, endorsed by, or sponsored by ServiceNow. Vendor names, certification names and exam codes are trademarks of their respective owners and are used for identification only.