This integration requires a dedicated service account with specific, limited permissions. Do not use a personal account or admin account. Following the principle of least privilege ensures security and auditability.
Creating a custom role with granular permissions is the recommended approach for production environments. This follows the principle of least privilege and provides better security than using out-of-the-box roles like itil or admin.
1
Create the Custom Role
In the navigator, search for “Roles” and select User Administration → Roles
Click New
Fill in the role details:
Field
Value
Name
x_serval_integration
Description
Custom role for Serval integration with least-privilege API access
Click Submit
2
Add Base Roles
Open the role you just created and scroll down to the Contains Roles related list. Add the following base roles:
Role
Purpose
rest_api_explorer
Enables REST API access
personalize_choices
Allows reading sys_choice values
personalize_dictionary
Allows reading sys_dictionary for field definitions
These base roles provide the foundational REST API capabilities. We will add granular table access via ACLs in the next step.
Serval requires specific read/write access to various ServiceNow tables. You’ll create Access Control List (ACL) rules to grant only the necessary permissions.
Serval uses the following ServiceNow APIs, which may require specific plugins to be active on your instance:
Table API (/api/now/table) — Active by default on all instances
Service Catalog API (/api/sn_sc/servicecatalog) — Requires the Service Catalog plugin (active by default)
Change Management REST API (/api/sn_chg_rest/change) — Requires the Change Management - REST API plugin (com.snc.change_management.rest_api)
Attachment API (/api/now/attachment) — Active by default on all instances
These tables are required for change request workflows.
Table
Read
Create
Write
Purpose
change_request
✅
✅
✅
Change request records
sysapproval_approver
✅
❌
✅
Change request approval records
Creating change requests uses the Change Management REST API (/api/sn_chg_rest/change), which requires the Change Management - REST API plugin to be active on your ServiceNow instance. This plugin is active by default on most instances.
These tables are required if using Serval’s access profile capabilities for syncing organizational resources and provisioning/deprovisioning users.
If you are not using access profiles, you can skip these ACLs. The sys_user and sys_user_group tables listed above under Configuration Tables still require read access for basic functionality regardless.
Table
Read
Create
Write
Delete
Purpose
sys_user
—
❌
✅
❌
Write access for department assignment (read access already listed above)
sys_user_grmember
✅
✅
❌
✅
Group membership provisioning and deprovisioning
sys_user_role
✅
❌
❌
❌
Role definitions for resource sync
sys_user_has_role
✅
✅
❌
✅
Role assignment provisioning and deprovisioning
core_company
✅
❌
❌
❌
Company records for resource sync
cmn_department
✅
❌
❌
❌
Department records for resource sync
cmn_location
✅
❌
❌
❌
Location records for resource sync
cmn_cost_center
✅
❌
❌
❌
Cost center records for resource sync
For each table that requires access, create appropriate ACLs:
1
Navigate to ACLs
In the navigator, search for “Access Control (ACL)”
Select System Security → Access Control (ACL)
2
Create Read ACLs
For each table that requires read access, create a new ACL:
Click New
Set Type to record
Set Operation to read
Set Name to the table name (e.g., incident)
In the Requires role related list, add your custom role x_serval_integration
Click Submit
Repeat for all tables listed in the Required Table Access tab.
3
Create Write ACLs
For tables that require create, write, or delete access:
Click New
Set Type to record
Set Operation to create, write, or delete as needed
Set Name to the table name
In the Requires role related list, add your custom role x_serval_integration
Click Submit
Create ACLs for the following tables:Incident & Problem Management:
incident (create, write)
problem (create, write)
Change Management:
change_request (create, write)
sysapproval_approver (write)
Service Catalog:
sc_request (create)
sc_req_item (create, write)
sys_attachment (create)
Access Management (if using access profiles):
sys_user (write)
sys_user_grmember (create, delete)
sys_user_has_role (create, delete)
Using out-of-the-box roles is simpler but grants more permissions than necessary. Only use this approach for development/testing or if your organization’s security policy permits.
Instead of creating custom ACLs, you can assign these out-of-the-box roles to the integration user:
Role
Purpose
Notes
itil
ITSM functionality (incidents, problems, changes)
Grants broad access to incident, problem, and change management
catalog
Service catalog access
For catalog item browsing, ordering, and request management
knowledge
Knowledge base access
For knowledge article sync
user_admin
User and group administration
Required only if using access profiles for provisioning/deprovisioning
The itil role includes access to the Change Management REST API. If you use the custom role approach instead, ensure the Change Management - REST API plugin (com.snc.change_management.rest_api) is active on your instance.
This step is optional but recommended to verify your configuration before connecting to Serval. If you encounter issues connecting, use these methods to troubleshoot.
1
Test with REST API Explorer
In the navigator, search for “REST API Explorer”
In the Namespace dropdown, select now
In the API Name dropdown, select Table API
Click Send to test a simple query
If you see a successful response with data, the API access is working correctly.
By default, Serval polls your ServiceNow instance to sync comments. For faster, near-instant comment delivery, you can configure a Business Rule that pushes new comments to Serval via webhook. This applies to comments on Incidents and Catalog Request Items that were created by the Serval integration.
This requires a single Business Rule on the sys_journal_field table. No ServiceNow plugins, store apps, or additional licensing are required.
When a comment is added to a Serval-managed record, an async insert Business Rule fires on the sys_journal_field table. The rule verifies the parent record was opened by the Serval service account, constructs a JSON payload, and sends it asynchronously to the Serval webhook. Serval processes the event and delivers the comment to the relevant conversation in real time.
In ServiceNow, go to System Definition → Business Rules and click New.
2
Configure the rule settings
Set the following fields:
Field
Value
Name
Serval – Sync Comment to Webhook
Table
sys_journal_field
Advanced
Checked
When
async
Insert
Checked
Update
Unchecked
Delete
Unchecked
Query
Unchecked
3
Add the script
Switch to the Advanced tab and paste the following script:
(function executeRule(current, previous /*null when async*/) { var tableName = current.getValue('name'); var elementType = current.getValue('element'); // Validate: only Serval-managed records. // Replace 'serval.integration' with the user_name of your // Serval service account if it differs. var SERVAL_USER = 'serval.integration'; var recordSysId = current.getValue('element_id'); var parentRecord = new GlideRecord(tableName); if (!parentRecord.get(recordSysId)) { gs.warn('Serval webhook: parent record not found: ' + tableName + '/' + recordSysId); return; } var openedBy = parentRecord.opened_by.user_name.toString(); if (openedBy !== SERVAL_USER) { return; } // Build payload var instanceName = gs.getProperty('instance_name'); var instanceUrl = 'https://' + instanceName + '.service-now.com'; var payload = { instance_url: instanceUrl, table: tableName, record_sys_id: recordSysId, number: parentRecord.getValue('number'), comment: { sys_id: current.getUniqueValue(), element: elementType, value: current.getValue('value'), sys_created_by: current.getValue('sys_created_by'), sys_created_on: current.getValue('sys_created_on') } }; // Configuration // Replace the token value with the token provided by Serval. // For production, store this in a System Property // (e.g., x_serval.webhook_token) and retrieve it via // gs.getProperty('x_serval.webhook_token'). var SERVAL_WEBHOOK_URL = 'https://svwebhook.api.serval.com/servicenow/new-comment'; var SERVAL_WEBHOOK_TOKEN = '<TOKEN_PROVIDED_BY_SERVAL>'; try { var request = new sn_ws.RESTMessageV2(); request.setEndpoint(SERVAL_WEBHOOK_URL); request.setHttpMethod('POST'); request.setRequestHeader('Content-Type', 'application/json'); request.setRequestHeader('X-Serval-Webhook-Token', SERVAL_WEBHOOK_TOKEN); request.setRequestBody(JSON.stringify(payload)); // Run asynchronously so we don't block the user's transaction request.setEccParameter('skip_sensor', 'true'); var response = request.executeAsync(); gs.info('Serval webhook: sent ' + elementType + ' event for ' + tableName + '/' + parentRecord.getValue('number') + ' (async)'); } catch (e) { gs.error('Serval webhook: failed to send event: ' + e.message); }})(current, previous);
The script references serval.integration as the Serval service account user_name. This must match the user_name of the service account provisioned in your instance. If your team chose a different name during onboarding, update the SERVAL_USER variable accordingly.
4
Save the Business Rule
Click Submit to save the rule. Comment sync will begin working immediately for Serval-managed records.