Identity

On this page

SCIM provisioning

Enterprise identity providers (Okta, Entra ID, OneLogin and others) create, update and deactivate users in your app over SCIM 2.0. A mock identity provider can do the same: it pushes its test users and groups to your app's SCIM endpoint and grades every answer against RFC 7643 and RFC 7644, so you find the mistakes before a customer's IdP does.

SCIM provisioning is included from the Team plan. On the Free plan, setting a target or starting a run answers 402 with "code": "feature_unavailable".

Set up a target

On the IdP's Provisioning tab (owners and admins), enter:

Setting Notes
SCIM base URL For example https://staging.example.com/scim/v2. Requests go to /Users and /Groups below it. It must be reachable from the internet: private, loopback and link-local addresses are refused
Bearer token At least 8 characters, sent as Authorization: Bearer <token>. It is encrypted at rest, never shown again or returned by the API, and redacted from recorded requests and responses

Changing the base URL keeps the token unless you enter a new one, and forgets the remote IDs of the old target.

Requests use Content-Type: application/scim+json and Accept: application/scim+json, application/json, a 10-second timeout and a 1 MB limit on each response. Runs execute in the background, one at a time per IdP, and are kept for 30 days.

Actions

Action Requests
Push all users For each user: POST /Users (expects 201), or PUT /Users/<id> once it was provisioned. On 409, GET /Users?filter=userName eq "…" and adopt the existing user
Push user The same for one user
Update (PATCH) PATCH /Users/<id> with a PatchOp that replaces name, displayName, emails and active
Update (PUT) PUT /Users/<id> with the full representation
Deactivate PATCH /Users/<id> with { "op": "replace", "value": { "active": false } }
Delete DELETE /Users/<id> (expects 204); the remote ID is forgotten
Push groups Pushes users that were not provisioned yet, then for each group POST /Groups or PUT /Groups/<id> with members (the users' remote IDs)
Compliance check The sequence below

Users are sent with the core User schema: userName is the email, externalId the test user's subject, plus name, displayName, emails (primary, work) and active. The remote IDs your app returns are kept per test user (scimId in the users API) and per group name. A run handles up to 500 users and 100 groups.

Compliance check

The compliance check runs an Okta-style sequence with a throwaway scim-check-<random>@example.com user:

  1. Create the user (expects 201).
  2. Get it by ID (expects 200).
  3. Filter by userName eq "…" (expects 200 and a ListResponse with exactly that user).
  4. Create the same user again (expects 409).
  5. PATCH it to active: false (expects 200 with active: false, or 204).
  6. Delete it (expects 204).
  7. Get an unknown ID (expects 404).

Grading

Every step is graded. Must checks decide whether the step passes; should checks are warnings:

Answer Must Should
A resource (create, get, replace, patch) The expected status; Content-Type: application/scim+json; schemas has the core User or Group URN; id is a string; the same id and the echoed userName; meta.resourceType meta.location; meta.created and meta.lastModified; a Location header on 201
A ListResponse 200; the content type; schemas has the ListResponse URN; totalResults is a number; Resources is an array; the filter returns exactly the match startIndex and itemsPerPage
An error (409, 404) The expected status; the content type; schemas has the Error URN; status repeats the HTTP status status is a string; scimType: "uniqueness" on 409
A delete 204 An empty body

A transport error (a timeout, a refused connection, a response over 1 MB) fails the step. Each step shows the request and response, headers and body, with the token redacted, in the run details.

From the API

bash
# Set the target once
curl -X PUT https://app.testlie.com/api/idps/$IDP_ID/scim \
  -H "Authorization: Bearer $TESTLIE_API_KEY" -H "Content-Type: application/json" \
  -d '{ "baseUrl": "https://staging.example.com/scim/v2", "token": "'"$SCIM_TOKEN"'" }'

# Run the compliance check and wait for the result
RUN=$(curl -s -X POST https://app.testlie.com/api/idps/$IDP_ID/scim/runs \
  -H "Authorization: Bearer $TESTLIE_API_KEY" -H "Content-Type: application/json" \
  -d '{ "action": "compliance" }' | jq -r .run.id)
until STATUS=$(curl -s -H "Authorization: Bearer $TESTLIE_API_KEY" \
  https://app.testlie.com/api/idps/$IDP_ID/scim/runs/$RUN | jq -r .run.status) && [ "$STATUS" != queued ] && [ "$STATUS" != running ]; do sleep 2; done
echo "$STATUS"   # passed, failed or error

The API actions are push_all, push_user, update_patch, update_put, deactivate, delete, push_groups and compliance; the per-user ones take a userId. Starting a run while another one of the same IdP is in progress answers 409. The Identity API lists every endpoint and field.

Owners and admins configure targets and start runs; every change and run is recorded in the team's audit log. Members can read the target (without the token) and the runs.