SCIM 2.0 Provisioning
Arbitex implements the System for Cross-domain Identity Management (SCIM) 2.0 protocol (RFC 7644) for automated user and group lifecycle management from your identity provider. SCIM provisioning keeps your Arbitex users and groups in sync with your IdP directory without manual imports.
For Entra ID-specific setup (Entra ID Enterprise App gallery configuration), see the Entra ID SCIM guide. This guide covers IdP-agnostic setup that applies to Okta, OneLogin, JumpCloud, and any SCIM 2.0-compliant IdP.
What SCIM does
Section titled “What SCIM does”SCIM provisioning automates:
- User lifecycle — create users when they are assigned to the Arbitex app in your IdP, deactivate users when they are removed or deprovisioned
- Group sync — create and maintain Arbitex groups that mirror IdP groups; sync group membership changes
- Attribute updates — propagate display name, email, and external ID changes from the IdP to Arbitex
Without SCIM, users must be manually invited via the Arbitex admin panel, and group membership must be managed separately in both systems.
SCIM base URL
Section titled “SCIM base URL”All SCIM endpoints are under:
https://api.arbitex.ai/scim/v2Schema discovery:
https://api.arbitex.ai/scim/v2/SchemasAuthentication
Section titled “Authentication”Bearer token
Section titled “Bearer token”SCIM endpoints require a Bearer token in the Authorization header:
Authorization: Bearer <scim-token>A missing or invalid token returns 401:
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"], "status": "401", "detail": "SCIM authentication required"}If SCIM provisioning is not configured (no token set), requests return 403:
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"], "status": "403", "detail": "SCIM provisioning is not configured (no bearer token set)"}Per-org token rotation
Section titled “Per-org token rotation”Arbitex supports per-org SCIM tokens, stored as bcrypt hashes. To rotate your org’s SCIM token:
POST /v1/orgs/{org_id}/scim/token/rotateAuthorization: Bearer arb_live_your-api-key-hereResponse:
{ "token": "raw-token-value", "org_id": "8d4b2c1e-0a3f-4e9d-b7c6-1a2b3c4d5e6f", "created_at": "2026-03-11T00:00:00+00:00"}When you rotate, the previous active token is immediately invalidated. Update your IdP SCIM configuration with the new token before or immediately after rotation to avoid a provisioning sync failure.
Supported SCIM resources
Section titled “Supported SCIM resources”| Resource | Endpoints | Description |
|---|---|---|
| Users | /scim/v2/Users | Individual user accounts |
| Groups | /scim/v2/Groups | User groups with optional Arbitex extension attributes |
| Schemas | /scim/v2/Schemas | Schema discovery (read-only) |
User endpoints
Section titled “User endpoints”List users
Section titled “List users”GET /scim/v2/UsersAuthorization: Bearer <scim-token>Query parameters:
| Parameter | Default | Description |
|---|---|---|
startIndex | 1 | 1-based pagination start index |
count | 100 | Maximum results per page (max 1000) |
filter | — | SCIM filter expression (see Filtering) |
Response:
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"], "totalResults": 47, "startIndex": 1, "itemsPerPage": 100, "Resources": [...]}Get a user
Section titled “Get a user”GET /scim/v2/Users/{user_id}Authorization: Bearer <scim-token>Returns a single SCIM User resource. Returns 404 if not found.
Create a user
Section titled “Create a user”POST /scim/v2/UsersAuthorization: Bearer <scim-token>Content-Type: application/json
{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"], "userName": "alice@example.com", "displayName": "Alice Smith", "emails": [ { "value": "alice@example.com", "primary": true } ], "active": true, "externalId": "00u1abcdef1234567890"}Returns 201 with the created SCIM User resource. Returns 409 if userName already exists.
SCIM-provisioned users are created with a randomly generated password — they authenticate via SSO, not local password. SCIM provisioning is designed to work alongside SSO (SAML or OIDC).
Replace a user (PUT)
Section titled “Replace a user (PUT)”PUT /scim/v2/Users/{user_id}Authorization: Bearer <scim-token>Content-Type: application/json
{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"], "userName": "alice@example.com", "displayName": "Alice Smith-Jones", "emails": [ { "value": "alice@example.com", "primary": true } ], "active": true, "externalId": "00u1abcdef1234567890"}Returns 200 with the updated resource. Returns 404 if not found, 409 on uniqueness conflict.
Partially update a user (PATCH)
Section titled “Partially update a user (PATCH)”PATCH /scim/v2/Users/{user_id}Authorization: Bearer <scim-token>Content-Type: application/json
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ { "op": "replace", "path": "active", "value": false } ]}Applies partial updates. Used by IdPs to deactivate a user when they are deprovisioned.
Deactivate a user (DELETE)
Section titled “Deactivate a user (DELETE)”DELETE /scim/v2/Users/{user_id}Authorization: Bearer <scim-token>SCIM DELETE is a soft-delete. Arbitex sets is_active=false on the user record rather than physically deleting it. This preserves audit trail and conversation history. Returns 204 No Content.
Group endpoints
Section titled “Group endpoints”List groups
Section titled “List groups”GET /scim/v2/GroupsAuthorization: Bearer <scim-token>Same pagination and filter parameters as Users.
Get a group
Section titled “Get a group”GET /scim/v2/Groups/{group_id}Authorization: Bearer <scim-token>Returns the SCIM Group resource, including Arbitex extension attributes if present.
Create a group
Section titled “Create a group”POST /scim/v2/GroupsAuthorization: Bearer <scim-token>Content-Type: application/json
{ "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:Group", "urn:arbitex:scim:schemas:extension:Group:2.0" ], "displayName": "Engineering", "externalId": "grp_0001", "members": [ { "value": "user-uuid-1" }, { "value": "user-uuid-2" } ]}Returns 201 with the created SCIM Group resource. Returns 409 if displayName already exists.
Replace a group (PUT)
Section titled “Replace a group (PUT)”Full group replacement, including updating the members list and any Arbitex extension attributes.
Partially update a group (PATCH)
Section titled “Partially update a group (PATCH)”Used by IdPs to add or remove individual members from a group. Operations include add and remove for the members path.
Delete a group
Section titled “Delete a group”DELETE /scim/v2/Groups/{group_id}Authorization: Bearer <scim-token>Deletes the group and all its memberships. Returns 204 No Content.
Attribute mapping
Section titled “Attribute mapping”User attributes
Section titled “User attributes”| SCIM attribute | Arbitex field | Notes |
|---|---|---|
userName | email / username | Used as both email and username in Arbitex |
emails[primary=true].value | email | Preferred email source when present |
displayName | username | Display name |
externalId | (stored for IdP linkage) | Used to correlate with IdP directory objects |
active | is_active | SCIM active=false deactivates the account |
Group attributes
Section titled “Group attributes”| SCIM attribute | Arbitex field | Notes |
|---|---|---|
displayName | name | Group display name |
externalId | external_group_id | IdP group ID for SSO claim mapping |
members[].value | group_memberships | User UUIDs in membership junction table |
Arbitex Group extension
Section titled “Arbitex Group extension”Arbitex supports a custom SCIM schema extension for provisioning group-level policy configuration:
Schema URN: urn:arbitex:scim:schemas:extension:Group:2.0
Extension attributes:
| Attribute | Type | Description |
|---|---|---|
dlpPolicy | string | DLP policy action override: SKIP, BLOCK, CANCEL, or REDACT |
modelAccess | array | List of permitted model identifiers |
complianceBundles | array | Compliance bundle IDs to activate for this group |
quotaTokens | integer | Per-group daily token budget |
These extension attributes allow IdP administrators to configure Arbitex group policies directly from their IdP provisioning interface, without requiring separate configuration in the Arbitex admin panel.
Filtering
Section titled “Filtering”SCIM filter expressions use the format attribute op value. Arbitex supports basic equality filters on key attributes:
Users:
| Filter | Example |
|---|---|
userName eq | filter=userName eq "alice@example.com" |
email eq | filter=email eq "alice@example.com" |
externalId eq | filter=externalId eq "00u1abcdef1234567890" |
Groups:
| Filter | Example |
|---|---|
displayName eq | filter=displayName eq "Engineering" |
externalId eq | filter=externalId eq "grp_0001" |
Unsupported filter expressions return the full unfiltered list (not a 400 error) — the IdP is responsible for any client-side filtering of the result set.
IdP-agnostic setup
Section titled “IdP-agnostic setup”The following steps apply to any SCIM 2.0-compliant identity provider:
-
Generate a SCIM token — Use
POST /v1/orgs/{org_id}/scim/token/rotatewith your admin API key. Copy the returned raw token immediately. -
Configure your IdP — In your IdP’s SCIM provisioning settings, enter:
- SCIM base URL:
https://api.arbitex.ai/scim/v2 - Authentication method: Bearer token
- Bearer token: The raw token from step 1
- SCIM base URL:
-
Map attributes — Configure user attribute mappings per the Attribute mapping table. At minimum, map
userNameto the user’s primary email. -
Test the connection — Most IdPs provide a “Test connection” button that performs a
GET /scim/v2/Users?count=1request. Verify it returns success. -
Enable provisioning — Enable “Create”, “Update”, and “Deactivate” provisioning operations. Most IdPs also support group sync — enable it to synchronize groups and memberships.
-
Initial sync — Trigger a manual full sync to import existing users and groups. Monitor the IdP’s provisioning logs for any errors.
In Okta, add a custom SCIM 2.0 app (no gallery app is required — Arbitex uses the standard SCIM 2.0 protocol). Set the SCIM connector base URL, select Bearer Token authentication, and configure the attribute mappings. Enable both user and group provisioning features.
OneLogin
Section titled “OneLogin”In OneLogin, create a SCIM Provisioner with SAML 2.0 or a custom connector. Enter the base URL and bearer token. Map the SCIM userName field to the user’s email address.
JumpCloud
Section titled “JumpCloud”In JumpCloud, use the Custom SCIM 2.0 integration type. Enter the base URL and bearer token under the “API type” → “SCIM 2.0” option. Enable group push to synchronize JumpCloud user groups as Arbitex groups.
Other SCIM 2.0 providers
Section titled “Other SCIM 2.0 providers”Any IdP that implements RFC 7644 SCIM 2.0 can provision to Arbitex. Configure the base URL as https://api.arbitex.ai/scim/v2 and authenticate with the Bearer token. The standard SCIM User and Group schemas are supported without additional configuration.
Troubleshooting
Section titled “Troubleshooting”Sync failures — user not created
Section titled “Sync failures — user not created”- Token rejected (401) — The SCIM token may have been rotated. Verify the token in your IdP matches the most recently issued token. Rotate and update if uncertain.
- Duplicate userName (409) — A user with the same
userName(email) already exists in Arbitex. If the user was created manually before SCIM was configured, update theirexternalIdto match the IdP’s ID, or delete the duplicate and allow SCIM to re-create. - SCIM not configured (403) — No SCIM token is set for the org. Run
POST /v1/orgs/{org_id}/scim/token/rotateto create one.
Attribute conflicts
Section titled “Attribute conflicts”When a SCIM user update fails due to a uniqueness conflict (409), it means the new userName or email is already taken by another user in the system. This typically occurs when:
- The same email exists under a different
externalId - A user was imported with a typo that was corrected in the IdP
Resolution: identify the conflicting user in Arbitex admin, update or remove the conflict, then trigger a re-sync from the IdP.
Token expiry
Section titled “Token expiry”SCIM tokens do not expire automatically — they remain active until rotated. If provisioning stops working, the likely cause is a token rotation (deliberate or accidental) that was not reflected in the IdP configuration. Re-run POST /v1/orgs/{org_id}/scim/token/rotate and update the IdP immediately.
Group members not syncing
Section titled “Group members not syncing”Some IdPs sync users and groups independently. Ensure:
- Group provisioning is enabled in the IdP (not just user provisioning)
- The group is assigned to the Arbitex app in the IdP
- Member UUIDs in SCIM PATCH operations use the Arbitex user UUIDs returned from
GET /scim/v2/Users, not the IdP’s internal user IDs
Deactivated users still appearing as active
Section titled “Deactivated users still appearing as active”SCIM DELETE sets is_active=false (soft-delete). If a user shows as active after deletion in the IdP:
- Verify the IdP sent a DELETE (or PATCH with
active=false) — check the IdP’s provisioning log - Verify the user’s
is_activefield in Arbitex viaGET /scim/v2/Users/{id} - If the DELETE arrived, the user should be inactive. If not, confirm the SCIM endpoint URL includes the correct user UUID
See also
Section titled “See also”- SSO Configuration — SAML IdP setup and SCIM token management from the admin panel
- User and group management — Manual user invite and group CRUD
- Multi-tenancy architecture — Per-org SCIM token isolation model
- Security Overview — Authentication and access control overview