ServiceNow integration
ServiceNow is SARC’s workflow control plane. Where the Evidence Vault (Fides) holds the immutable evidence, ServiceNow holds the human change process — the change request, the approval, the CMDB, problems, incidents, and SLAs. SARC talks to ServiceNow in both directions: the CI pipeline writes the change record and its evidence, and the SARC portal reads that data back to drive decisions and surface it to operators and auditors.
This page is the full story: why, the technical design, what lands in ServiceNow, how the portal consumes it, and how SARC turns ServiceNow data into decisions. Use the Fullscreen button on any diagram to study it.
Why we integrate with ServiceNow
Section titled “Why we integrate with ServiceNow”A scan result or a Fides attestation proves what happened technically. It does not satisfy the change-management control an enterprise auditor expects: a recorded change request, a risk assessment, an approver, and a closed-out record tied to the CMDB. SARC bridges that gap automatically — every pipeline run produces a real ServiceNow Change Request, enriched with the evidence, risk- scored, gated on approval, and closed after deploy. The result: the same deployment is both technically attested (Evidence Vault) and process- compliant (ServiceNow), with no manual ticket-raising.
The shape: two directions
Section titled “The shape: two directions”
flowchart TD
subgraph CI["CI pipeline — WRITE path (Basic auth; attest + post-deploy)"]
direction TB
W1["servicenow-cr.sh<br/>POST change_request + ~40 custom fields"]
W2["fides-score.sh<br/>PATCH 5-axis clearance + approval"]
W3["compliance-report / sbom-attach<br/>POST /attachment/file + work_notes"]
W4["servicenow-fides-sync.sh<br/>POST u_fides_artifact / test_result / vulnerability"]
W5["wait-approval.sh<br/>GET approval (poll — qa/prod gate)"]
W6["cr close (post-deploy)<br/>PATCH state=Closed + close_code"]
W1 ~~~ W2 ~~~ W3 ~~~ W4 ~~~ W5 ~~~ W6
end
SNOW[("ServiceNow<br/>change_request · cmdb_ci_* · problem · incident<br/>task_sla · pa_dashboard · u_fides_*")]
subgraph PORTAL["SARC portal — READ path (per-tenant TenantConfig Basic auth)"]
direction TB
R1["/change-requests · /timeline<br/>read CRs · approve / reject"]
R2["/services · /services/[slug]<br/>SLA + CR-conflict banners"]
R3["/problems<br/>regression + deploy correlation"]
R4["/cmdb<br/>CIs + relationship graph"]
R1 ~~~ R2 ~~~ R3 ~~~ R4
end
CI ==>|write| SNOW
SNOW ==>|read| PORTAL
PORTAL -.->|approve / reject · CMDB upsert| SNOW
class W1,W2,W3,W4,W5,W6 write
class R1,R2,R3,R4 read
class SNOW snow
classDef write fill:#2da44e,stroke:#116329,color:#ffffff
classDef read fill:#1f6feb,stroke:#0b3d91,color:#ffffff
classDef snow fill:#d29922,stroke:#8a6500,color:#ffffff
Both directions use the ServiceNow Table API (/api/now/table/...) and
Attachment API (/api/now/attachment/file) over HTTP Basic auth. The
pipeline reads its credentials from CI variables (SERVICENOW_INSTANCE_URL,
SERVICENOW_USERNAME, SERVICENOW_PASSWORD); the portal reads per-tenant
credentials from the TenantConfig table (snowUrl, snowUser, snowPass),
so each tenant points at its own instance.
How the pipeline writes to ServiceNow (technical design)
Section titled “How the pipeline writes to ServiceNow (technical design)”The write path runs in the attest stage (create + enrich + risk) and the post-deploy stage (close), with the approval poll in approve-deploy.
flowchart TD
CREATE["attest · servicenow-cr.sh create<br/>POST change_request (state=New)<br/>custom fields + 5 narratives + assignment refs"]
RISK["attest · fides-score.sh<br/>query Evidence Vault trail -> 5-axis clearance<br/>PATCH u_risk_score · u_risk_assessment · approval"]
ENRICH["attest · enrich<br/>compliance report + SBOM zip (attachments)<br/>+ u_fides_* rows"]
GATE{"auto-approve?<br/>risk <= env threshold<br/>AND Evidence Vault compliant"}
WAIT["approve-deploy · wait-approval.sh<br/>poll approval (30s, 1h timeout)"]
CLOSE["post-deploy · servicenow-cr.sh close<br/>PATCH state=Closed · close_code · duration"]
CREATE --> RISK --> ENRICH --> GATE
GATE -->|"dev: always · qa: score<=5"| AUTO["auto-approved<br/>(fast-path, no poll)"]
GATE -->|"prod: always manual · or non-compliant"| WAIT
AUTO --> CLOSE
WAIT -->|approved| CLOSE
WAIT -->|rejected / timeout| FAIL["pipeline fails<br/>(real gate)"]
class CREATE,ENRICH write
class RISK risk
class GATE,WAIT gate
class AUTO auto
class CLOSE close
class FAIL fail
classDef write fill:#2da44e,stroke:#116329,color:#ffffff
classDef risk fill:#6639ba,stroke:#3b1f7a,color:#ffffff
classDef gate fill:#9a6700,stroke:#5c3d00,color:#ffffff
classDef auto fill:#1f8f6b,stroke:#0d5a42,color:#ffffff
classDef close fill:#1b7c83,stroke:#0f4a4e,color:#ffffff
classDef fail fill:#b62324,stroke:#6e0f10,color:#ffffff
Create (servicenow-cr.sh) POSTs a change_request carrying the full
pipeline context as u_* custom fields — u_target_cloud, u_deploy_env,
u_commit_sha, u_branch, u_services_deployed, u_cluster_namespace,
u_security_scan_url, u_platform (and platform-specific IDs for GitLab /
GitHub / Azure DevOps) — plus the five narrative fields ServiceNow requires
(short description, justification, implementation plan, backout plan, risk &
impact, test plan). Reference fields (assignment_group, assigned_to) are
resolved from names/emails to sys_ids by servicenow-resolve-refs.sh (robust to
renames, retries on transient errors).
Enrich attaches the compliance report (JSON/TXT/optional PDF) and a zipped bundle of all CycloneDX SBOMs to the CR, and posts work notes linking back to the pipeline and the evidence trail.
Close (post-deploy, when: always) moves the CR to Closed with a
close_code derived from the deploy outcome, the deployment duration, and an
audit work note — so the change lifecycle always completes.
The 5-axis risk score and auto-approval
Section titled “The 5-axis risk score and auto-approval”fides-score.sh reads the Evidence Vault trail for the commit and computes a
deployment clearance across five axes, written to the CR:
| Axis | What it evaluates |
|---|---|
| Artifact | Is the pipeline-validation attestation present and compliant? |
| Scope | Environment + cloud + blast radius (dev < qa < prod; internal vs customer-facing) |
| Attestation | Status of all 8 canonical attestations (SAST, secret, dependency, container, IaC, k8s-manifest, SBOM, pipeline-validation) |
| Temporal | Freshness of the attestations |
| Code | Merged security-scanner findings (SARIF + GitLab reports) |
The result lands on the CR as u_risk_score / u_risk_level (Low → Moderate →
High → Critical → HOLD), with the full assessment in u_risk_assessment and the
reasoning in u_risk_evidence_chain. A legacy 0–100 scalar drives the
auto-approval gate:
- dev — always auto-approves (fast iteration).
- qa — auto-approves only if the score is at/under the threshold (default ≤ 5).
- prod — always manual CAB; never auto-approves.
- Hard gate: auto-approval is refused if the Evidence Vault trail is not compliant, even when the score would otherwise pass (defense in depth).
This is the decision that makes “compliant changes ship fast, risky ones get a human” automatic and evidence-driven — see approve-deploy-qa and approve-deploy-prod.
What lands in ServiceNow — and what it’s used for
Section titled “What lands in ServiceNow — and what it’s used for”| Artifact in ServiceNow | What SARC puts there | What it’s used for |
|---|---|---|
change_request + u_* fields | Full per-deploy change record with risk, evidence links, platform metadata | CAB review, change calendar, SOC 2 evidence export, native risk routing |
| Attachments | Compliance report + zipped SBOMs + attestation evidence | One-pane audit evidence on the CR |
u_fides_artifact / u_fides_test_result / u_fides_vulnerability | Evidence rows keyed by commit SHA (trail) | Native ServiceNow reporting on evidence with no Fides login (#306); e.g. “critical CVEs shipped to prod in 30 days” |
cmdb_ci_service + 9 u_* fields | Container image, digest, namespace, Helm release, ArgoCD app, pipeline/commit URLs | CMDB mapping; trace a CR to the running service |
Kubernetes CIs (cmdb_ci_kubernetes_*) | Workloads, services, ingress, (pods planned) | Deployment-impact views in the standard SN UI |
| OpenShift CIs (Build → BuildConfig → ImageStreamTag → Route) | Walked and pushed on Build-complete (#319) | Correlate deployments back to OCP builds + routes for CAB |
Because the evidence lives in native ServiceNow tables, the customer can build their own ServiceNow reports, Performance Analytics dashboards, and CAB workflows on top of SARC’s output without any external lookups.
AI agents inside ServiceNow
Section titled “AI agents inside ServiceNow”The x_sarc_agent_tools scoped app registers three SARC agent recipes as
Now Assist Tools so a ServiceNow AI agent (e.g. “Change Risk Analysis”) can
invoke them from the CR without leaving ServiceNow — each calls
POST {portal}/api/agents/run with a stored Portal Token:
x_sarc.vuln_suggest_fix— propose a dependency bump + open a PR/MR.x_sarc.problem_investigate_fix— investigate a Problem record and propose a fix.x_sarc.right_sizing_apply— apply a right-sizing recommendation.
A read-only MCP server (servicenow_server.py) also exposes ServiceNow +
Evidence Vault data (change requests, analytics, risk-score details, trails) to
MCP clients. Every agent write stays human-gated — propose → approve → execute.
How the SARC portal reads and uses ServiceNow
Section titled “How the SARC portal reads and uses ServiceNow”The portal authenticates per tenant (Basic auth from TenantConfig) and applies
Layer-2 scoping: every read is filtered to the tenant’s allow-listed
cmdb_ci / business-service sys_ids (strict by default, permissive for
legacy instances), so one portal safely serves many tenants on shared instances.
flowchart LR
subgraph IN["ServiceNow data (read)"]
direction TB
D1["change_request<br/>(overlapping windows)"]
D2["task_sla<br/>(14-day trailing)"]
D3["problem<br/>(reopen_count · closed_at)"]
D4["cmdb_ci_* · cmdb_rel_ci"]
end
subgraph DEC["Decisions SARC makes"]
direction TB
C1["CR conflict banner<br/>warn on overlapping change windows"]
C2["SLA compliance pill<br/>compliancePct + week-over-week delta"]
C3["Problem regression flag<br/>+ fixed-by-deploy correlation (±60 min)"]
C4["CR approve / reject<br/>RBAC APPROVER/ADMIN + hash-chained audit"]
C5["CMDB graph + impact view"]
end
D1 --> C1
D1 --> C4
D2 --> C2
D3 --> C3
D4 --> C5
class D1,D2,D3,D4 read
class C1,C2,C3,C4,C5 decision
classDef read fill:#d29922,stroke:#8a6500,color:#ffffff
classDef decision fill:#8957e5,stroke:#512a8f,color:#ffffff
What the operator sees, and the decisions behind it:
/change-requests— the CR list (scoped, with per-CR Evidence Vault clearance); approve / reject is RBAC-gated (APPROVER or ADMIN) and writes a hash-chained audit log entry, flippingstate+approvalin ServiceNow./services/[slug]— a CR-conflict banner (other non-terminal CRs whose change windows overlap this service’s deploy window) and an SLA pill (task_slaover 14 days → compliance % and a week-over-week delta arrow)./problems— a regression flag (reopened within 30 days) and problem-to-deploy correlation (a Problem closed within ±60 min of aDeploymentRecordis tagged “fixed in deploy<sha>”)./cmdb— browse CIs and the relationship graph (relationships fetched in 100-id batches), plus an ADMIN-only CMDB sync that upserts Kubernetes workload CIs via the ServiceNow IRE API./timeline— a live SSE stream that merges ServiceNow CR events (polled every 15s) with GitLab pipelines, Evidence Vault audits, ArgoCD syncs, and internal deploy records, with a REST snapshot fallback.
Security and graceful degradation
Section titled “Security and graceful degradation”- Auth: HTTP Basic over TLS. Pipeline creds from CI variables; portal creds
per-tenant in
TenantConfig(encrypted at rest). No long-lived data in URLs. - No-op when unconfigured: every write script exits 0 cleanly if
SERVICENOW_INSTANCE_URLis unset (local dev, MRs), and most CR jobs areallow_failure: true— a ServiceNow outage never blocks a deploy, because the Evidence Vault remains the source of truth. The approval-poll jobs are the exception (allow_failure: false) — they are real gates. - ACLs: the
u_fides_*custom tables need anitil-scoped read ACL applied on the instance, or the Table API returns 403; the portal’s integration user carries a role that inheritsitil.
Where to go next
Section titled “Where to go next”- Pipelines + integration — the conceptual map and the “How CI talks to ServiceNow” data-flow diagram
- Full pipeline action map — every stage, including where the CR is created, enriched, gated, and closed
- attest stage · approve-deploy-qa · approve-deploy-prod · post-deploy