Roles, Groups, ACLs, and Application Access
Key Takeaways
- Assign application roles through groups whenever possible; direct user-role assignment is harder to audit and offboard than group membership.
- Module and application-menu roles control navigation visibility, while Access Control Lists (ACLs) control create, read, write, and delete on the underlying data.
- A read on a sensitive field can require both a table-level ACL and a field-level ACL to pass; if either denies, access is denied.
- Within one ACL the role check, the condition, and the script must all evaluate true, and ServiceNow uses a default-deny model when no ACL matches.
- Application Access (Can read / Can write / accessible-from) plus cross-scope privileges gate what other scopes may attempt; user ACLs still evaluate afterward.
Security Is Part of the App Design
The ServiceNow Certified Application Developer (CAD) exam treats security as a design requirement, not a cleanup step after table and form work is done. Security and Restricting Access is about 20% of the 60-question, 90-minute exam, so it carries roughly 12 questions. A scoped application should have clear personas before any record is exposed: requester, fulfiller, manager, application administrator, integration user, and read-only auditor. Each persona maps to the smallest role set that supports the work.
A role is a named permission container, but roles stay maintainable only when granted through groups. Give x_app.requester to a Requesters group, x_app.reviewer to a Reviewers group, and x_app.admin to the application admins group. Onboarding and offboarding then happen through group membership instead of one-off role edits on user records. Roles can also contain other roles: granting x_app.admin can carry x_app.user automatically, which keeps elevated personas from missing baseline access.
Navigation Is Not Data Security
Application menus and modules help users find the app. Their Roles fields control whether navigation appears in the All menu or Application Navigator. That is useful, but it is not an authorization boundary for the records themselves.
| Control | What it protects | What it does NOT prove |
|---|---|---|
| Application-menu role | Whether a menu group appears | That any table records are readable |
| Module role | Whether a link appears | That a bookmarked URL or API call is allowed |
| Table ACL | Whether a user can operate on records | That every sensitive field is visible |
| Field ACL | Whether a user can read or write one column | That the user can access the whole record |
A classic CAD trap: a module opens a list, the user sees the module because the module role matches, but the list is empty because the table read ACL fails. The reverse also matters — hiding a module does not secure data if the table ACLs are broad, because the user can still reach records by direct URL, list, or REST.
ACL Gates: Table, Field, and Default Deny
An Access Control List (ACL) is a server-side rule for one operation — typically create, read, write, or delete. For record security think in two layers. The table-level rule (table.None for the whole record, or table.* as a field wildcard) answers whether the user can perform the operation on the table. The field-level rule (table.field_name) answers whether the user can act on a specific column. To read a sensitive field the user must satisfy both the record access and the field access.
Inside one ACL the checks are cumulative — all three gates must pass:
- The user holds one of the required roles, or the role list is empty.
- The ACL condition evaluates to true for the current record context.
- The ACL script, if present, returns true (or sets
answer = true).
If no matching ACL grants the requested operation, access is denied — that default-deny model is why a custom table needs explicit ACLs for the personas that need it, never UI hiding. ServiceNow also evaluates ACLs most-specific first: a matching table.field ACL is checked, then table.*, then table.None. Use conditions for readable logic such as Assigned to is (dynamic) Me, and reserve scripts for rules the condition builder cannot express. Server-side checks should use gs.hasRole() rather than trusting client values.
Application Access and Cross-Scope Boundaries
Scoped applications add an application boundary on top of ACLs. Application Access on a table controls whether scripts or web services from other scopes may read, write, create, or delete the table, and whether it is accessible from All application scopes or only This application scope only. The runtime flags Can read and Can write are cross-scope gates; Can read is the foundation other operations build on.
For more restricted inter-scope calls, ServiceNow records or requires cross-scope privilege decisions, and the target app owner approves only the operation and resource actually needed. Critically, scope access is checked first; once it permits the attempt, ACLs still evaluate the user or execution context.
The mental model is: scope gates first, then user/data gates. A scoped app also has runtime restrictions of its own — it can only create system records of types its scope permits, and it must be granted access to call APIs or scripts in other scopes, which is why a cross-scope privilege record (sys_scope_privilege) is created when one scope reaches into another.
How to Verify Security
Never test only as admin — the admin role bypasses most ACLs and hides gaps. Instead:
- Impersonate each persona (User menu > Impersonate User).
- Open the navigator, then try direct list URLs and a single-record URL.
- Check the form, attempt list editing, and confirm sensitive fields hide or deny.
- Re-run as the integration user to confirm cross-scope behavior.
A correct CAD answer names the right layer: group role for maintainability, module role for discoverability, table ACL for record access, field ACL for sensitive columns, and Application Access for cross-scope behavior.
A scoped Vendor Review app needs reviewers to open a Review Queue module, read review records, and keep the confidential_vendor_score field hidden unless they also hold the x_vendor.score_viewer role. Another scoped finance app must query review records through server-side script. Which controls belong in a correct design?
Select all that apply