ServiceNow OAuth 2.0 Setup
Configure OAuth 2.0 bearer-token authentication for ServiceNow actions in Simple Chat using ServiceNow's current inbound integration flow.
This guide matters when Basic Auth is not acceptable and you want a cleaner production authentication story for ServiceNow actions. The important idea is that OAuth setup here still depends on a dedicated ServiceNow user because the token executes with that user’s permissions.
Create a dedicated integration user
The OAuth token should represent a service identity with only the roles required for the ServiceNow operations you plan to expose.
Create the OAuth application
ServiceNow's inbound integration flow generates the client ID and client secret you need before Simple Chat can request bearer tokens.
Obtain and store the token
Use cURL, PowerShell, or Python to request the access token, then store it securely and plan for refresh before expiry becomes an outage.
Wire it into the action
Once the token exists, the Simple Chat action configuration becomes straightforward: the bearer token is what the OpenAPI action sends on each request.
Both credential sets matter
The token request needs the OAuth app credentials and the ServiceNow integration-user credentials. That is the easiest place to get confused, so keep those identities clearly separated as you configure the flow.
Version: 0.237.005
Implemented in version: 0.237.005
Overview
This guide shows you how to configure OAuth 2.0 bearer token authentication for ServiceNow integration with Simple Chat using the modern “New Inbound Integration Experience” method. This is more secure than Basic Auth and recommended for production environments.
Note: This guide uses the current ServiceNow OAuth configuration method. The deprecated “Create an OAuth API endpoint for external clients” method is no longer recommended.
Prerequisites
- ServiceNow instance (Developer or Production)
- Admin access to ServiceNow
- ServiceNow integration user with appropriate roles (e.g.,
itil,incident_manager)- Best Practice: Create a dedicated user (e.g.,
simplechat_integration) instead of using a personal account - This user’s permissions determine what the OAuth token can access
- Best Practice: Create a dedicated user (e.g.,
- Existing Simple Chat ServiceNow action (or create new one)
Part 1: Configure OAuth in ServiceNow
Step 1: Create ServiceNow Integration User (Recommended)
Before creating the OAuth application, create a dedicated integration user:
- Navigate to User Administration:
- In ServiceNow, search for: “Users” in the left navigation filter
- Click: System Security > Users
- Create New User:
- Click “New”
- Fill in the form:
User ID: simplechat_integration First name: Simple Chat Last name: Integration Email: your-email@example.com Password: [Set a strong password - save this!]
- Assign Roles:
- Click on the Roles tab
- Add appropriate roles based on your Simple Chat use case:
itil- Read access to ITIL tables (incidents, problems, changes)incident_manager- Create and update incidentsknowledge- Read knowledge base articles
- Security Best Practice: Grant only the minimum roles needed for Simple Chat operations
- Activate and Save:
- Check the “Active” checkbox
- Click “Submit”
- Save These Credentials (you’ll need them in Step 3):
ServiceNow Integration User Username: simplechat_integration Password: [the password you set]
Why Create a Dedicated User?
- ✅ Security: Limit blast radius if credentials are compromised
- ✅ Audit Trail: Clear visibility in ServiceNow logs (shows “simplechat_integration” performed actions)
- ✅ Permission Control: Grant only the specific roles needed, not your full admin rights
- ✅ Lifecycle Management: Can deactivate or rotate credentials without affecting personal accounts
Step 2: Create OAuth Application
- Log in to your ServiceNow instance as an admin
- URL:
https://devnnnnnn.service-now.com
- URL:
- Navigate to OAuth Application Registry:
System OAuth > Application RegistryOr search for “OAuth” in the navigation filter
- Create New OAuth Integration:
- Click New
- Select “New Inbound Integration Experience” (recommended for external clients)
- ⚠️ Do NOT use the deprecated “Create an OAuth API endpoint for external clients”
-
Select OAuth Grant Type:
ServiceNow will present you with several OAuth grant type options:
For this POC, select: “OAuth - Resource owner password credential grant”
📋 Why This Grant Type for POC:
- ✅ Trusted application scenario: Simple Chat is a trusted first-party application on your Azure infrastructure
- ✅ User context preserved: Actions execute with the integration user’s permissions and audit trail
- Token request requires: OAuth app credentials (Client ID/Secret) + ServiceNow user credentials (Username/Password)
- ServiceNow issues token on behalf of that specific user
- All API calls execute with that user’s roles, ACLs, and permissions
- Audit logs show the integration user’s name, not just “OAuth app”
- ✅ Simple token management: Easy to obtain and refresh tokens programmatically
- ✅ Development/testing friendly: Works well for POC without complex OAuth flows
- ✅ Server-to-server integration: Simple Chat backend directly requests tokens using credentials
⚠️ IMPORTANT - Review Grant Type for Production:
The OAuth grant type should be revisited based on your customer’s security requirements and deployment scenario:
Grant Type Best For Use When Resource Owner Password Trusted apps, POC/Dev App is first-party, trusted infrastructure, need user context Client Credentials Machine-to-machine No user context needed, service account only Authorization Code Third-party apps Interactive user consent required, multi-tenant scenarios JWT Bearer Advanced scenarios Token exchange, federated identity, microservices Production Considerations:
- If customer requires no password storage, use Authorization Code grant with PKCE
- If customer requires service account only, use Client Credentials grant
- If customer has strict OAuth compliance, avoid Resource Owner Password grant (considered legacy by some standards)
- If integrating with external identity providers, use JWT Bearer or Authorization Code grant
Always align the grant type choice with your customer’s security policies and compliance requirements.
-
Configure the Integration Form:
ServiceNow presents a “New record” form with several sections. Configure as follows:
Details Section:
Name: Simple Chat Integration Provider name: Azure app service (auto-filled) Client ID: (auto-generated - COPY THIS!) Client secret: (auto-generated - COPY THIS IMMEDIATELY!) Comments: OAuth integration for Simple Chat AI assistant Active: ☑ CheckedAuth Scope Section:
Auth scope: useraccount (default) Limit authorization to following APIs: (leave empty for POC)⚠️ The “useraccount” scope grants access to all resources available to the signed-in user. This is acceptable for POC with a dedicated integration user account. For production, consider creating custom scopes to limit access to only required APIs.
Advanced Options (optional):
Enforce token restriction: ☐ Unchecked (for POC) Token Format: Opaque (default) Access token lifespan (seconds): 3600 (1 hour - recommended for POC) Refresh token lifespan (seconds): 86400 (24 hours - recommended for POC)Note: ServiceNow defaults to 1800 seconds (30 min) for access tokens, which is too short for testing. Change to longer based on your needs or the dev/testing duration.
-
⚠️ CRITICAL - Copy Credentials BEFORE Saving:
Before clicking “Save”, you MUST copy these values:
- Client ID: Visible in plain text (e.g.,
565d53a80dfe4cb89b8869fd1d977308)- Select and copy the entire value
- Client Secret: Hidden behind dots
- Click the 👁️ (eye icon) to reveal, OR
- Click the 📋 (copy icon) to copy directly
- This may only be shown once - copy it now!
Save these values securely - paste them into a text file or password manager immediately.
Example format to save:
ServiceNow OAuth Credentials Instance: https://devnnnnnn.service-now.com Client ID: 565d53a... Client Secret: [paste the revealed secret here] Token Endpoint: https://devnnnnnn.service-now.com/oauth_token.do Username: <unique name> - Client ID: Visible in plain text (e.g.,
-
Click “Save”
- Note the token endpoint:
- Token endpoint:
https://devnnnnnn.service-now.com/oauth_token.do
- Token endpoint:
Step 3: Obtain Access Token
You have two options to get an access token.
Important: The token request requires BOTH:
- OAuth App Credentials:
client_idandclient_secret(from Step 1)- ServiceNow User Credentials:
usernameandpassword(integration user you created)The resulting token will execute API calls as that integration user with their specific roles and permissions.
Option A: Using REST Client (Postman/cURL/PowerShell)
Using cURL:
curl -X POST https://devnnnnnn.service-now.com/oauth_token.do \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "client_id=YOUR_CLIENT_ID" \ # OAuth app Client ID
-d "client_secret=YOUR_CLIENT_SECRET" \ # OAuth app Client Secret
-d "username=YOUR_USERNAME" \ # ServiceNow integration user
-d "password=YOUR_PASSWORD" # Integration user's password
Using PowerShell (recommended for Windows):
$response = Invoke-RestMethod -Uri "https://devnnnnnn.service-now.com/oauth_token.do" `
-Method Post `
-ContentType "application/x-www-form-urlencoded" `
-Body @{
grant_type="password"
client_id="YOUR_CLIENT_ID" # OAuth app Client ID
client_secret="YOUR_CLIENT_SECRET" # OAuth app Client Secret
username="YOUR_USERNAME" # ServiceNow integration user
password="YOUR_PASSWORD" # Integration user's password
}
# Display the response
$response | ConvertTo-Json -Depth 10
Response:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"scope": "useraccount",
"token_type": "Bearer",
"expires_in": 31536000
}
Option B: Using Python Script
Create get_servicenow_token.py:
#!/usr/bin/env python3
"""
Get ServiceNow OAuth access token for Simple Chat integration.
Requires BOTH:
- OAuth App credentials (Client ID/Secret from ServiceNow OAuth registry)
- ServiceNow integration user credentials (Username/Password)
The token will execute API calls as the integration user with their permissions.
"""
import requests
import json
# ServiceNow OAuth App credentials (from Step 1 - OAuth registry)
SERVICENOW_INSTANCE = "https://devnnnnnn.service-now.com"
CLIENT_ID = "YOUR_CLIENT_ID" # From OAuth Application Registry
CLIENT_SECRET = "YOUR_CLIENT_SECRET" # From OAuth Application Registry
# ServiceNow integration user credentials (dedicated user with specific roles)
USERNAME = "YOUR_USERNAME" # e.g., simplechat_integration
PASSWORD = "YOUR_PASSWORD" # Integration user's password
def get_access_token():
"""Get OAuth access token from ServiceNow."""
url = f"{SERVICENOW_INSTANCE}/oauth_token.do"
data = {
'grant_type': 'password',
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'username': USERNAME,
'password': PASSWORD
}
response = requests.post(url, data=data)
if response.status_code == 200:
token_data = response.json()
print("✅ Access Token obtained successfully!")
print(f"\nAccess Token: {token_data['access_token']}")
print(f"Expires in: {token_data['expires_in']} seconds")
print(f"Token Type: {token_data['token_type']}")
# Save to file
with open('servicenow_token.json', 'w') as f:
json.dump(token_data, f, indent=2)
print("\n📁 Token saved to servicenow_token.json")
return token_data['access_token']
else:
print(f"❌ Failed to get token: {response.status_code}")
print(response.text)
return None
if __name__ == "__main__":
get_access_token()
Run the script:
python get_servicenow_token.py
Part 2: Configure Action in Simple Chat
Step 1: Navigate to Actions Configuration
- Navigate to Actions page:
- Go to Settings > Actions (Global) or Group Settings > Actions (Group-specific)
- Edit your ServiceNow action or click “Create New Action”
Step 2: Upload OpenAPI Specification
- Action Details:
Name: ServiceNow Query Incidents (or your preferred name) Display Name: ServiceNow - Query Incident Description: Query ServiceNow incidents with filters - OpenAPI Specification:
- Upload your
servicenow_incident_api.yamlfile - Or paste the OpenAPI spec content directly
- Upload your
- Base URL:
https://devnnnnnn.service-now.com/api/now(Replace devnnnnnn with your actual ServiceNow instance)
Step 3: Configure Bearer Token Authentication
In the Authentication Configuration section:
- Select Authentication Type:
- From the “Type” dropdown, select: Bearer Token
- Enter Token:
- Paste your access token in the “Token” field
YOUR_ACCESS_TOKEN_FROM_PART_1_STEP_2(Use the actual token obtained from Part 1, Step 2)
- Paste your access token in the “Token” field
- Save the Action
That’s it! Simple Chat will automatically:
- Add
Authorization: Bearer YOUR_TOKENheader to all requests - Handle the token properly for ServiceNow API authentication
Production Considerations:
For production deployments, consider the following:
- Secure Token Storage: Store the OAuth token in Azure Key Vault rather than directly in the action configuration
- Enables centralized secret management and rotation
- Provides audit logging for secret access
- Allows token updates without modifying Simple Chat configuration
- Token Expiration Management: OAuth tokens have limited lifespans (typically 1-8 hours)
- Monitor token expiration: Set up alerts before tokens expire
- Implement token refresh: Use the refresh token to obtain new access tokens automatically
- Automated renewal: Consider creating an Azure Function or scheduled task to refresh tokens periodically
- See the “Token Refresh Strategy” section below for implementation options
- Graceful Failure Handling: Implement monitoring to detect authentication failures due to expired tokens
Part 3: Testing
Test with Simple Chat Agent
- Open Simple Chat and select your ServiceNow agent
- Test query:
Show me recent incidents - Check logs for successful authentication:
Added bearer auth: eyJ0eXAi... Authorization: Bearer eyJ0eXAi...
Test with Curl
curl -X GET \
"https://devnnnnnn.service-now.com/api/now/table/incident?sysparm_limit=5" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Accept: application/json"
Token Refresh Strategy
OAuth tokens expire. Here are your options:
Option 1: Manual Refresh (Simple)
- Set calendar reminder before token expires
- Run
get_servicenow_token.pyscript - Update Key Vault secret
- Simple Chat will use new token automatically
Option 2: Automatic Refresh (Advanced)
Create a scheduled task/Azure Function to refresh tokens:
# refresh_servicenow_token.py
import requests
from azure.keyvault.secrets import SecretClient
from azure.identity import DefaultAzureCredential
def refresh_token():
# Get refresh token from Key Vault
credential = DefaultAzureCredential()
client = SecretClient(vault_url="https://your-vault.vault.azure.net", credential=credential)
refresh_token = client.get_secret("servicenow-refresh-token").value
# Request new access token
response = requests.post(
"https://devnnnnnn.service-now.com/oauth_token.do",
data={
'grant_type': 'refresh_token',
'refresh_token': refresh_token,
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET
}
)
if response.status_code == 200:
new_token = response.json()['access_token']
# Update Key Vault
client.set_secret("servicenow-oauth-token", new_token)
print("✅ Token refreshed successfully!")
else:
print(f"❌ Refresh failed: {response.text}")
if __name__ == "__main__":
refresh_token()
Schedule with Azure Function (Timer Trigger):
Trigger: Every 50 minutes (before 1-hour expiration)
Option 3: Long-Lived Tokens
Configure longer token lifespans in ServiceNow:
Access Token Lifespan: 28800 (8 hours)
Refresh Token Lifespan: 604800 (7 days)
Security Best Practices
✅ DO:
- Store tokens in Azure Key Vault
- Use HTTPS for all requests
- Set appropriate token expiration times
- Rotate tokens regularly
- Use refresh tokens to avoid storing passwords
- Monitor token usage in ServiceNow
❌ DON’T:
- Hardcode tokens in code
- Share tokens between environments
- Use overly long token lifespans
- Commit tokens to source control
- Use the same credentials for dev and prod
Comparison: Basic Auth vs OAuth Bearer
| Aspect | Basic Auth | OAuth Bearer Token |
|---|---|---|
| Security | Lower (credentials in every request) | Higher (token-based, expirable) |
| Setup | Simple | Moderate complexity |
| Token Expiration | None | Configurable (1-8 hours) |
| Rotation | Manual password change | Automatic with refresh tokens |
| Audit Trail | Username-based | Token-based (better tracking) |
| Revocation | Change password (affects all) | Revoke individual tokens |
| Best For | Development/Testing | Production environments |
Troubleshooting
Error: “invalid_client”
- Verify Client ID and Client Secret are correct
- Check OAuth application is active in ServiceNow
Error: “invalid_grant”
- Check username and password are correct
- Verify user has necessary roles in ServiceNow
Error: 401 Unauthorized with Bearer Token
- Token may have expired - refresh it
- Verify token is being sent correctly:
Authorization: Bearer TOKEN - Check token wasn’t truncated when copying
Next Steps
- Complete OAuth setup in ServiceNow
- Get initial access token using script or Postman
- Store token in Key Vault (recommended)
- Update action configuration in Simple Chat
- Test with agent to verify authentication works
- Set up token refresh strategy (manual or automated)