
ServiceNow ACLs Explained: How Access Control Really Works
Security in ServiceNow is not the same thing as hiding a button or making a field read-only on a form.
A Client Script can hide a field.
A UI Policy can make a field read-only.
A Business Rule can reject an update.
But if the requirement is:
Who is actually allowed to read or modify this data?
then we need to think about Access Control Lists, usually called ACLs.
ACLs are one of the core security mechanisms in ServiceNow.
They determine whether a user can perform operations such as:
- read a record
- create a record
- modify a record
- delete a record
- read a particular field
- write to a particular field
- execute certain protected resources
Understanding ACLs is essential because ServiceNow security is layered.
A user may be able to open a table but not see one sensitive field.
They may be able to read a record but not modify it.
They may have the required role but still fail a record condition.
And a field-level rule may restrict access even after table access has been granted.
In this guide, we'll build a practical mental model for how ServiceNow ACLs work and how to design them without creating an unmaintainable security model.
What Is a ServiceNow ACL?
An Access Control List rule defines who can perform a particular operation on a protected ServiceNow object.
For record security, that object is commonly:
- a table
- a field on a table
An ACL might answer questions such as:
Can this user read Incident records?
Can this user modify this particular Incident?
Can this user see the u_sensitive_notes field?Can this user write to the Assignment Group field?
The ACL does not decide what the form looks like.
It decides whether access is permitted.
That is an important distinction.
ACLs Are Security, Not Presentation
Suppose we hide a sensitive field using:
1g_form.setVisible(2 'u_sensitive_notes',3 false,4)The field disappears from that form.
But that does not make the field securely inaccessible.
There may be other ways to access data, including:
- lists
- APIs
- reports
- different forms
- integrations
- other interfaces
A UI change controls the user experience.
An ACL controls access.
If information must be protected, use the platform's security mechanisms rather than relying on presentation logic.
ACLs Protect Operations
An ACL secures a particular operation.
For record ACLs, the operations developers work with most often include:
readwritecreatedelete
These operations solve different problems.
A user might be allowed to:
- read an Incident
- update an Incident
but not:
- delete the Incident
That would require different ACL rules.
Do not assume that granting one operation automatically grants every other operation.
Table-Level ACLs
A table-level ACL protects records on a table.
For example, a read ACL on:
incident
controls whether the user can read Incident records.
Conceptually, it answers:
Is this user allowed to read records from this table under these conditions?
A table ACL can use things such as:
- required roles
- record conditions
- scripts
This allows the rule to become more specific than simply checking whether someone has a role.
Field-Level ACLs
A field-level ACL protects one particular field.
For example:
incident.u_sensitive_notes
might have a read ACL.
A user could therefore be allowed to read the Incident record while still being unable to read that field.
This gives us two layers:
Table access
Can the user access the record?
Field access
Can the user access this particular field?
For protected fields, both layers matter.
Table Access Does Not Automatically Mean Field Access
Imagine a user passes the read ACL for the incident table.
They can read the record.
Now imagine incident.u_security_notes has its own read ACL requiring a special role.
The user does not have that role.
The result can be:
- Incident record is readable
- normal fields are readable
- Security Notes is not readable
That is one of the most important concepts to understand about ServiceNow ACLs.
Access can become more granular as the platform evaluates the object being requested.
A Simple Role-Based ACL
One of the simplest ACL designs is a role requirement.
For example, we may require:
itil
for a particular operation.
This means users need the appropriate role before the ACL can pass.
Role-based controls are useful because they are:
- easy to understand
- efficient
- easy to administer
- easy to audit
If a requirement can be accurately expressed using roles, you often do not need a complex ACL script.
Multiple Roles in an ACL
An ACL can contain multiple required roles.
A user typically needs one of the roles listed in the required-role list for that role check to succeed.
For example, the ACL might permit users with either:
x_app.case_agentx_app.case_manager
The role check is only one part of the ACL.
If the ACL also contains a condition or script, those requirements must still succeed too.
Roles, Conditions, and Scripts Work Together
An ACL can contain several types of requirements.
For example:
Required Role
x_app.case_agent
Condition
Active is true
Script
User must be assigned to the record
These are not three alternative ways of gaining access within that ACL.
If all three are configured, the user must satisfy the configured requirements.
That gives us a useful mental model:
Role
Who is broadly eligible?
Condition
For which records should this apply?
Script
What dynamic rule still needs to be evaluated?
Use Conditions When Possible
Suppose the requirement is:
Agents can update Cases only while the Case is Active.
If the Active field can express that requirement directly, use an ACL condition.
That is usually clearer than writing:
1answer =2 current.getValue(3 'active',4 ) === 'true'A declarative condition communicates the rule directly in the ACL configuration.
Scripts are powerful, but they should not be your automatic first choice.
ACL Scripts Handle Dynamic Rules
Sometimes a role and condition are not enough.
Imagine the requirement:
Users can read the record if they opened it themselves.
An ACL script could evaluate:
1answer =2 current.getValue(3 'opened_by',4 ) ===5 gs.getUserID()The script produces a boolean decision.
true means the scripted requirement passes.
false means it fails.
The script should remain focused on the access question.
Keep ACL Scripts Small
ACL scripts are security logic.
That is a strong reason to keep them easy to understand.
Avoid enormous scripts that:
- perform many unrelated queries
- contain business-process logic
- modify records
- trigger events
- perform integrations
- contain hundreds of lines
An ACL script should ideally answer one question:
Does this user satisfy this access requirement?
Complex reusable calculations can often be moved into a Script Include and called from the ACL if necessary.
ACL Scripts Should Not Modify Data
An ACL exists to determine access.
It should not be used as a hidden record-processing mechanism.
Avoid logic such as:
1current.setValue(2 'state',3 '2',4)5
6current.update()inside an ACL script.
Access evaluation may occur frequently and from places you did not expect.
ACLs should decide whether something is permitted.
Business logic that modifies data belongs elsewhere.
Be Careful With Database Queries Inside ACLs
Sometimes an ACL genuinely needs information from another table.
For example, access might depend on membership in a custom relationship.
A GlideRecord query may be necessary.
But remember that ACLs can be evaluated frequently.
An expensive query inside an ACL may run many times as users:
- open forms
- load lists
- access fields
- call APIs
- navigate related data
That can become a performance problem very quickly.
Before querying from an ACL, ask whether the requirement can be determined through:
- a role
- the current record
- a condition
- existing user information
- a reusable optimized security helper
Keep the hot security path as simple as possible.
Prefer Roles Before Complex Scripts
Suppose the real requirement is:
Only Payroll Managers can read this information.
If a well-designed role already represents Payroll Managers, use the role.
Do not write a script that queries several tables to rediscover whether the user is effectively a Payroll Manager.
Roles exist to represent access responsibilities.
Scripts are better reserved for rules that genuinely depend on dynamic data.
Record Conditions Make ACLs Powerful
ACLs do not have to provide identical access to every record in a table.
Imagine a Case table.
A user might be allowed to read a Case when:
- they opened it
- they are assigned to it
- they belong to the assigned group
- the Case belongs to their department
That means two users can request the same table operation but receive different results because the record data differs.
This is why ServiceNow record security can become very granular.
Example: User Owns the Record
A custom table might have a field:
u_requested_for
We could allow a user to read the record when they are the requested-for user.
A simple script might look like:
1answer =2 current.getValue(3 'u_requested_for',4 ) ===5 gs.getUserID()This rule is record-dependent.
The same user might pass the ACL for one record and fail it for another.
Example: Assigned User or Manager
Suppose the requirement is:
The assigned user can update the record, and managers can update any record.
One possible script is:
1if (2 gs.hasRole(3 'x_app.case_manager',4 )5) {6 answer = true7} else {8 answer =9 current.getValue(10 'assigned_to',11 ) ===12 gs.getUserID()13}However, if the manager role can be expressed cleanly in the ACL's role configuration or through separate ACL design, prefer configuration over unnecessarily embedding role logic into every script.
The goal is clarity.
Table Inheritance Affects ACLs
ServiceNow tables can extend other tables.
For example:
incident
extends:
task
That matters because ACLs defined on parent tables can affect child tables.
An ACL on task may therefore participate in access decisions involving Incident records.
When troubleshooting access, do not inspect only ACLs whose names begin with incident.
Parent-table security may also be involved.
This is one reason ACL debugging tools are so valuable.
More Specific ACLs Matter
ServiceNow looks for ACLs that match the object being accessed.
For table access, this can involve:
- the requested table
- parent tables
- wildcard rules
For field access, matching can become more specific.
Examples include:
incident.numbertask.number*.numberincident.*task.**.*
Understanding this hierarchy is important when a field behaves differently from the rest of the table.
A more specific rule may be participating in the decision.
Wildcard ACLs
The * wildcard allows an ACL to secure a broader set of objects.
For example:
incident.*
represents fields on the Incident table at a broader level.
A specific field rule such as:
incident.u_sensitive_notes
can then provide more targeted security for one field.
Wildcard ACLs are useful, but they also increase the number of objects affected by one security rule.
Use them deliberately.
Don't Add ACLs Until You Understand Existing Ones
One of the easiest ways to make ServiceNow security confusing is to respond to every access problem by creating another ACL.
You may end up with:
- table ACLs
- parent-table ACLs
- wildcard ACLs
- field ACLs
- scripted ACLs
all overlapping.
Before creating a new rule:
- inspect the existing ACLs
- identify which ones already match
- debug the user's access
- understand why the existing evaluation produces the current result
Then make the smallest appropriate change.
Read and Write ACLs Solve Different Problems
Suppose a user is allowed to see Salary but must not change it.
You might have:
Read
Allowed for the user's HR role.
Write
Restricted to HR managers.
The field remains visible but cannot be modified by unauthorized users.
This is fundamentally different from a UI Policy that merely makes the field appear read-only on one form.
The ACL protects the write operation at the security layer.
Create Security Needs Thought Too
Creating a record is different from updating an existing record.
A create ACL answers:
Is this user allowed to create this kind of record?
You might allow employees to create requests while allowing only agents to update certain fields afterward.
Design create access separately from write access instead of assuming the same rules apply to both.
Delete Should Usually Be Deliberate
Delete access is powerful.
Many business applications allow users to create and modify records but intentionally restrict deletion.
Before granting delete access, ask whether the user truly needs to permanently delete the record.
Depending on the application, alternatives may include:
- closing the record
- cancelling it
- deactivating it
- marking it obsolete
Preserving historical records is often important for auditability and troubleshooting.
Admin Access Has Special Behaviour
ACL records have security behavior around administrative users.
Depending on the ACL configuration, an admin may be allowed to override normal ACL requirements.
That means testing only as an administrator is a poor way to verify security.
An ACL that appears to work perfectly for you while logged in as admin may behave very differently for the intended user.
Always test using realistic user access.
Creating ACLs Requires Elevated Security Privileges
ACL configuration is intentionally protected.
Administrators who are authorized to modify access controls generally need to elevate to the:
security_admin
role.
This reduces the chance that sensitive security configuration is changed casually during an ordinary administrator session.
Treat elevated security access carefully.
ACL changes can expose or block large amounts of data.
Test as the Actual User
A security rule should be tested using a user that represents the real requirement.
For example:
- normal requester
- ITIL agent
- team manager
- application administrator
- user from another department
Testing only with admin can hide problems because admin behavior may differ from normal access.
Impersonation is extremely useful for this.
Ask:
What can this specific user actually read, write, create, and delete?
Debug Security Rules
When access does not behave as expected, guessing is usually slower than debugging.
ServiceNow provides security debugging tools that can show which ACLs are being evaluated and whether they passed or failed.
This helps answer questions such as:
- Which ACL matched?
- Did the role check fail?
- Did the condition fail?
- Did the script fail?
- Is a parent-table ACL involved?
- Is a field ACL blocking access?
- Is a wildcard ACL affecting the result?
These tools are essential for troubleshooting complex access-control behavior.
Access Analyzer Can Help With Complex Security
For broader access analysis, ServiceNow also provides tools for examining why a user, role, or group has particular access.
This becomes valuable when security depends on several layers.
Rather than manually inspecting dozens of ACLs, use the platform's analysis tools to understand the complete permission path.
Security debugging should be evidence-driven.
A Missing Field Is Often an ACL Clue
Suppose a user opens a record and can see:
- Number
- Short Description
- Priority
- Assignment Group
but one field is missing or empty.
Before assuming there is a UI problem, investigate field-level read security.
Likewise, if a field appears but cannot be modified, investigate field-level write access.
ACL issues can sometimes look like form configuration issues.
A Missing Record Can Also Be an ACL Clue
If one user can see 200 records while another can see only 40, there may be record-level read security involved.
Do not automatically assume:
- the filter is different
- the records were deleted
- the list is broken
Access controls can affect which records the user is permitted to retrieve.
Security changes the data the user is allowed to access.
ACLs and APIs
ACLs are not only about forms.
When data is accessed through normal platform interfaces and APIs under a user's security context, access control remains an important part of the request.
This is why proper ACL design is much stronger than simply hiding information from the ServiceNow UI.
An integration user should receive access appropriate to that account's responsibilities.
Do not grant enormous roles to an integration merely to make an API call succeed.
Server-Side Scripts Need Their Own Security Thinking
Not every server-side execution context behaves like an end user interacting with a form.
When building custom server-side code, consider whether the code is supposed to:
- run with application/system authority
- respect the current user's record access
- explicitly verify access
Do not assume every GlideRecord query automatically represents exactly the same security model as a user opening a record.
Choose security-aware APIs and access checks when the requirement needs them.
ACLs Are Not a Substitute for Good Role Design
If your application has dozens of ACL scripts checking:
1gs.getUserName()or individual user sys_id values, the underlying role model may need improvement.
Prefer designing roles around responsibilities.
For example:
- request user
- case agent
- case manager
- finance reviewer
- application administrator
Then ACLs can refer to stable access concepts rather than individual people.
People change.
Responsibilities are more durable.
Avoid Hard-Coding Users in ACL Scripts
Avoid:
1answer =2 gs.getUserID() ===3 '46f3...'unless there is an extremely specific reason.
Hard-coded user IDs create several problems:
- difficult maintenance
- poor portability between instances
- unclear business meaning
- personnel changes require code changes
Use roles, groups, relationships, or configuration that represents the real business requirement.
Groups and Roles Solve Different Problems
A group generally represents organizational membership or assignment.
A role represents platform capability or access responsibility.
Sometimes ACL logic legitimately depends on group membership.
For example:
Users in the assigned group can update this Case.
But do not use one massive group as a replacement for thoughtful role design.
Likewise, do not create a new role for every individual record relationship.
Choose the model that represents the real requirement.
Avoid Complex Security Logic in Many ACLs
Suppose five fields need the same complicated access calculation.
Copying a 30-line script into five ACLs creates five versions of security logic.
If the rule is genuinely reusable, consider centralizing the calculation in a focused Script Include.
For example:
1var security =2 new CaseSecurity()3
4answer =5 security.canReadSensitiveData(6 current,7 gs.getUserID(),8 )The ACL remains easy to read.
The shared security calculation has one maintained implementation.
Keep Security Script Includes Focused
A security helper should not become another giant utility class.
For example:
CaseSecurity
could contain methods such as:
canReadSensitiveData()canUpdateCase()
It should not also contain:
- email formatting
- integration processing
- unrelated asset logic
Security code deserves especially clear responsibilities because mistakes may expose sensitive information.
Avoid Side Effects in Security Helpers
A method called from an ACL should answer an access question.
It should not:
- modify the record
- create audit records manually
- update another table unnecessarily
- send notifications
- change assignments
Security evaluation should remain predictable and as close to read-only as possible.
Conditions Are Easier to Audit Than Scripts
Compare:
Condition
State is not Closed
with:
1answer =2 current.getValue(3 'state',4 ) !== '7'The script may work.
But the declarative condition is easier for another administrator to inspect.
When possible, prefer:
- roles
- straightforward conditions
- scripts only for logic that actually requires scripting
Simple security is easier to verify.
Don't Duplicate Security in Client Scripts
Suppose an ACL prevents a user from updating a field.
You may also make the field read-only in the UI for a cleaner user experience.
That is fine.
But the UI rule should not become the authoritative implementation.
Think of the layers like this:
UI Policy / Client Script
Communicates what the user should be able to do.
ACL
Enforces what the user is actually allowed to do.
The server-side security rule remains the protection.
ACLs and Business Rules Have Different Responsibilities
An ACL asks:
Is this operation allowed?
A Business Rule asks:
What business logic should happen during this record operation?
For example:
ACL
Only Case agents can update this record.
Business Rule
When Priority changes to Critical, calculate the escalation timestamp.
Do not use a Business Rule as a substitute for actual access control.
Likewise, do not fill an ACL with business-processing logic.
ACLs and Data Policies Are Different Too
A Data Policy might enforce:
Resolution Code must contain a value.
An ACL might enforce:
Only users with a certain responsibility may modify Resolution Code.
The first is about the validity or requirement of the data.
The second is about authorization.
Both may participate in the same application, but they solve different problems.
Example: Protecting Sensitive Notes
Imagine a custom Case table contains:
u_sensitive_notes
The requirement is:
Agents can read Cases, but only Case Managers can read Sensitive Notes.
A good design might include normal table read access for Case agents.
Then add a field-level read ACL on:
u_case.u_sensitive_notes
requiring:
x_app.case_manager
Now agents can continue working with the Case without gaining access to the restricted field.
That is exactly what field-level ACLs are designed for.
Example: Users Can Read Their Own Requests
Suppose employees should be able to read only requests created for themselves.
A record-level rule could check a field such as:
requested_for
against the current user.
A script might contain:
1answer =2 current.getValue(3 'requested_for',4 ) ===5 gs.getUserID()If managers also need broader access, design that explicitly through appropriate roles or additional access rules.
Do not bury every exception in one enormous script.
Example: Assigned Group Can Update
Suppose members of the assigned group can modify a Case.
A reusable security helper could perform the membership test.
For example:
1var security =2 new CaseSecurity()3
4answer =5 security.isMemberOfAssignedGroup(6 current,7 gs.getUserID(),8 )The helper might use the platform's appropriate group-membership capabilities.
If this ACL executes frequently, pay particular attention to performance and avoid unnecessary repeated queries.
Build Security From Broad to Specific
A useful way to design access is:
- identify who should have broad table access
- identify record-specific restrictions
- identify sensitive fields
- separate read and write requirements
- use roles wherever they accurately model responsibility
- use conditions for simple record rules
- add scripts only where dynamic logic is required
This produces a much clearer security model than starting with scripts.
Principle of Least Privilege
A strong security design follows a simple principle:
Give users the access they need to perform their responsibility, but no more.
Avoid solving access problems by granting:
- admin
- security_admin
- broad application administrator roles
- unnecessarily powerful inherited roles
simply because it makes the error disappear.
A successful test does not mean the security design is good.
The goal is correct access with the smallest reasonable privilege.
Be Careful With Powerful Roles
Granting a broad role can affect far more than the one table you're troubleshooting.
Roles may:
- contain other roles
- grant application access
- satisfy many ACLs
- expose unrelated data
Before granting a role, understand what it actually provides.
Do not use role assignment as trial-and-error debugging.
Test Positive and Negative Cases
Security testing should confirm both sides.
Do not only test:
The manager can see the field.
Also test:
The agent cannot see the field.
For an update rule, test:
- authorized user succeeds
- unauthorized user fails
- record condition is satisfied
- record condition is not satisfied
- field access behaves correctly
- alternative access paths behave correctly
Security that only has a successful test has only been half tested.
Test After Changing Parent or Wildcard ACLs
A change to a specific ACL may affect one field.
A change to a parent or wildcard ACL can affect many objects.
For broad ACL changes:
- identify impacted child tables
- identify impacted fields
- test representative roles
- test positive and negative cases
- review unexpected access changes
The broader the rule, the broader the testing should be.
Document Why the ACL Exists
An ACL called:
u_case.u_financial_details read
tells us what it protects.
But it does not tell us why.
Use meaningful descriptions to explain the security requirement.
For example:
Restricts Case financial details to users with the Case Finance Reviewer role.
That makes future maintenance far easier than forcing another administrator to reverse-engineer the intention from a script.
Common ACL Mistakes
Hiding a field instead of securing it
UI visibility is not access control.
Testing only as admin
Admin behavior may bypass rules that affect normal users.
Adding ACLs without debugging existing rules
Overlapping security becomes difficult to understand.
Putting all access logic in scripts
Use roles and conditions when they accurately express the rule.
Writing expensive GlideRecord queries inside frequently evaluated ACLs
Security code can become a performance bottleneck.
Hard-coding individual users
Model responsibilities with roles, groups, relationships, or configuration.
Mixing record processing into ACL scripts
ACLs should make access decisions.
Forgetting field-level security
Passing the table rule does not necessarily grant access to every protected field.
Ignoring parent tables
Inherited table structures affect ACL matching.
Granting broad roles just to make access work
Fix the security design instead of bypassing it.
A Practical ACL Checklist
Before creating an ACL, ask:
What object am I protecting?
A table, record operation, field, or another protected resource?
What operation am I protecting?
Read, write, create, delete, or another supported operation?
Can a role express the requirement?
Use the simplest accurate security model.
Can a condition express the record rule?
Prefer declarative configuration when possible.
Do I genuinely need a script?
Use scripting for dynamic logic that cannot be expressed cleanly otherwise.
Is this field more sensitive than the rest of the table?
Consider field-level security.
Does table inheritance affect the rule?
Check parent ACLs.
Are wildcard ACLs involved?
Understand the complete match hierarchy.
Am I testing as the real type of user?
Do not rely on admin testing.
Have I tested both allowed and denied cases?
Security needs both.
How ACL Evaluation Fits Together
A useful simplified mental model is:
User requests an operation
For example:
Read incident.u_sensitive_notesServiceNow determines which access controls apply.
The user must first have sufficient access to the record/table.
Then field-level security is also considered for the requested field.
Within an ACL, the configured requirements may include:
- roles
- security attributes
- conditions
- script logic
If the required security checks do not pass, access is denied.
The real platform evaluation can involve inheritance, wildcard rules, and multiple matching ACLs, which is why debugging tools are important when the result is not obvious.
Modern ACL Decision Types
Modern ServiceNow releases can also support ACL decision behavior such as:
- Allow-If
- Deny-Unless
For most developers learning ACL architecture, the core model is still:
Define exactly who should be permitted to perform an operation and under what conditions.
Deny-style rules deserve additional care because a broad deny can affect access across many users.
When working with these rules, understand the evaluation behavior for the ServiceNow release your instance is running and test thoroughly.
Why ACL Design Becomes Hard
ACLs usually become difficult for one of three reasons.
Too many overlapping rules
Nobody knows which ACL is producing the result.
Too much scripted logic
The security model can no longer be understood from configuration.
Poor role design
ACLs are forced to compensate for unclear access responsibilities.
Good ACL architecture starts with a clear access model before writing security scripts.
Start With an Access Matrix
For a larger application, write down the intended access before implementing it.
For example:
| User Type | Read Case | Update Case | Read Sensitive Notes | Delete Case |
| --- | --- | --- | --- | --- |
| Requester | Own only | Limited | No | No |
| Case Agent | Assigned cases | Yes | No | No |
| Case Manager | All team cases | Yes | Yes | No |
| App Admin | All | Yes | Yes | Yes |
This immediately exposes the real requirements.
Then roles, conditions, and field ACLs can be designed to implement that model.
Without an access matrix, security often evolves through one-off exceptions.
Keep the Security Model Understandable
An administrator should ideally be able to answer:
Why can this user access this record?
and:
Why can't this user access this field?
without spending hours reading scripts.
That means favoring:
- meaningful roles
- clear conditions
- focused ACLs
- small scripts
- useful descriptions
- centralized reusable security logic where needed
Security that nobody understands is difficult to trust.
A Better Layered Security Model
A well-designed ServiceNow application might use:
Roles
Represent broad application responsibilities.
Table ACLs
Control access to records.
Record conditions
Restrict access based on record state or relationships.
Field ACLs
Protect especially sensitive fields.
ACL scripts
Handle genuinely dynamic access rules.
UI Policies and Client Scripts
Provide a matching user experience.
Business Rules and Data Policies
Enforce business and data rules.
Each tool has a clear job.
Conclusion
ServiceNow ACLs are the foundation of secure record and field access.
They answer a very different question from UI Policies, Client Scripts, and Business Rules.
Those tools may ask:
What should the form look like?
or:
What should happen when this record changes?
An ACL asks:
Is this user actually allowed to perform this operation?
ACLs can protect:
- tables
- records
- fields
- read operations
- write operations
- create operations
- delete operations
- other protected platform resources
A strong ACL design starts simple.
Use roles to represent responsibilities.
Use conditions to represent straightforward record rules.
Use scripts only when access genuinely depends on dynamic logic.
Protect sensitive fields independently when necessary.
Understand table inheritance and wildcard rules.
Test with realistic users rather than only administrators.
Use ServiceNow's security debugging and analysis tools instead of guessing.
And most importantly:
Never confuse hiding something in the interface with securing the underlying data.
Once that distinction becomes natural, ServiceNow security becomes much easier to design correctly.
The goal is not to create the largest number of ACLs.
The goal is a security model where the right users have the right access, unauthorized users do not, and another developer can still understand why.

Learn the difference between ServiceNow Client Scripts and Business Rules, when to use each, common mistakes, performance considerations, and practical examples.

Learn how to use ServiceNow GlideRecord for server-side queries, filters, updates, inserts, reference fields, encoded queries, and performance-friendly scripting.

Learn how ServiceNow Script Includes organize reusable server-side logic, reduce duplicated code, work with GlideRecord, and support GlideAjax client calls.