Skip to content

Connectors ​

Connectors link Axiom Control to the systems your organisation already uses to resolve approvers, take decisions, grant privileged access and keep evidence. Each connector declares the operations it supports; Control only calls declared operations, and the console shows the declaration so you can see exactly what a connector claims to verify.

Each catalog entry also states its availability: implemented or declared. Only ServiceNow is implemented (request, webhook and server-to-server readback). Every other type is declared: the catalog lists the operations it is planned to support, and the console marks it "Planned, not yet available". Routing an approval to a declared-only connector fails delivery with "… is in the connector catalogue but not implemented yet; use ServiceNow or the built-in approval page".

Developer preview status

Every connector has a simulated mode that exercises the same request, webhook and server-to-server readback paths against an in-platform stand-in. None is qualified against a real customer tenant. Declared only, today: Microsoft Entra ID Governance, Okta, SailPoint, Saviynt, CyberArk, BeyondTrust, Delinea, Slack and Teams.

Catalog ​

GET /v1/connector-catalog returns every descriptor.

ConnectorAvailabilityCategoryDeclared operationsBoundary (what its evidence does not prove)
ServiceNowimplementedworkflowrequest_decision, verify_native_status, export_evidenceA webhook wakes Control; a server-to-server read verifies the approver, action binding, decision and deadline.
Microsoft Entra ID Governance / Agent IDdeclaredidentityresolve_approvers, retrieve_provisioning_stateAn access package assignment supports standing eligibility. The individual business transaction still needs its applicable approval.
Okta Cross App Accessdeclaredidentityresolve_approvers, retrieve_provisioning_stateReuses an agent-to-app connection and on-behalf-of flow. Business constraints are added at the receiver.
SailPoint Identity Security Clouddeclaredigaresolve_approvers, request_decision, retrieve_provisioning_stateApproval and successful provisioning are separate events.
Saviynt Enterprise Identity Clouddeclaredigarequest_decision, verify_native_status, export_evidenceCorrelates a governed identity, access request, approval and processing history. Validate service-account mapping per tenant.
CyberArk Central Credential Providerdeclaredpamopen_privileged_accessCredential retrieval happens inside a customer-side executor. It proves neither just-in-time access, revocation nor session termination.
BeyondTrust Password Safedeclaredpamopen_privileged_access, close_privileged_access, verify_native_statusPassword rotation, check-in and session termination are tracked independently.
Delinea Secret Serverdeclaredpamrequest_decision, open_privileged_access, verify_native_statusTarget-specific credentials stay inside the customer executor and out of model inputs.
SlackdeclarednotificationnotifyNotifies an eligible person. A click opens the authenticated approval page; Slack does not record the decision.
Microsoft TeamsdeclarednotificationnotifyNotifies an eligible person. A click opens the authenticated approval page; Teams does not record the decision.

Where an identity or IGA product only proves entitlement, keep a separate transaction approval: an assignment is standing eligibility, not approval of this refund.

Manage connectors ​

Console: Connectors at /control/orgs/:oid/connectors. You need connector.write (org_admin or security_admin).

CallBody
POST /v1/orgs/{oid}/connectors{ type, name, mode: "simulated"|"live", config, secret_ref? }
PATCH /v1/connectors/{id}any of name, mode, config, secret_ref, status: "active"|"disabled"
DELETE /v1/connectors/{id}disables it (status: "disabled") and returns it
POST /v1/connectors/{id}/healthruns a health check: { ok, detail, checked_at }
GET /v1/connectors/{id}/simulated-requestsrequests held by a simulated connector
POST /v1/connectors/{id}/simulateact as the native approver (simulated mode only)

Rules for configuration:

  • Fields the catalog marks secret (passwords, client secrets, keys, webhook URLs) must be given as a secret reference (secret_ref, e.g. env:SERVICENOW_PASSWORD), never in config. The platform resolves the reference (Worker secret on Cloudflare, Secret Manager on GCP).
  • live mode requires every required field.
  • The connector view shows has_secret instead of the reference, and its webhook_url.

Route approvals to a connector by setting approval.connector_id in a policy rule. A disabled connector fails delivery, which retries and then shows as failed (see Failure modes).

ServiceNow ​

ServiceNow is the first external approval target. The model is webhook wakes, readback decides: the body of a webhook is never trusted for the decision.

Live setup ​

  1. Create an integration user with access to the request table and sysapproval_approver.

  2. Create (or choose) a request table that has two custom fields, u_axiom_action_id and u_axiom_digest, and build your approval flow on it (for example with the Workflow Studio "Ask for approval" action).

  3. Create the connector:

    http
    POST /v1/orgs/{oid}/connectors
    content-type: application/json
    
    {
      "type": "servicenow",
      "name": "ServiceNow finance approvals",
      "mode": "live",
      "config": { "instance_url": "https://acme.service-now.com", "table": "u_axiom_request", "username": "axiom.integration" },
      "secret_ref": "env:SERVICENOW_PASSWORD"
    }
  4. In ServiceNow, add a business rule or flow step that calls the connector's webhook_url (POST /v1/connectors/{id}/webhook) when an approval on the record changes, with { "native_ref": "<the record sys_id>" } (or { "correlation_id": "…" }).

  5. Reference the connector from a policy rule: "approval": { "approver_role": "finance_approver", …, "connector_id": "con_…" }.

What happens ​

  1. Request. Axiom creates a record in your table through the Table API with short_description (the summary), a description listing tenant, agent, resource, every approver-visible field, the Axiom action ID, the request digest and the deadline, plus correlation_id, u_axiom_action_id and u_axiom_digest. The record's sys_id becomes the approval's native reference. Retries reuse the same correlation ID.
  2. Decision. Your approver decides in ServiceNow as usual.
  3. Webhook. ServiceNow calls the webhook. Axiom queues a readback for matching pending approvals and answers 202 { accepted }. Replaying a webhook only causes another readback.
  4. Readback. Axiom reads sysapproval_approver rows for the record (state, approver user name and name) and reads u_axiom_digest back from your record. Each approved or rejected row is applied as a decision by servicenow:<user_name>, only if the digest matches the request and the deadline has not passed. A replayed webhook or restored backup cannot count the same approver twice.

Why the webhook is unauthenticated ​

POST /v1/connectors/{id}/webhook takes no credential, by design. Its body is never trusted: it only names which pending approval to look at (native_ref or correlation_id), and Axiom then reads the decision, approver and digest from ServiceNow itself with the connector's own credentials. A forged or replayed call can at most cause an extra readback, which finds nothing new. To bound that load the endpoint is rate limited to 60 calls per minute per connector; beyond that it answers 429 rate_limited with retry_after_seconds: 60. Keep the webhook_url private anyway.

While the approval is waiting, decisions can only be made in ServiceNow: the Axiom approval page shows the request but refuses a decision on a connector-routed approval.

If ServiceNow cannot be reached during readback, the action shows progress decision_readback_unavailable and the readback retries every 60 seconds while the approval is pending.

Eligibility of the ServiceNow approver is the connector's claim, recorded with the native reference; Axiom does not map ServiceNow users to Axiom tenant roles.

Try it in simulated mode ​

  1. Create the connector with "mode": "simulated" (no config needed).

  2. Submit an action that a rule routes to it. The simulated record appears under GET /v1/connectors/{id}/simulated-requests (native reference SIM-REQ-…, digest, state, approval and action IDs, deadline).

  3. Act as the ServiceNow approver:

    http
    POST /v1/connectors/{id}/simulate
    content-type: application/json
    
    { "native_ref": "SIM-REQ-1A2B3C4D", "decision": "approved", "approver_name": "Dana Finance", "approver_id": "dana.finance" }

    This changes only the simulated native record, then fires the connector webhook, so the decision reaches Axiom through the same readback path a live instance uses.

Developer preview. Contract version 2026-11-14.