ServiceNow ACLs Explained: A Complete Security Reference

How Access Control Lists actually work in ServiceNow — evaluation order, common patterns, debugging access issues, and the mistakes that create security vulnerabilities.

ACLs (Access Control Lists) are the primary security mechanism in ServiceNow. Understanding how they evaluate is essential for both building secure applications and debugging access issues efficiently.

How ACL Evaluation Works

When a user attempts to perform an operation on a record or field, ServiceNow evaluates ACLs in a specific order. Understanding this order explains why some ACLs seem to be ignored.

The evaluation sequence:

  1. ServiceNow finds all ACLs that match the object being accessed
  2. ACLs are sorted by specificity — more specific ACLs evaluate before general ones
  3. The first matching ACL that grants or denies access determines the outcome
  4. If no ACL matches, access is denied by default (secure by default)

ACL Types

ACLs can be applied at different levels:

  • Table-level — controls read/write/create/delete on the entire table
  • Field-level — controls read/write on a specific field
  • Record-level — controls access based on record data (uses scripts)

The Three Conditions

Each ACL has three conditions that must ALL pass for access to be granted:

  1. Role — user must have one of the specified roles
  2. Condition — a filter condition evaluated against the record
  3. Script — a server-side script that returns true or false

If any one of these conditions fails, the ACL denies access regardless of the others.

Common Pattern: Record Owner Access

// ACL Script: Allow access only to the record's caller
// Table: incident, Operation: write
(function() {
    // Allow if user is the caller on the incident
    if (current.caller_id == gs.getUserID()) {
        return true;
    }
    // Allow if user has itil role
    if (gs.hasRole('itil')) {
        return true;
    }
    return false;
})();

Debugging Access Issues

The fastest way to debug ACL issues is using the Security Debug plugin:

  1. Navigate to System Diagnostics > Security
  2. Enter the sys_id of the record the user cannot access
  3. Enter the user's sys_id
  4. Select the operation (read, write, etc.)
  5. Click Evaluate

The output shows exactly which ACL evaluated, in what order, and why access was granted or denied.

Alternatively, add &sysparm_ck_security=true to any URL to see ACL debug output directly on the page.

Common Security Mistakes

1. Over-broad roles in ACLs

Using the admin role as a bypass in ACL scripts is common but dangerous. If admin access is ever expanded, those ACLs expose data you didn't intend to expose.

2. Missing field-level ACLs

Securing the table but not the fields means a user with read access to the table can see all fields including sensitive ones like salary, SSN, or passwords. Always add field-level ACLs for sensitive data.

3. ACL scripts with performance issues

ACL scripts execute on every record access. A script that queries another table runs that query for every single record in a list view. Use gs.hasRole() and current field comparisons rather than GlideRecord queries inside ACL scripts.

4. Not testing as the actual user

Testing ACLs as admin with impersonation is unreliable because admin bypasses many ACL checks. Test in a separate browser session logged in as the actual user or a test account with the exact same roles.

Best Practices

  • Create custom roles for your applications rather than using built-in roles
  • Document what each custom role grants — add a description to the role record
  • Review ACLs during every release — they accumulate technical debt fast
  • Never use admin checks in ACL scripts for production access control
  • Test ACL changes in a sub-production environment before promoting

Want the complete reference?

This article is part of the NowSpectrum knowledge library. Browse all products for cheat sheets, interview prep, and deep-dive reference guides.

Browse All Products →
← Back to all posts