CSA Hub Part 4 Access Control Rules (ACLs)
🔒 Part 4 · Topic 3 of 4

Access Control Rules (ACLs)

⏱ ~75 min read · Part 4 — Database & Security · 27% Exam Weight — HIGHEST
Most Tested Security Topic: ACLs represent the single most heavily examined security concept in the CSA exam. Expect 6–10 questions directly testing ACL evaluation order, anatomy, role matching, and the behavior difference between standard and High Security modes. Master this topic completely.

ACL Overview

Access Control Lists (ACLs) are ServiceNow's primary database-layer security mechanism. Every read, write, create, delete, or execute operation against platform data passes through ACL evaluation before being permitted or denied.

What ACLs Protect

ACLs are stored in the sys_security_acl table. Navigate to them via Security > Access Control (ACL) or type sys_security_acl.list in the filter navigator. Each ACL record defines one permission rule combining a target object, an operation, and a set of requirements the user must satisfy.

Core Formula: An ACL = (Table + Field) + Operation + (Role & Condition & Script). All three requirement components must individually pass for access to be granted.

The Four Primary Operations

👁

read

View record data, field values, or list results. Controlled separately from write — a user can have read-only access.

write

Modify an existing record or field value. Does not cover creating new records — that is governed by create.

+

create

Insert a new record into the table. Evaluated when a user submits a form for a new record or uses the API to POST.

🗑

delete

Remove an existing record from the table. Often locked down more tightly than write to prevent accidental data loss.

Additional Operations

Operation When It Applies Typical Target
execute Running a script, callable API endpoint, or service operation Scripted REST APIs, workflow activities, processors
report_on Using a field as a report filter, column, or grouping criterion Fields that should not appear in reports for compliance reasons

The Three Object Types

Record ACL

Controls access to an entire row within a table. If the record ACL denies access, the user cannot see the record at all — no fields are returned. Row-level security is implemented here using conditions and scripts.

Example: incident[READ] — who can read any incident row?

Field ACL

Controls access to a specific column within a table. Evaluated in addition to the record ACL — both must pass. Used to protect sensitive fields like salary, SSN, or medical information.

Example: incident.short_description[READ] — who can see this specific field?

Table ACL

Controls table-level operations such as schema access. Less commonly encountered on the exam than record and field types. Primarily governs schema-level operations.

Example: Table-level execute for scripted REST APIs.

Exam Distinction — Record vs. Field ACLs: The exam frequently tests whether candidates understand that record ACLs and field ACLs are evaluated independently and cumulatively. A user must pass the record ACL and the field ACL to access any specific field value. Passing one does not waive the other.

ACL Anatomy — All Fields Explained

Every ACL record in sys_security_acl contains the following fields. Understanding each field's purpose is essential for both the exam and real-world ACL authoring.

Field Purpose Notes / Example
Type Defines the object scope: record, field, or table Most ACLs are type record or field
Operation The access operation being controlled read, write, create, delete, execute, report_on
Name What is protected — format: table.field or table.* or table incident.caller_id, incident.*, *.*
Active Checkbox — only active ACLs are evaluated Deactivating an ACL disables it without deletion
Requires role(s) Related list of roles; user must have at least one to pass the role check itil, admin; empty list = any authenticated user
Condition Filter expression evaluated against the current record; must evaluate to true assigned_to=javascript:gs.getUserID()
Script Advanced server-side logic; must explicitly return true or return false return gs.hasRole('manager');
Advanced Checkbox that enables the Script field — must be checked to write ACL scripts When unchecked, the script field is hidden and inactive
Admin overrides When true (default), admin users bypass this ACL entirely Set to false to enforce even for admins (sensitive data)
Description Free-text explanation of the ACL's intent Best practice: always fill in for maintainability

ACL Name Patterns

The Name field determines what object the ACL protects. It follows a table.field convention with wildcards supported at both levels.

incident.short_description

Specific field on a specific table. Most targeted — highest specificity in evaluation.

incident.*

All fields on the incident table (and its extensions). Applies to every column not covered by a more-specific ACL.

incident

Record-level ACL for the incident table with no field qualifier. Controls access to entire rows.

task.*

Wildcard covering all fields on the task table and every table that extends task (incident, problem, change).

*.*

Global catch-all: applies to all fields on all tables. The fallback of last resort when no more-specific ACL matches.

Inheritance via Table Hierarchy: ServiceNow's table extension model means an ACL on task.* applies to incident, problem, change_request, and every other table that extends task. A more specific ACL on incident.* will override the inherited task.* ACL for incident records.

ACL Evaluation Order (CRITICAL — Most Tested)

ServiceNow evaluates ACLs from most-specific to least-specific. The moment a matching ACL is found, its result (allow or deny) is applied and evaluation stops. No further ACLs are checked.

Specificity Priority Order

Priority ACL Pattern Description Example
1 — Highest table.field with condition Exact table + exact field + record-level condition applied incident.caller_id[READ] where assigned_to = user
2 table.field Specific table and specific field, no record condition incident.caller_id[READ]
3 table.* All fields on a specific table incident.*[READ]
4 *.field A specific field name on any table *.sys_created_by[READ]
5 — Lowest *.* Global fallback — all fields on all tables *.*[READ]

Same-Specificity Rules: ALL Must Pass

When multiple ACLs exist at the same specificity level for the same table/field/operation combination, the user must pass all of them. There is no short-circuit allow at the same level — each ACL is an independent gate.

Exam Trap — Most Specific Wins, Period: If a more-specific ACL denies access, the evaluation stops immediately. A permissive wildcard ACL lower in the hierarchy will NOT rescue the user. The most specific matching ACL's decision is final.

Example: incident.caller_id[READ] denies access. The incident.*[READ] ACL that would allow access is never consulted because evaluation already concluded at the higher-specificity level.

The Three-Gate Check

Once the most-specific matching ACL is found, the user must pass all three internal checks. These run in sequence:

1

Role Check

Does the user have at least one of the roles listed on this ACL?

Empty role list = any authenticated user passes automatically

2

Condition Check

Does the optional filter condition evaluate to true for this record?

Evaluated after role check; no condition = automatic pass

3

Script Check

Does the optional ACL script return true?

Only runs if Advanced is checked; no script = automatic pass

All Three Must Pass: The role check, condition check, and script check are AND logic — all must individually succeed. If any one of them fails, the ACL denies access regardless of what the others returned.

Fail-Closed Behavior

No Matching ACL = DENIED (Standard Mode): If ServiceNow finds no matching ACL for a given table/field/operation, access is denied by default. This fail-closed model means you must explicitly grant access — it is never granted by the absence of rules.

Exception — Without High Security Plugin: On instances without the High Security plugin, the default behavior for missing ACLs may be more permissive. The High Security plugin enforces strict deny-by-default across the board. See Section 9 for details.

Admin Bypass

Default Admin Behavior: Users with the admin role bypass ACL evaluation entirely by default. The platform skips ACL checks for admin users, granting full access to all records and fields. This behavior can be overridden on individual ACL records by setting Admin overrides = false.

Role Matching Logic

The role check is the first gate in ACL evaluation. Understanding exactly how role matching works prevents common exam mistakes.

OR Logic Across Roles

When multiple roles are listed in an ACL's Requires role(s) list, the check uses OR logic — the user needs to have at least one of the listed roles. Possessing any single matching role is sufficient to pass the role check.

ACL Roles Required User's Roles Role Check Result Reason
itil, manager itil PASS User has itil — one match is enough
itil, manager manager PASS User has manager — one match is enough
itil, manager itil, manager PASS Has both; still passes (OR logic)
itil, manager approver_user FAIL Has neither required role
(empty) any authenticated user PASS Empty list = no role requirement; all users pass

Role Hierarchy and Inheritance

ServiceNow roles support a parent-child hierarchy. A parent role includes all permissions of its child roles. If an ACL requires role itil and a user has a role that contains itil as a child, the role check passes.

Role Containment Example: If role itil_manager contains itil as a child role, then a user with itil_manager automatically also has itil. Any ACL requiring itil will pass for that user even though they were not explicitly granted the itil role directly.

Empty Roles List — Important Behavior

Exam-Tested Behavior: An ACL with an empty roles list means the role check is satisfied by any authenticated (logged-in) user. It does not mean the ACL is inactive or skipped — the condition and script checks still run. An empty roles list is a deliberate way to allow broad access while still enforcing conditions or scripts on the record.

The security_admin Role

Creating, editing, or deleting ACL records requires the security_admin role. This is a separate, elevated role that is not granted automatically with admin.

security_admin vs. admin — Critical Distinction:
  • admin — Full platform administration, bypasses ACLs by default, cannot modify ACL records without security_admin
  • security_admin — Specifically grants the ability to create, modify, and delete ACL rules; does NOT automatically include admin platform permissions
  • An admin user who wants to edit ACLs must also be granted security_admin separately (or elevate to it)
  • This separation prevents admins from accidentally or maliciously tampering with security controls

Condition Evaluation

The Condition field on an ACL provides record-level (row-level) filtering. It is a standard ServiceNow filter expression that is evaluated against the current record being accessed.

How Conditions Work

  • Conditions run after the role check — if the role check fails, the condition is never evaluated
  • Both the role check AND the condition must pass for the ACL to allow access
  • If no condition is specified, that check passes automatically
  • The condition has access to the current object (the record being evaluated)
  • JavaScript expressions can be embedded using the javascript: prefix

Common Condition Patterns

// Show only records assigned to the current user
assigned_to=javascript:gs.getUserID()

// Show records belonging to any group the user is a member of
assignment_group=javascript:gs.getMyGroups()

// Records where caller is the current user
caller_id=javascript:gs.getUserID()

// Records where active flag is true
active=true

// Records in open state (1 = open in ITSM)
state=1

GlideSystem Methods Used in Conditions

Method Returns Use Case
gs.getUserID() sys_id of current user (String) Match records where a reference field points to the current user
gs.getUserName() Username (login name) String Match string fields storing username values
gs.getMyGroups() Comma-separated list of group sys_ids Match records assigned to any of the user's groups
gs.hasRole('rolename') Boolean true/false Conditional access based on role membership within a condition expression
Exam Must-Know: gs.getUserID() returns the sys_id (not the username) of the currently logged-in user. It is the most commonly tested GlideSystem method in ACL context. Used in conditions to implement row-level security patterns like "users can only see their own records."

ACL Scripts

The Script field enables advanced, programmatic access control logic that goes beyond what filter conditions can express. ACL scripts run server-side and have full access to the ServiceNow scripting API.

Script Requirements

  • The Advanced checkbox must be checked on the ACL to enable the Script field
  • The script must explicitly return true to allow access or return false to deny
  • Script runs after both the role check and the condition check
  • If the script does not return anything, the behavior is undefined — always return explicitly
  • The current object provides access to the record being evaluated

Available Script Objects

Object Type Description
current GlideRecord The record currently being evaluated for access. Access field values via current.field_name
gs GlideSystem Platform API: user identity, role checks, session info, logging
gs.getUserID() String (sys_id) Returns the sys_id of the currently logged-in user
gs.hasRole('role') Boolean Returns true if the current user has the specified role
gs.hasRoleInGroup('role','group') Boolean Returns true if user has the role within a specific group context

ACL Script Examples

// Allow access only to manager or above
answer = gs.hasRole('itil_manager') || gs.hasRole('admin');

// Allow if current user is the caller or assigned agent
answer = (current.caller_id == gs.getUserID() ||
          current.assigned_to == gs.getUserID());

// Allow if the record is in a specific state
answer = (current.state == 1 || current.state == 2);

// Check a related (referenced) record's field value
var grp = new GlideRecord('sys_user_group');
grp.get(current.assignment_group);
answer = (grp.manager == gs.getUserID());

// Combine role and field value check
if (gs.hasRole('itil')) {
  answer = (current.priority == 1 || current.priority == 2);
} else {
  answer = false;
}
Script vs. Condition — When to Use Each:
  • Use Condition for simple database-style filters (field = value, field IN list)
  • Use Script for multi-step logic, boolean combinations, method calls, or when you need to query related records
  • Scripts are more powerful but more expensive — conditions are evaluated with SQL-level efficiency, scripts require JavaScript execution

Record ACLs vs. Field ACLs

Understanding the relationship between record-level and field-level ACLs is one of the most commonly tested topics in the security section of the CSA exam.

Record ACLs

A record ACL controls whether a user can access the entire row. It is the outer gate — if the record ACL denies access, the user cannot see the record in any form: not in list views, not via form, not via API.

Operation on Record ACL Effect When Denied
read Record is excluded from list results and form views; appears as if it does not exist
write Record can be viewed but form fields are read-only; save operations are blocked
create User cannot insert new records into the table; New/Insert operations fail
delete Delete button is hidden; delete operations via API return a security error

Field ACLs

A field ACL controls access to a specific column within a table. Field ACLs are evaluated in addition to the record ACL — both must pass for the user to interact with a specific field.

Operation on Field ACL Effect When Denied
read Field is hidden on the form; field value is blank in list views; API returns empty string
write Field is rendered read-only on the form; user can view the value but cannot edit it

The Cumulative Rule

Both Must Pass — Critical Exam Rule: To access a specific field, a user must pass both the record-level ACL AND the field-level ACL. Passing the record ACL does not automatically grant access to all fields — each field ACL is checked independently on top of the record ACL result.

Failure Scenario: If a user passes the incident[READ] record ACL but fails the incident.salary_band[READ] field ACL, they can see the incident record but the salary_band field will be blank/hidden.

Visual Flow: Record + Field ACL Evaluation

User requests: READ incident record #INC0001234
↓ Step 1: Evaluate record ACL — incident[READ]
✕ DENY → entire record blocked, user sees nothing
✓ PASS → record returned, now evaluate field ACLs
↓ Step 2: For each field, evaluate field ACL
✓ incident.short_description[READ] PASS → shown
✓ incident.priority[READ] PASS → shown
✕ incident.salary_band[READ] DENY → field hidden

Table Wildcards and Fallback Behavior

Wildcard ACLs provide broad coverage when no specific rule exists. Understanding when wildcards are applied and which wildcards take precedence is essential for predicting ACL behavior.

Wildcard Reference

Pattern Applies To Specificity Common Use
incident.short_description Exactly one field on one table Highest (2) Protect a single sensitive field
incident.* All fields on the incident table Medium (3) Default field access policy for a table
task.* All fields on task + all extending tables Medium (3) Single policy covering the full task hierarchy
*.field_name A named field on any table that has it Low (4) Protect a field name globally (e.g., *.password)
*.* Every field on every table Lowest (5) — global fallback Default platform-wide baseline access rule

The *.* Global Catch-All

The *.* ACL is the fallback of last resort. When no more specific ACL matches for a given table/field/operation combination, ServiceNow falls through to the *.* ACL if one exists. If no *.* ACL exists either, the fail-closed rule applies and access is denied.

Real-World Pattern: A common architecture is to have a restrictive *.*[READ] ACL requiring a base authenticated user role, combined with specific ACLs on individual tables that grant access to particular user groups. This ensures baseline denial for unauthenticated access while allowing targeted grants.

Table Extension and Wildcard Inheritance

The task.* wildcard demonstrates an important behavior: because incident, problem, and change_request all extend task, an ACL on task.* automatically applies to all those extended tables unless a more specific ACL exists for the extended table.

Inheritance Override: If both task.*[READ] and incident.*[READ] exist, then for incident records, only incident.*[READ] is evaluated (higher specificity). The task.* ACL is not consulted for incidents when a more specific incident-level ACL exists.

High Security Plugin

The High Security Settings plugin (com.glide.security.high_security) enables strict security enforcement at the platform level. It is a critical topic for the CSA exam's security section.

What the Plugin Does

Strict ACL Enforcement

Enables fully enforced fail-closed ACL behavior: if no matching ACL exists for an operation, access is denied for all users — including admin.

Disables Admin Bypass

The default admin bypass of ACLs is disabled. Even users with the admin role must pass ACL checks like all other users. This is the most significant behavioral change.

security_admin Required

Creating, editing, or deleting ACL records strictly requires the security_admin role. This separation of duties prevents admins from modifying their own access rules.

Password Policies

Enforces configurable password strength rules: minimum length, complexity requirements (uppercase, digits, special characters), and password expiration intervals.

Session Controls

Adds configurable session timeout and idle session expiration to reduce risk from unattended authenticated sessions.

Account Lockout

Configures automatic account lockout after a specified number of consecutive failed login attempts to prevent brute-force attacks.

Standard vs. High Security Mode

Behavior Standard Mode High Security Plugin
No matching ACL found Access GRANTED (by default on many tables) Access DENIED (strict fail-closed)
Admin bypass of ACLs Enabled by default — admin skips ACL checks Disabled — admin must pass ACLs like all users
Who can modify ACLs admin or security_admin (depends on instance config) security_admin only — strictly enforced
Password enforcement Basic or none by default Configurable strength, expiry, complexity rules
Session timeout Platform default Enforced, configurable per policy
Account lockout Not enforced by default Configurable lockout after N failed attempts
Recommended for Development / sandbox instances All production instances
Critical Exam Fact — Default Behavior Flip:
  • Without High Security: no matching ACL = access GRANTED
  • With High Security: no matching ACL = access DENIED
This is one of the most heavily tested distinctions in the security portion of the exam. Know the direction of the default for both modes.

Key Exam Facts & Debugging

This section consolidates the highest-frequency exam facts for ACLs, including common trap questions and the debugging tools available on the platform.

Master Fact List

Exam Fact 1: Default (no plugin): if no ACL matches, access is GRANTED. With the High Security plugin, the same scenario results in DENIED. The direction of the default flips.
Exam Fact 2: security_admin and admin are different roles. You need security_admin to create or edit ACL records. Having admin alone is not sufficient — these roles serve different purposes and are granted separately.
Exam Fact 3: Field ACLs require the record ACL to also pass. A user cannot access a field if the record ACL has already denied them, even if they would pass the field ACL. The record ACL is the outer gate; the field ACL is the inner gate — both must be open.
Exam Fact 4: When an ACL has multiple roles listed, the check is OR logic — the user needs at least one. When an ACL has all three checks (role + condition + script), the logic is AND — all three must pass.
Exam Fact 5: The most specific ACL wins and evaluation stops immediately. A permissive catch-all ACL below in specificity cannot override a more-specific ACL that denied access. Most specific = most targeted table + field combination.
Exam Fact 6: gs.hasRole('admin') returns true for users with the admin role. In standard mode, admin users bypass ACL evaluation entirely unless Admin overrides = false is set on the specific ACL. The High Security plugin removes the admin bypass globally.
Exam Fact 7: An ACL with an empty roles list is satisfied by any authenticated user — it does not mean the ACL is permissive for unauthenticated access, and condition/script checks still apply normally.

Debugging ACL Issues

When a user reports unexpected access problems, ServiceNow provides built-in tools to diagnose ACL evaluation without requiring code changes.

Access Control Related List

Open any record and view the Access Controls related list (may need to be added via Personalize Related Lists). Shows which ACLs were evaluated for that record and their results.

Best for: quick field-level access debugging on a specific record

ACL Debug Logs

Enable debug logging via System Diagnostics > Session Debug > Security. The system log (syslog.list) will show detailed ACL evaluation including which ACLs were checked and why access was granted or denied.

Best for: deep-dive diagnosis when the source of denial is unclear

Security ACL Simulator

Navigate to Security > Diagnose > Access Control. Simulate the access path for a specific user against a specific record to see exactly which ACLs match and what their evaluation result is.

Best for: testing access configuration for a specific user scenario

sys_security_acl.list

Navigate directly to the ACL table via the filter navigator. Filter by table name, operation, and active status to find the specific ACLs governing the affected record or field.

Best for: reviewing all ACLs for a specific table

Quick Reference: ACL Decision Matrix

Scenario Standard Mode Result High Security Result
No ACL exists for table/field/operation GRANTED DENIED
ACL exists, user has required role, no condition, no script GRANTED GRANTED
ACL exists, user does NOT have required role DENIED DENIED
ACL exists, role passes, condition fails DENIED DENIED
ACL exists, role passes, condition passes, script returns false DENIED DENIED
User has admin role, ACL admin overrides = true GRANTED (bypasses ACL) MUST PASS ACL
User has admin role, ACL admin overrides = false MUST PASS ACL MUST PASS ACL
Record ACL denied; field ACL would allow DENIED (record gate blocked first) DENIED
Putting It All Together — The Full Access Path:
  1. User navigates to a module → Role check: does the module appear in the navigator?
  2. User opens a record list → Record ACL [READ]: which rows are returned?
  3. Row-level condition on record ACL → Row filter: which specific records does this user see?
  4. User opens a record form → Field ACLs [READ]: which fields are visible/populated?
  5. User modifies a field → Field ACL [WRITE]: is this field editable?
  6. User saves the form → Record ACL [WRITE]: is this record updatable?
  7. User inserts a new record → Record ACL [CREATE]: can new records be created?
  8. User clicks delete → Record ACL [DELETE]: can this record be removed?
← CMDB & Relationships Auditing & Archiving →