UI Policies & UI Actions
UI Policy Overview
A UI Policy is a no-code mechanism for dynamically controlling field behavior on a ServiceNow form. Rather than writing JavaScript, administrators define rules that automatically make fields mandatory, read-only, or hidden based on conditions evaluated in the browser.
Key Characteristics
Client-Side Execution
UI Policies run entirely in the browser. They execute as JavaScript client-side, which means they fire instantly when a condition changes — no server round-trip required.
Consequence: they can be bypassed by REST API calls or direct database access.
Form-Scoped
UI Policies apply only to forms. They have no effect on list views, integrations, API calls, background scripts, or any non-form data access path.
Use ACLs when you need enforcement across all access paths.
Reactive to Field Changes
Policies can trigger when the form first loads and/or whenever a watched field changes its value, providing a responsive form experience.
Configure via the "On load" checkbox and the condition field references.
Storage Table
UI Policies are stored in the sys_ui_policy table. Navigate via System UI > UI Policies or type sys_ui_policy.list in the filter navigator.
Related actions stored in: sys_ui_policy_action
UI Policy Anatomy
Every UI Policy record has a set of header fields that define when and how it activates, plus a related list of UI Policy Actions that specify what happens to individual fields.
Policy-Level Fields
| Field | Purpose | Notes |
|---|---|---|
| Table | Which table this policy applies to | e.g., incident — policy only fires on forms for that table |
| Short description | Human-readable name for the policy | Used to identify the policy in lists and update sets |
| Active | Checkbox — enables or disables the policy | Inactive policies are completely ignored at runtime |
| Conditions | Filter defining when the policy activates | Built using the condition builder; evaluated against the current record's field values |
| On load | Run the policy when the form first loads | Without this, the policy only fires when a condition-watched field changes |
| Reverse if false | Undo all policy actions when the condition becomes false | Critical: without this, fields stay in the policy state even after condition clears |
| Applies on | Client (default) or Server | Server execution is rare and uses a different execution context |
| Order | Numeric priority — lower number runs first | When multiple policies affect the same field, order determines which wins |
| Global | Apply to all views or a specific form view | Global policies fire regardless of which form view is active |
| Inherit | Apply to child tables that extend this table | Useful for policies on base tables like task |
UI Policy Actions — Field-Level Control
A UI Policy header defines the when and where. UI Policy Actions define the what — specifically, what changes to apply to individual fields when the policy condition is met.
Action Structure
Each UI Policy Action targets one field and independently controls three behavioral properties for that field:
Mandatory
Controls whether the field is required before the form can be saved.
- True — field is required
- False — field is not required
- Don't change — leave as currently set
Read Only
Controls whether the user can edit the field's value.
- True — field is read-only
- False — field is editable
- Don't change — leave as currently set
Visible
Controls whether the field is displayed on the form.
- True — field is shown
- False — field is hidden
- Don't change — leave as currently set
Storage & Navigation
- Actions are stored in the
sys_ui_policy_actiontable - They appear as a related list at the bottom of each UI Policy record
- You can add multiple actions to one policy — one row per field you want to control
- A single policy can control many fields simultaneously
Practical Example
Setup:
- Create a UI Policy on table:
incident - Condition:
Priority is 1 - Critical - Check On load and Reverse if false
- Add Action 1: Field =
short_description, Mandatory = True - Add Action 2: Field =
impact, Read Only = True
Result: As soon as Priority is set to 1 - Critical (or the form loads with that value), Short Description becomes required and Impact locks. If Priority changes away from 1 - Critical, both revert.
UI Policy vs. Client Script (High-Frequency Exam Topic)
Both UI Policies and Client Scripts run client-side in the browser. The exam frequently tests when to use each — understanding the trade-offs is critical.
| Aspect | UI Policy | Client Script |
|---|---|---|
| Coding required | None — fully declarative / no-code | Full JavaScript required |
| Execution | Client-side (browser) | Client-side (browser) |
| Actions available | Mandatory, Read Only, Visible — only these three | Any DOM/form manipulation, value setting, server calls, alerts, navigation |
| Set field values | No — cannot set a field's value | Yes — g_form.setValue() |
| Server lookups | No | Yes — via GlideAjax |
| Complex conditions | Limited — condition builder only | Full JavaScript logic: loops, regex, multi-field comparisons |
| Trigger types | On load, on field change (auto-detected from condition) | onLoad, onChange, onSubmit, onCellEdit |
| Preferred when | Simple show/hide, mandatory, read-only based on a condition | Setting values, complex logic, server lookups, validation on submit |
| Storage table | sys_ui_policy |
sys_script_client |
| Equivalent API calls | (no-code equivalent of the below) | g_form.setMandatory() / g_form.setReadOnly() / g_form.setVisible() |
Client Script g_form Equivalents
When you need UI Policy-style behavior inside a Client Script, use these g_form API methods:
// Make a field mandatory (true = mandatory, false = optional)
g_form.setMandatory('short_description', true);
// Make a field read-only (true = locked, false = editable)
g_form.setReadOnly('impact', true);
// Show or hide a field (true = visible, false = hidden)
g_form.setVisible('resolution_notes', false);
// Set a field's value (cannot be done with UI Policy alone)
g_form.setValue('state', '6'); // Sets State to Resolved
// Combined example: onLoad Client Script
function onLoad() {
var priority = g_form.getValue('priority');
if (priority == '1') {
g_form.setMandatory('short_description', true);
g_form.setReadOnly('impact', true);
}
}
UI Policy vs. ACL — The Layer Boundary
This is perhaps the most important conceptual distinction on the entire CSA exam. UI Policies and ACLs can both make fields read-only or invisible, but they operate at fundamentally different layers with very different security implications.
| Aspect | UI Policy | ACL (Access Control List) |
|---|---|---|
| Enforcement layer | Presentation layer — browser/client | Database layer — server-side always |
| Can be bypassed | YES — REST API, scripts, integrations bypass it entirely | NO — enforced on every access path, no exceptions |
| Read-only via UI Policy | Field appears read-only on the form but CAN still be written via API | Field ACL with write deny: field is truly non-writable from any path |
| Hidden via UI Policy | Field is hidden visually but value is still transmitted in form data and readable via API | Field ACL with read deny: value is never transmitted or accessible |
| True security control | No — UX only | Yes — genuine enforcement |
| Primary use | Form UX: improve workflow, guide users, simplify complex forms | Data security: protect sensitive fields and records from unauthorized access |
| Example use case | Hide "Escalation Reason" field when Priority is not Critical | Prevent non-HR users from reading or writing salary-related fields |
UI Actions
UI Actions are configurable buttons, links, and context menu items that appear on forms and lists. They allow administrators and developers to expose custom functionality — from simple form saves to complex server-side workflows — as clickable elements in the ServiceNow UI.
Key Facts
- Stored in the
sys_ui_actiontable - Navigate via System UI > UI Actions or type
sys_ui_action.list - Can run client-side JavaScript (browser) or server-side scripts (GlideRecord)
- Appear on both forms (individual record views) and lists (table row views)
- A Condition field controls when the action is visible to the user
- An Action name provides a unique identifier used in scripts and ACLs
UI Action Types
Form Button
Appears as a button in the form action bar at the top/bottom of a record form.
Example: "Resolve", "Assign to Me", "Clone Incident" buttons on the Incident form.
Form Context Menu
Appears when the user right-clicks on a form (the form's context menu).
Used for less-frequently accessed actions that don't need a prominent button.
Form Link
Appears as a hyperlink at the bottom of a form, typically in the related links section.
Suitable for navigation actions or secondary operations.
List Button
Appears as a button in the list action bar — operates on selected rows in a list view.
Example: "Assign Selected" button on the Incident list.
List Context Menu
Appears when the user right-clicks on a row in a list.
Good for row-level operations accessible without opening the full record.
List Link
Appears as a link visible in list view rows or the list's related links section.
Less commonly used but available for navigational or lightweight operations.
UI Action Fields
| Field | Purpose |
|---|---|
| Name | Display label shown on the button or menu item |
| Table | Which table's forms/lists the action appears on |
| Action name | Unique internal identifier — used by scripts and referenced in ACLs controlling the action |
| Active | Enables or disables the action — inactive actions are invisible to all users |
| Condition | JavaScript expression evaluated to determine if the action is visible to the current user. If false, the button/link does not appear. |
| Client | Checkbox — if checked, the Script field runs client-side JavaScript in the browser |
| Isolate script | Run the server script in a separate thread (isolated from the main transaction) |
| Script | The JavaScript or server-side GlideRecord script to execute when the action is triggered |
| Order | Controls the display order of multiple actions on the same form/list |
Client vs. Server UI Actions & Common Patterns
UI Actions can execute code either in the browser (client) or on the server. Understanding when each runs and how they interact is a key exam topic.
Client UI Action
- The Client checkbox is checked on the UI Action record
- Script runs as JavaScript in the user's browser
- Has access to
g_form,g_user,g_list,window, DOM APIs - Can call
g_form.submit()to trigger a server-side save after client validation - Cannot directly access GlideRecord — must use GlideAjax for server data lookups
- Useful for: validation before save, setting field values, user confirmation dialogs, navigation
Server UI Action
- The Client checkbox is unchecked — script runs on the server
- Has access to
current(the active record),gs(GlideSystem),GlideRecord - Used for: updating records, calling web services, running business logic, setting state
- Can use
action.setRedirectURL()to navigate the user after execution
Common UI Action Patterns
"Resolve" Button (Incident)
Server-side action that sets current.state = '6' (Resolved) and current.update(). Condition: current.state != 6 so it only shows on unresolved incidents.
Client Validation Before Submit
Client-side action that checks field values, shows an alert if invalid, then calls g_form.submit() to proceed with save only if validation passes.
Context Menu Bulk Operation
List context menu action that applies a category or assignment group update to all selected rows using a GlideRecord loop in server script.
"Assign to Me" Button
Server-side action that sets current.assigned_to = gs.getUserID() and current.update(). Simple, common pattern seen on most task-based tables.
Server UI Action Script Pattern
// Server-side UI Action — "Resolve Incident"
// Table: incident | Client checkbox: UNCHECKED
current.state = '6'; // Resolved
current.close_code = 'Solved'; // Resolution code
current.resolved_by = gs.getUserID();
current.resolved_at = new GlideDateTime();
current.update();
// Redirect user to the incident list after resolution
action.setRedirectURL('incident_list.do');
// Client-side UI Action — validate before save
// Table: incident | Client checkbox: CHECKED
if (!g_form.getValue('short_description')) {
alert('Short Description is required before saving.');
return; // Stop — do not submit
}
g_form.submit(); // Proceed with save
Key Exam Facts & Traps
This section consolidates the highest-priority facts and the most common wrong-answer traps for UI Policies and UI Actions on the CSA exam.
sys_ui_policy table. Catalog UI Policies (for Service Catalog items and order guides) use the catalog_ui_policy table. They are separate records — a standard form UI Policy does NOT apply to Catalog item forms.
sys_ui_policy— UI Policy headers (the "when" rules)sys_ui_policy_action— UI Policy Actions (the "what" field changes)sys_ui_action— UI Actions (buttons, links, menu items)sys_script_client— Client Scripts
Quick Reference Summary
| Feature | Table | Runs On | Can Set Values | Enforces Security |
|---|---|---|---|---|
| UI Policy | sys_ui_policy |
Client | No | No |
| Client Script | sys_script_client |
Client | Yes | No |
| UI Action (client) | sys_ui_action |
Client | Yes | No |
| UI Action (server) | sys_ui_action |
Server | Yes | Partial (via GlideRecord) |
| ACL | sys_security_acl |
Server | N/A | Yes — all paths |
- Need to make a field mandatory/read-only/hidden based on another field's value? → UI Policy
- Need to set a field's value or run complex conditional logic in the browser? → Client Script
- Need a button or menu item that triggers custom logic? → UI Action
- Need to protect a field from unauthorized writes at the database level? → ACL
- Need server-side record manipulation triggered by a button click? → UI Action (server-side, Client unchecked)