Docs/Administration/Scim Provisioning

SCIM Provisioning

ANTS Platform exposes a SCIM 2.0 endpoint so your identity provider can add people to an organization, set their built-in role, push groups and their members, and remove people when they leave. SCIM manages organization membership and groups. Groups assign roles, including custom and project roles, through group role mappings. SCIM does not manage passwords.

ℹ

SCIM authenticates with an organization API key. Only the Owner role can create one, under Organization Settings → API Keys, and that tab needs the admin-api entitlement. See API Keys and Billing & Plans.

Connect your identity provider

Create an organization API key

Go to Organization Settings → API Keys and create a key. Copy the secret key when it is shown. It is not shown again.

Configure the SCIM app

In your identity provider, set:

SettingValue
SCIM base URLhttps://<your-host>/api/public/scim
AuthenticationHTTP Basic
UsernameThe organization public key (pk-ap-...)
PasswordThe organization secret key (sk-ap-...)
Unique identifieruserName, set to the user's email address

A project API key is refused with 403. Bearer tokens are not accepted.

Test the connection

Run your identity provider's connection test, then assign a pilot user and check that they appear under Organization Settings → Members. To manage groups, turn on group push in your identity provider (in Okta, Push Groups) and push a pilot group.

Endpoints

All paths are relative to https://<your-host>/api/public/scim. The User and Group resources are supported. There are no Bulk or Me endpoints.

Method and pathWhat it does
GET /ServiceProviderConfigCapabilities: PATCH supported; filter supported; bulk, sort, ETag and password change not supported; HTTP Basic authentication.
GET /SchemasThe User and Group schemas.
GET /ResourceTypesTwo resource types, User and Group.
GET /UsersLists the organization's members. Supports filter=userName eq "<email>", startIndex (default 1) and count (default 100).
POST /UsersAdds a user to the organization.
GET /Users/{id}Returns one member.
PUT /Users/{id}Sets active and roles.
PATCH /Users/{id}Sets active only.
DELETE /Users/{id}Removes the user from the organization. Returns 204.
GET /GroupsLists the organization's groups. Supports filter=displayName eq "<name>", startIndex and count.
POST /GroupsCreates a group, with optional members.
GET /Groups/{id}Returns one group and its members.
PATCH /Groups/{id}Adds and removes members, and renames the group.
DELETE /Groups/{id}Deletes the group. Returns 204.

Errors use the SCIM error schema (urn:ietf:params:scim:api:messages:2.0:Error) with detail and status.

Creating users

POST /Users reads these attributes:

AttributeUse
userNameRequired. The user's email address. Stored in lower case.
name.formattedDisplay name. Falls back to displayName.
rolesOptional. The built-in organization role. See below.

Other attributes, including password, emails and active, are ignored. SCIM never sets a password, so users created this way sign in with SSO. If the email already belongs to an ANTS Platform user, that user is added to the organization. If they are already a member, the request returns 409.

json
{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"], "userName": "jane.doe@example.com", "name": { "formatted": "Jane Doe" }, "roles": ["END_USER"] }

The roles attribute

roles is an array. Each entry can be a plain string such as "AUDITOR" or a standard SCIM role object such as {"value": "AUDITOR"}. Only the first value is used. Values are case sensitive:

ValueRole
OWNEROwner
DEPARTMENT_ADMINDepartment Admin
SECURITY_COMPLIANCE_ADMINSecurity & Compliance
ROI_ANALYSTCost Analyst
AUDITORAuditor
MANAGER_VIEWERManager Viewer
END_USEREnd User
NONENone
  • When roles is missing or empty, the member gets None: no organization access until someone grants a project role.
  • roles sets built-in organization roles only. To assign custom roles or project roles from your identity provider, push groups and map them to roles. See Group role mappings.
  • When a group role mapping applies to a member, the mapped role takes precedence over roles.
⚠

PUT /Users/{id} with "active": true always sets the role from roles. If you send a PUT without roles, the member's organization role becomes None. Map a role in your identity provider for every assigned user.

Groups

A SCIM group belongs to one organization. It has a displayName and a list of members, each referencing a user by the id that /Users returned. Push the users before the groups that contain them.

json
{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"], "displayName": "AI-Security", "members": [{ "value": "<user id>" }] }

PATCH /Groups/{id} accepts the standard add, remove and replace operations on members, and replace on displayName:

json
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ { "op": "add", "path": "members", "value": [{ "value": "<user id>" }] }, { "op": "remove", "path": "members[value eq \"<user id>\"]" } ] }

A group on its own grants no access. Map it to a built-in or custom role, at organization or project scope, under group role mappings. Every membership change pushed through SCIM applies the mappings to the members it touches straight away, so the role follows the group without anyone editing it in ANTS Platform. When a group is deleted, its former members lose the roles that came from it, following the mapping rules.

Deactivating and removing users

Deactivate with PATCH:

json
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [{ "op": "replace", "value": { "active": false } }] }

PATCH accepts only op set to lower case replace with a boolean active inside value. Other forms, such as "path": "active", return 400. You can also send PUT with "active": false, or DELETE.

Deactivation and DELETE both:

  • Remove the organization membership, including any custom role.
  • Remove every project membership the user had in that organization.
  • End every open console session the person has. Their next request from any signed-in browser is refused and they are signed out.
  • Revoke the Budget AI keys issued to or collected by the person in that organization, and cancel their pending key collection links. Requests with those keys are refused.
  • Keep the user account, so the person keeps access to any other organization they belong to.

PATCH or PUT with "active": true adds the membership back. PATCH re-adds the user with the None role.

ℹ

SCIM changes are not written to Audit Logs.

Okta access reconciliation (self-hosted)

Self-hosted deployments that use Okta can also run a scheduled reconciliation job. It compares organization members with the active members of chosen Okta groups and removes people who are no longer in them. It is configured with environment variables on the deployment, not in the product, and is off by default.

VariableDefaultMeaning
AUTH_OKTA_RECONCILIATION_ENABLEDfalseTurns the job on.
AUTH_OKTA_API_TOKEN, AUTH_OKTA_ISSUERnoneOkta API token and Okta tenant.
AUTH_OKTA_RECONCILIATION_GROUPSnoneOkta group names or patterns that define who should have access.
AUTH_OKTA_RECONCILIATION_ORG_IDSnoneOrganizations to reconcile.
AUTH_DOMAINS_WITH_SSO_ENFORCEMENTnoneOnly members with these email domains are checked.
AUTH_OKTA_RECONCILIATION_MODEreportreport records drift only. enforce removes access.
AUTH_OKTA_RECONCILIATION_MAX_REMOVALS25The whole run stops if it would remove more people than this.
AUTH_OKTA_RECONCILIATION_MAX_REMOVAL_PERCENT20An organization is skipped if it would lose a larger share of members.
AUTH_OKTA_RECONCILIATION_CRON30 20 * * *Schedule, in UTC.

How it behaves:

  • Suspended and deprovisioned Okta users count as gone. Instance administrators are never removed.
  • The run stops without changes if Okta returns an error, a partial list, no matching groups or no members.
  • An organization is skipped if the removals would leave it without anyone who can manage members.
  • In enforce mode it removes the organization membership and project memberships, and the person is signed out on their next request.
  • It never adds members or changes roles.
  • Every run writes to Audit Logs: okta_reconciliation.drift_detected in report mode, membership.deprovisioned.okta_reconciliation for each removal (with the previous role and project memberships), and okta_reconciliation.aborted when a safety check stops the run.

Next steps

© 2026 ANTS Platform, Inc.Docs v1.0 · Last updated June 2026