Skip to main content

Entra-ServiceNow Connector: Environment & API Reference

What exactly this connector queries, what permissions it needs, and what test data must exist for it to produce output.

Read architecture/11-platform-mental-model.md first for the conceptual model.


Credentials Required

# Azure Entra (app registration with client_credentials grant)
AZURE_TENANT_ID=<directory-tenant-id>
AZURE_CLIENT_ID=<app-registration-client-id>
AZURE_CLIENT_SECRET=<app-registration-secret>

# ServiceNow (basic auth API user)
SERVICENOW_INSTANCE=<instance-name> # e.g. "dev12345" (not full URL)
SERVICENOW_USERNAME=<integration-user>
SERVICENOW_PASSWORD=<password>

Azure Entra Permissions

PermissionRequired?Purpose
Application.Read.AllYesDiscover all service principals
Directory.Read.AllYesRead SP owners and directory context
User.Read.AllYesEnrich owner records (status, department)
AuditLog.Read.AllRecommendedSign-in logs (execution evidence). Needs Azure AD P1/P2 licence

ARM RBAC (assigned via Azure Portal → Subscription → IAM)

RoleScopePurpose
ReaderSubscription(s)Enumerate Function Apps, resolve managed identities, read role assignments

ServiceNow Permissions

The connector needs a read-only API user. Recommended: create a dedicated integration_user with custom ACL policy.

Tables queried (all read-only)

Core discovery (must have access):

TableWhat's fetchedWhy
oauth_entityOAuth apps (client_id, name, active)Cross-system correlation with Azure SPs
sys_rest_messageOutbound REST endpointsDiscover external API connections
sys_rest_message_fnHTTP methods per REST messageExecution chain detail
oauth_entity_profileOAuth profile → entity mappingLink credentials to connections
sys_scriptBusiness Rules (name, table, script)Workload discovery + caller analysis
sys_script_includeScript Includes (name, script)Indirect execution chain callers
sysauto_scriptScheduled JobsRecurring automation workloads
sys_userUser accounts (name, email, active)Owner lookup and validation

Flow Designer (must have access if flows exist):

TableWhat's fetchedWhy
sys_hub_flowFlow definitions (name, status, triggers)Flow Designer workload discovery
sys_hub_trigger_instanceDeployed flow triggersWhat events trigger flows
sys_hub_action_instanceHTTP/REST actions within flowsEgress detection
sys_hub_flow_versionFlow version payloadsConnection alias resolution
sys_connectionConnection aliasesResolve URLs for flow HTTP actions

Execution evidence (optional, scan continues without):

TableWhat's fetchedWhy
sys_flow_contextFlow execution records (last 30d)Prove flow actually ran
sys_triggerJob trigger recordsProve scheduled job ran
sys_logSyslog entries from Script IncludesStructured execution evidence

Trigger examples (optional, scan continues if denied):

TableWhat's fetchedWhy
incidentRecent incident recordsTrigger provenance context
change_requestRecent change recordsTrigger provenance context
sc_requestRecent catalog requestsTrigger provenance context

Azure Graph API Calls (exact endpoints)

Service Principal Discovery

GET /v1.0/servicePrincipals

Paginates via @odata.nextLink. Filters to first-party SPs (same tenant). Currently fetches all then filters client-side.

Per matched SP (for each cross-system integration)

GET /v1.0/servicePrincipals/{sp_id}/owners
GET /v1.0/auditLogs/signIns?$filter=appId eq '{app_id}' and createdDateTime ge {30d_ago}&$top=100
GET /v1.0/servicePrincipals/{sp_id}/appRoleAssignments
GET /v1.0/servicePrincipals/{sp_id}/oauth2PermissionGrants

ARM (only if Function App endpoints detected)

GET https://management.azure.com/subscriptions?api-version=2020-01-01
GET https://management.azure.com/subscriptions/{sub}/providers/Microsoft.Web/sites?api-version=2023-12-01
GET https://management.azure.com/subscriptions/{sub}/providers/Microsoft.Authorization/roleAssignments?$filter=principalId eq '{id}'
GET /v1.0/servicePrincipals/{principal_id} (resolve managed identity)

Scan Phases (execution order)

Phase 1 — Cross-service identity binding:

  1. Fetch all Azure SPs (Graph)
  2. Fetch all ServiceNow OAuth entities (SN Table API)
  3. Match by client_id = appId
  4. For each match: fetch owners, sign-in logs, app roles, delegated permissions

Phase 2 — Execution chain discovery: 5. Fetch all ServiceNow REST Messages 6. For each: fetch HTTP methods, OAuth profiles 7. Fetch Business Rules, Script Includes, Scheduled Jobs 8. Trace callers: which scripts reference which REST Messages 9. Build execution chains (workload → script → REST message → OAuth → Azure SP)

Phase 3 — Flow Designer: 10. Fetch flow triggers, published flows 11. For each flow: fetch HTTP actions, resolve connection aliases 12. Classify egress targets

Phase 4 — Execution evidence: 13. Query sys_flow_context for recent flow runs 14. Query sys_trigger for recent job executions 15. Query sys_log for Script Include execution traces

Phase 5 — ARM resolution (if Function App detected): 16. Enumerate subscriptions → Function Apps → resolve managed identity 17. Fetch RBAC role assignments for managed identity


Test Data Requirements

For the connector to produce meaningful output in a dev environment, these must exist:

Minimum viable test data

  1. Azure SP with a known appId (e.g., 560ad26b-...)
  2. ServiceNow OAuth Entity with client_id matching that appId
  3. ServiceNow REST Message with authentication_type: "OAuth2.0" pointing to that OAuth entity
  4. ServiceNow Business Rule whose script field references the REST Message name (e.g., RESTMessageV2('Graph - sn-router', 'post'))

This gives you one complete execution chain: BR → REST Message → OAuth → Azure SP.

For richer output

  1. Flow Designer flow (published, active) with an HTTP action calling an external URL
  2. Flow trigger (e.g., record_create on incident)
  3. Recent sys_flow_context record (last 30 days) for that flow
  4. Azure SP with an owner (so ownership findings can fire)
  5. Azure SP with app role assignments (so permission analysis works)

What the current dev environment has

Our Contoso Corp dev setup (SERVICENOW_INSTANCE=dev*, Azure tenant bcf375ed-...) contains:

  • 24 Azure SPs (filtered from 122 total)
  • 23 ServiceNow OAuth entities
  • 3 matched cross-system integrations:
    • servicenow-openai-clientAzure OpenAI OAuth - sm
    • sn-ticket-routerAzure Graph OAuth Client
    • sn-ticket-router (second OAuth profile)
  • 9 outbound REST Messages (4 matched to Azure, 5 unmatched)
  • 83 Flow Designer flows with autonomous triggers
  • 4 flows with recent execution records
  • 1 Function App (sv0-edr-stub-7165) with managed identity resolution

Evidence Completeness

The connector reports what data it could and couldn't access:

Evidence SourceStatus when workingCommon failure
Azure SPsavailableWrong AZURE_CLIENT_SECRET → auth failure
SP ownersavailableMissing Directory.Read.All
Sign-in logsavailable or unavailable_not_enabledNo P1/P2 licence, or missing AuditLog.Read.All
SN OAuth entitiesavailableWrong SN credentials, or ACL blocks oauth_entity
SN execution chainsavailableACL blocks sys_script or sys_rest_message
SN flow executionspartialACL blocks sys_flow_context
ARM role assignmentsavailable or unavailable_no_accessMissing Reader role on subscription

Troubleshooting

"0 matched integrations" — No ServiceNow OAuth entity has a client_id matching any Azure SP appId. Create a test OAuth entity with a matching client_id.

"0 execution chains" — No Business Rules or Script Includes reference a REST Message name in their script body. Create a BR that calls RESTMessageV2('Your REST Message Name', 'post').

Sign-in logs empty — Either the SP hasn't authenticated in 30 days, or the tenant lacks Azure AD P1/P2 licence, or AuditLog.Read.All permission isn't granted.

"Failed to query sys_log: 400" — The ServiceNow user lacks read access to sys_log. Non-blocking; connector continues without syslog evidence.