ServiceNow Integration
Connect ServiceNow to let agents query your CMDB and ITSM data during investigations. This data includes configuration items and their relationships (for blast-radius analysis), incidents, problems, change requests, assignment groups, users, and knowledge articles. You can also sync ServiceNow services, teams, and people into the Autoheal catalog. In addition, you can forward ServiceNow incidents to Autoheal as alerts, so that Autoheal triages and investigates them automatically. For those alert-sourced incidents, Autoheal writes each investigation's progress back onto the incident as work notes (see Investigation Write-Back).
Data queries are read-only. When Autoheal reads the CMDB/ITSM, it never creates or modifies records. The one thing Autoheal writes is investigation work notes. You can forward an incident as an alert (see Alert Source Setup). For that incident, Autoheal posts its investigation progress back onto the same incident as internal Work notes (see Investigation Write-Back). It writes only work notes, and only on incidents it is actively investigating. It never writes the customer-facing Additional comments, and never any other field or record.
Capabilities
Once connected, agents can:
| Capability | Description |
|---|---|
| Query the CMDB | Read configuration items across any class (cmdb_ci and its descendants) |
| Service topology & blast radius | Fetch a CI together with its upstream/downstream relationships in one call |
| Incidents, problems, changes | Read incident, problem, and change_request records for RCA timelines and change-risk analysis |
| Assignment groups & users | Find sys_user_group and sys_user records for SME routing |
| Knowledge articles | Search kb_knowledge for runbooks, SOPs, and architecture notes |
| Aggregate counts | Group-by counts over any table (e.g. CIs per class) for coverage questions |
| Catalog sync | Import ServiceNow services, assignment groups, and users into the Autoheal catalog |
| Alert source webhooks | Receive incident created/updated events that a ServiceNow Business Rule pushes. The events include every custom u_* field. Resolved, closed, or canceled incidents auto-resolve the Autoheal alert |
| Investigation write-back | Post investigation progress (started, root-cause hypothesis, needs-input, completion, postmortem) back onto the originating incident as internal work notes. Requires a write-capable service account |
Agents read ServiceNow through its REST APIs — the Table API (/api/now/table/{table}), the CMDB Instance API (/api/now/cmdb/instance/{class}/{sys_id}), and the Aggregate API (/api/now/stats/{table}).
Prerequisites
- A ServiceNow instance (e.g.
https://acme.service-now.com) - A service account (local ServiceNow user) for Autoheal to authenticate as
- Read access to the tables agents query (CMDB, incident, problem, change_request, sys_user, sys_user_group, kb_knowledge), and write access to the incident journal (
work_notes). Autoheal needs the write access to post investigation work notes back onto incidents
Authentication
Autoheal supports two authentication modes. Pick one when you add the integration:
| Mode | What you provide | When to use |
|---|---|---|
| OAuth 2.0 (Client Credentials) — recommended | OAuth client ID + secret only | Best security posture: no stored password and short-lived tokens. The right choice for production. Requires ServiceNow Washington DC or later (ServiceNow introduced the inbound client-credentials grant in that release). The OAuth endpoint must be bound to a service-account user. |
| Username & Password (basic) | Service-account username + password | Simplest to configure: no OAuth registration. Works on every ServiceNow release, but Autoheal sends the password on every API call. Good for a quick start or older instances. |
Both modes authenticate as a service account (not a human user). As a result, the required ServiceNow roles/ACLs (below) are the same for both modes. For production we recommend Client Credentials. Use Username & Password when you want the fastest setup or are on a pre-Washington DC release.
Setup
- In ServiceNow, go to User Administration → Users and create a dedicated user (e.g.
autoheal.svc) - Set a strong password. Username & Password auth uses this password directly. For Client Credentials, this user is the user that the OAuth endpoint is bound to
- Grant read access to the tables Autoheal queries. The simplest path is the built-in
snc_read_onlyrole. Add any roles your instance requires for the CMDB, incident, problem, change, and knowledge tables. Instead of these roles, you can use table-level read ACLs - Grant write access to the incident journal so Autoheal can post investigation work notes back onto incidents. The built-in
itilrole covers this. Alternatively, add a write ACL onincident(work_notes)
Skip this step if you're using Username & Password. This grant requires ServiceNow Washington DC or later.
Client-credentials grants are off by default instance-wide. An admin must set the system property glide.oauth.inbound.client.credential.grant_type.enabled to true (in sys_properties). Otherwise, token requests fail. ServiceNow shows a banner on the grant form that reminds you of this.
- In ServiceNow, go to System OAuth → Application Registry and click New
- Choose New Inbound Integration Experience — the guided flow for letting an external client (Autoheal) authenticate into ServiceNow
- On the Select your application connection type screen, choose OAuth - Client credentials grant ("machine-to-machine access to the application without the user's context"). Do not choose Authorization code, JWT bearer, Resource owner password, or the OIDC third-party option
- On the New record form, complete these fields:
- Name and Provider name — any label, e.g.
Autoheal(both are required) - OAuth application user — your Autoheal service account. This is the key field. The access token authenticates as this user, so the user's roles/ACLs become the token's permissions. The account must be Active and must not have Password needs reset set. It should be a Machine Identity type user with a Name. The name is required, or the account won't appear in this picker
- Leave Active checked. Comments is optional
- Name and Provider name — any label, e.g.
- Under Auth scope, keep Allow access only to APIs in selected scope checked (ServiceNow's recommended posture). Add an Auth scope row. The
useraccountscope grants exactly the resources available to the bound user. As a result, the token inherits the service account's read + work-note-write permissions and nothing more. For tighter control, click Create auth scope instead, and define a scope limited to the specific APIs - Click Save. Then copy the generated Client ID and Client Secret. ServiceNow shows the full secret only once. Use the reveal/copy icon
Creating a custom auth scope? In Limit authorization to the following APIs, select exactly the three APIs Autoheal calls. Autoheal needs no other APIs:
- Table API (
/api/now/table) — reads incidents, problems, change requests, CMDB CIs, users, assignment groups, and knowledge articles. It also posts investigation work notes back onto incidents - CMDB Instance API (
/api/now/cmdb/instance) — a CI with its relationships (service topology / blast radius) - Aggregate API (
/api/now/stats) — group-by counts (e.g. CIs per class)
The bound user's roles/ACLs still govern access to individual tables (read on the query tables, write on the incident journal). The scope only limits which APIs the token may call.
Some older releases don't offer the inbound integration experience. On those releases, use the equivalent Create an OAuth API endpoint for external clients option under the same New menu instead. This option produces the same Client ID and Client Secret.
- Go to Integrations in Autoheal and click ServiceNow
- Enter a name (e.g. "Production ServiceNow")
Enter the Instance URL (your instance base URL, e.g. https://acme.service-now.com, not the REST API path). Then choose an Authentication mode and complete its fields:
- OAuth 2.0 (Client Credentials): Client ID + Client Secret
- Username & Password: service-account username + password
For security, Autoheal only sends credentials (and mints OAuth tokens at /oauth_token.do) on ServiceNow-owned domains (*.service-now.com, *.servicenowservices.com). If your instance is fronted by a custom/vanity domain (e.g. https://snow.acme.com), ask your Autoheal operator to allow that host before you save. The operator adds the host (or its parent domain) to the SERVICENOW_ALLOWED_INSTANCE_HOSTS deployment setting. Otherwise, Autoheal rejects the Instance URL as not allowed.
Click Test Connection to check the connection, then click Save. The connection test reads a single row from sys_user.
Required Permissions
The service account needs read access to the tables agents query, plus write access to the incident journal for the investigation write-back:
| Table / field | Access | Why it's needed |
|---|---|---|
cmdb_ci (+ class tables) and cmdb_rel_ci | read | Configuration items and their relationships (topology, blast radius) |
incident | read | Incident timelines for root-cause analysis and customer impact |
problem | read | Problem records for the RCA ledger |
change_request | read | Change records for change-risk and blast-radius analysis |
sys_user_group, sys_user, sys_user_grmember | read | Assignment groups, users, and membership for SME routing |
kb_knowledge | read | Knowledge articles (runbooks, SOPs) |
incident → work_notes | write | Post investigation work notes back onto the incident (write-back) |
Grant read + write access. Read access covers the query tables above (e.g.
snc_read_only). Write access to the incident journal (work_notes) lets
Autoheal post investigation work notes back onto
the incidents it investigates. The built-in itil role covers the write, or
you can add a scoped write ACL on incident. A purely read-only account still
answers data queries, but every work-note post is rejected with a 403.
Example Queries
Once connected, you can ask an agent questions like:
Show me the open P1 incidents for the Payments business service
What does the payments-api CI depend on, and what depends on it?
List the change requests that touched the checkout database in the last 7 days
Which assignment group owns the order-service, and who are its members?
How many configuration items exist per CMDB class?
Catalog Sync
ServiceNow can populate the Autoheal catalog with your organizational context:
| ServiceNow source | Catalog entity |
|---|---|
Assignment groups (sys_user_group) | Team |
Users (sys_user) | Person |
Business / application services (cmdb_ci_service) | Service |
Configuration items (cmdb_ci) | Configuration Item |
A CMDB can hold tens of thousands of items, so the sync runs as a background job. The job reads ServiceNow page by page with rate-limiting, and it never blocks the UI. Trigger it with an authenticated POST /api/v1/catalog/servicenow/sync/{integrationId} (the caller needs integration-write access for the tenant). Re-run it any time to refresh. The sync matches entities on their ServiceNow sys_id, so re-runs update in place.
The catalog sync brings in entities, ownership, and group membership. Fine-grained CI-to-CI dependency edges are read on demand during investigations, through the CMDB relationship lookup. As a result, the catalog stays accurate without snapshotting the entire relationship graph.
Alert Source Setup
ServiceNow can act as an alert source by forwarding incidents to Autoheal, where each incident becomes an alert that Autoheal triages and investigates automatically. Unlike tools with a built-in webhook UI, ServiceNow forwards records with a small Business Rule. A Business Rule is a script that runs whenever an incident is created or updated. This works on every ServiceNow instance and needs no IntegrationHub license.
Each incident lands as one alert group (keyed on the incident sys_id). Later updates refresh that alert group. Every field, including your custom u_* fields, is captured with both its raw value and its human-readable display value.
- Open your ServiceNow integration in Autoheal
- Scroll to the Alert Source section
- Enable the webhook and copy the Webhook URL
- Optionally, enter a Webhook Signing Secret — any token you choose. You'll paste the same value into the script below so Autoheal can authenticate incoming alerts.
- In ServiceNow, go to System Definition → Business Rules and click New. Keep the Application scope as Global (the default). The script below uses global-scope APIs.
- Set Table to Incident [incident] and check the Advanced checkbox (this reveals the When field and the Advanced tab).
- On the When to run tab, set When to After, not Async. Check both Insert and Update. (An after rule reliably exposes the create-vs-update operation and the instance base URL the script needs. Async rules do not. Optionally, set Filter Conditions to forward only the incidents you care about, e.g. Priority · is one of · 1 - Critical, 2 - High.)
- On the Advanced tab, paste the script below into the Script field. Then set
ENDPOINTto the Webhook URL you copied. SetSECRETto the Webhook Signing Secret, or leave it''. - Click Submit.
(function executeRule(current, previous) {
// ── Paste these two values from the Autoheal integration page ──────────
var ENDPOINT = 'https://<your-tenant>.autoheal.ai/api/v1/webhooks/servicenow/<webhook-secret>'; // the "Webhook URL"
var SECRET = ''; // the "Webhook Signing Secret" you set in Autoheal, or leave '' to skip auth
// ───────────────────────────────────────────────────────────────────────
var MAX_FIELD_CHARS = 2000; // cap huge fields (journal comments, work notes)
var MAX_BODY_CHARS = 900000; // stay under Autoheal's 1 MB request limit
function trunc(s) {
if (s === null || s === undefined) return '';
s = String(s);
return s.length > MAX_FIELD_CHARS ? s.substring(0, MAX_FIELD_CHARS) + '...[truncated]' : s;
}
// Emit EVERY field on the record — standard and custom (u_*) alike — as
// { value: <raw>, display_value: <human-readable> }.
var fields = {};
var elements = current.getElements();
for (var i = 0; i < elements.size(); i++) {
var el = elements.get(i);
var name = String(el.getName());
var raw = '';
var display = '';
try { raw = trunc(current.getValue(name)); } catch (e1) { /* skip unreadable */ }
try { display = trunc(el.getDisplayValue()); } catch (e2) { /* skip unreadable */ }
fields[name] = { value: raw, display_value: display };
}
// Instance base URL. glide.servlet.uri resolves inside an "after" rule;
// fall back to the instance name for incidents created without an HTTP
// context (e.g. inbound email or another integration).
var instanceUrl = String(gs.getProperty('glide.servlet.uri', ''));
if (!instanceUrl) {
instanceUrl = 'https://' + gs.getProperty('instance_name') + '.service-now.com';
}
if (instanceUrl.length > 0 && instanceUrl.charAt(instanceUrl.length - 1) === '/') {
instanceUrl = instanceUrl.substring(0, instanceUrl.length - 1);
}
var payload = {
event_type: (current.operation() == 'insert') ? 'incident.created' : 'incident.updated',
schema_version: '1.0',
instance_url: instanceUrl,
incident_url: instanceUrl + '/incident.do?sys_id=' + current.getUniqueValue(),
sent_at: new GlideDateTime().getValue(),
incident: fields
};
var body = JSON.stringify(payload);
if (body.length > MAX_BODY_CHARS) {
// Pathologically large record: send core fields only. The full record
// is still readable via the Autoheal ServiceNow data-source integration.
var core = ['sys_id', 'number', 'short_description', 'description', 'state',
'impact', 'urgency', 'priority', 'category', 'subcategory',
'assignment_group', 'assigned_to', 'caller_id', 'cmdb_ci',
'opened_at', 'resolved_at', 'closed_at', 'sys_created_on',
'sys_updated_on', 'close_code', 'close_notes'];
var slim = {};
for (var j = 0; j < core.length; j++) {
if (fields[core[j]]) slim[core[j]] = fields[core[j]];
}
payload.incident = slim;
body = JSON.stringify(payload);
}
try {
var r = new sn_ws.RESTMessageV2();
r.setEndpoint(ENDPOINT);
r.setHttpMethod('POST');
r.setRequestHeader('Content-Type', 'application/json');
if (SECRET) {
r.setRequestHeader('Authorization', 'Bearer ' + SECRET);
}
r.setRequestBody(body);
r.executeAsync(); // sent asynchronously — ServiceNow does not wait for Autoheal's response
} catch (ex) {
gs.error('Autoheal webhook business rule failed: ' + ex);
}
})(current, previous);
Create or update a test incident. Then check that it appears on Autoheal's Alerts page. In ServiceNow, you can inspect delivery under System Logs → Outbound HTTP Requests. To see request bodies, set the outbound web-service log level to Elevated or All. ServiceNow sends both created and updated events to the same endpoint. Resolving, closing, or canceling the incident automatically resolves the Autoheal alert.
The Webhook Signing Secret is an optional second layer of authentication. The
webhook URL already contains a unique secret that identifies your integration.
The signing secret adds verification through the Authorization: Bearer <secret>
header that the script sends. If you leave SECRET empty in the script, leave the
Webhook Signing Secret blank in Autoheal too.
Investigation Write-Back
An incident can be forwarded as an alert (see Alert Source Setup). When Autoheal investigates such an incident, it posts the investigation's progress back onto that same incident as work notes. Work notes are internal, fulfiller-visible entries in the incident's Activity stream. This way, your ITIL team stays in ServiceNow without switching tools. No setup is required beyond the alert source and a write-capable service account (below). Autoheal enables write-back automatically for ServiceNow-sourced incidents.
Autoheal posts a work note at these lifecycle points:
- Investigation started — with a link to follow along in Autoheal.
- Root-cause hypothesis — the finalized most-likely cause, with a confidence label. Preliminary/iterating hypotheses are suppressed, so the incident gets a single root-cause note rather than a stream.
- Needs input / paused for approval — when the agent needs a human to answer a question or approve a gated action.
- Investigation complete and postmortem generated.
Each note ends with a "🤖 Posted automatically by Autoheal" attribution line so it's never mistaken for a human comment.
The platform posts these status updates, not an agent tool call, so approval policies don't apply to them.
This is the only thing Autoheal writes to ServiceNow, and only on incidents you forward to it as alerts. Autoheal writes the investigation's progress, or a one-line note when it decides not to investigate (see When an investigation is skipped). It posts to internal Work notes, never to the customer-facing Additional comments. It never modifies any other field or record.
The write-back needs write access to the incident journal (work_notes). This access
is the built-in itil role or a scoped write ACL on incident. You grant it when you create
the service account (see Required Permissions). A purely read-only
account (e.g. snc_read_only alone) can still read and receive alerts. But each
work-note post is rejected with a 403. ServiceNow journal fields are plain
text, so links appear as label: https://… (not a labelled hyperlink). Your instance's
activity-stream settings control whether the URL renders clickable.
When an investigation is skipped
Autoheal doesn't always start an investigation for a forwarded incident. When it decides not to, it posts a short work note so your team isn't left wondering whether anything happened. Three reasons a skip happens:
- A recent investigation already found the root cause for a matching alert — the note links that earlier investigation. Always posted.
- Your workspace reached its investigation limit (daily or weekly) — the note names which limit. Always posted.
- A skip rule you configured matched the alert — off by default. Because you wrote the rule to cut noise, the note stays quiet unless you enable it.
To get a work note when one of your own skip rules skips an incident:
- Go to Settings → Alert Response → Investigate Group.
- Expand the skip rule.
- Enable Notify the source ticket.
(The toggle appears only when a Pylon, Jira, or ServiceNow integration is connected.)
Troubleshooting
401 Unauthorized
- Check that the username/password (basic) or OAuth Client ID/Secret are correct and that the account is active
- Check that the Instance URL is your ServiceNow base URL (e.g.
https://acme.service-now.com), not an API path - Client Credentials: check that the Application Registry endpoint is active, allows the client-credentials grant (Washington DC+), and is bound to the service-account user
- Client Credentials, if the token request itself fails with
server_error/access_denied: this is the token mint being refused, not bad credentials. Check these items, in order:- The instance-wide property
glide.oauth.inbound.client.credential.grant_type.enabledistrue. Client-credentials is disabled by default. - The OAuth client's OAuth application user is set. That user is Active, has no Password needs reset flag, and is a valid (Machine Identity) account.
- The instance-wide property
- If your instance enforces SSO, ensure the service account can still authenticate locally (basic auth authenticates as the user directly)
403 Forbidden / Empty Results for a Table
- The service account lacks read access (ACL/role) for that table
- Grant
snc_read_onlyor the specific table read ACLs (see Required Permissions)
No Records Returned
- Check your filter — ServiceNow uses encoded query syntax (e.g.
active=true^priority=1), not SQL - Reference fields (assignment group, CI) are matched by display value by default. Check that the name matches
- Widen the time range or remove filters to check that data exists
Instance URL Rejected / Not an Allowed Domain
- Autoheal only sends credentials to ServiceNow-owned domains (
*.service-now.com,*.servicenowservices.com) - If your instance uses a custom/vanity domain (e.g.
https://snow.acme.com), ask your Autoheal operator to allow that host. The operator adds that host or its parent domain to theSERVICENOW_ALLOWED_INSTANCE_HOSTSdeployment setting. Then save again - The URL must use
httpsand be the base URL (no path, query, or fragment)
Rate Limiting / Slow Catalog Sync
- ServiceNow enforces per-instance and per-account transaction limits
- Agents and the catalog sync both rate-limit their requests. Very large CMDBs simply take longer to sync
- Use more specific queries (fewer fields, tighter filters) to keep responses fast
Alert Source: Webhook Returns 401 Unauthorized
- The
SECRETvalue in your Business Rule script must exactly match the Webhook Signing Secret set on the integration in Autoheal - The script must send it as an
Authorization: Bearer <secret>header. The provided script does this automatically whenSECRETis non-empty - If you don't want signature verification, clear the Webhook Signing Secret in Autoheal and leave
SECRETempty ('') in the script
Alert Source: Incidents Not Appearing in Autoheal
- Check that the Business Rule is Active and set to run After, with Insert and Update checked
- In ServiceNow, open System Logs → Outbound HTTP Requests and check the request status and URL. A non-2xx status shows the error Autoheal returned
- Check that the
ENDPOINTis the full Webhook URL copied from Autoheal (https://<tenant>/api/v1/webhooks/servicenow/<secret>) - Check that your ServiceNow instance can reach the Autoheal host over outbound HTTPS (443). Check that no Filter Condition on the rule excludes your test incident
- A 413 Payload Too Large means the incident exceeded 1 MB. The script already truncates long fields. If the record is still too large, the script sends only core fields. But a custom field with a very large value can still cause this error. If needed, trim that field in the script's
corelist
Write-Back: Work Notes Not Appearing on the Incident
- Most common cause: the service account lacks write access to the incident journal. Reads and alert forwarding can succeed while the work-note post is rejected with a 403. Grant the
itilrole or a scoped write ACL onincident.work_notes(see Investigation Write-Back) - Write-back only fires for incidents forwarded as alerts and investigated. Check that the incident shows on the Alerts page and that an investigation ran
- Only the final root-cause hypothesis posts (preliminary ones are suppressed), so a still-running investigation may have posted only the "started" note so far
- Autoheal writes to Work notes, not Additional comments. Check the internal Work notes stream, not the customer-visible comments
BYOC: can't reach the instance
All authentication modes require the Autoheal host to make outbound HTTPS (443) calls to your ServiceNow instance. This includes OAuth, where Autoheal mints tokens at https://<instance>/oauth_token.do.
- Check that the Autoheal
api-server-gocontainer has outbound egress to your instance host (e.g.*.service-now.com) - If your network routes outbound traffic through a proxy, set
HTTP_PROXY/HTTPS_PROXY(andNO_PROXY) on the Autoheal stack. Autoheal honors these variables automatically - If a private/internal CA signs your instance's certificate (e.g. behind a TLS-terminating gateway), install that CA bundle into the
api-server-gocontainer's trust store. Or, front the instance with a publicly-trusted certificate. Do not disable TLS verification in production. Disabled certificate validation lets an attacker on the egress/proxy path present a forged certificate. The attacker can then capture your ServiceNow credentials (Basic password, or the OAuth client secret and token) - If your instance is fronted by a custom/vanity domain or is only reachable on a private network, see the "Instance URL Rejected" item above. Also contact your Autoheal operator