SCIM 2.0 provisioning

RFC 7643 + RFC 7644 implementation. IdPs (Okta, Entra, JumpCloud, OneLogin) provision users into AxisSynapse via these endpoints with a per-tenant bearer token.

Base URL + auth

curl
https://app.axissynapse.com/api/scim/v2

Authorize each request with Authorization: Bearer scim_…. Mint a token at /settings → Identity & SSO → SCIM 2.0 provisioning tokens. Tokens are bcrypt-hashed at rest, shown ONCE.

Capability discovery

Every IdP probes this first:

curl
curl https://app.axissynapse.com/api/scim/v2/ServiceProviderConfig

What we advertise:

  • PATCH supported: yes
  • Filter supported: yes (maxResults 200)
  • Bulk supported: no
  • Sort supported: no
  • Etag supported: no
  • Change-password supported: no
  • Auth scheme: OAuth Bearer Token

Filter language (RFC 7644 §3.4.2.2)

Comparison operators:

OpMeaningExample
eqequaluserName eq "alice@axis.com"
nenot equalstatus ne "DISABLED"
cocontainsname.familyName co "smith"
swstarts withname.givenName sw "Al"
ewends withuserName ew "@axis.com"
gt / ge / lt / leorderinglastLoginAt gt "2026-01-01T00:00:00Z"
prpresence (no value)phoneNumbers pr

Logical: and, or, not + parens. Whole-word keyword matching: an attribute named andrew won't be mis-parsed as and.

curl
curl 'https://app.axissynapse.com/api/scim/v2/Users?filter=active%20eq%20true%20and%20userName%20sw%20%22a%22' \
  -H "Authorization: Bearer $SCIM_TOKEN" \
  -H "Accept: application/scim+json"

PATCH (RFC 7644 §3.5.2)

add / replace / remove on top-level + dotted paths + filter sub-paths:

javascript
{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    { "op": "replace", "path": "active", "value": false },
    { "op": "replace", "path": "name.givenName", "value": "Bob" },
    { "op": "replace", "path": "emails[type eq \"work\"].value", "value": "new@axis.com" },
    { "op": "remove",  "path": "displayName" }
  ]
}

Idempotency

POST /Users with a userName that already exists for the tenant returns 200 with the existing resource (rather than 409). This matches what Okta + Entra retry-loops expect. Strict-RFC 409 is available on request.