Skip to main content

SCIM Provisioning (System for Cross‑domain Identity Management)

SCIM is an open standard for automating user and group provisioning between identity providers (IdPs) and service providers (SPs). With SCIM, your IdP can create, update, and deprovision users and groups in this app automatically.

Base URL

All SCIM endpoints are served under /scim/v2.

  • Example: https://your-domain.example.com/scim/v2/Users

Authentication

All SCIM endpoints require an Authorization header. We support a static bearer token.

  • Header: Authorization: Bearer <AUTH_SECRET>
  • The token is validated against the server environment variable AUTH_SECRET.
  • If you prefer to omit the Bearer prefix, sending the raw token in Authorization is also accepted.
  • On failure, endpoints return a SCIM‑formatted error with 401 and WWW-Authenticate: Bearer.

To rotate the token, update AUTH_SECRET in your deployment environment and redeploy.

Supported Resources

Service Provider Discovery

  • GET /scim/v2/ServiceProviderConfig

    • Returns supported SCIM features (PATCH supported, FILTER supported, BULK not supported, etc.) and advertised auth schemes.
  • GET /scim/v2/ResourceTypes

    • Lists resource types supported by this service: User and Group.
  • GET /scim/v2/Schemas

    • Returns the SCIM schemas for User and Group used by the service.

Users

  • GET /scim/v2/Users

    • Query params: startIndex (default 1), count (default 100), filter.
    • Supported filter: userName eq "<email>" and userName sw "<prefix>".
    • Returns SCIM ListResponse of Users.
  • POST /scim/v2/Users

    • Creates a user. Extracts emails[0].value (email) and name.formatted or displayName (fallback to givenName + familyName or userName).
    • Response: 201 Created with SCIM User.
  • GET /scim/v2/Users/{id}

    • Fetches a specific user by id. The implementation attempts lookup by email and by id.
  • PATCH /scim/v2/Users/{id}

    • Supports replace operations for name.formatted, displayName, userName, and emails[type eq "work"].value.
    • Also accepts direct payloads with name.formatted/displayName and userName/emails[0].value if not using SCIM Operations.
  • DELETE /scim/v2/Users/{id}

    • Deletes a user. Returns 204 No Content on success.

Groups

  • GET /scim/v2/Groups

    • Query params: startIndex, count, filter.
    • Supported filter: displayName eq "<name>" and displayName sw "<prefix>".
    • Returns SCIM ListResponse of Groups with members.
  • POST /scim/v2/Groups

    • Creates a group with displayName. If members are provided, it will set user_ids via a follow‑up call.
    • Response: 201 Created with SCIM Group.
  • GET /scim/v2/Groups/{id}

    • Fetches a specific group.
  • PATCH /scim/v2/Groups/{id}

    • Supports replace on displayName and full members replacement.
    • Supports add and remove on members including path expressions members[value eq "<userId>"].
  • DELETE /scim/v2/Groups/{id}

    • Deletes a group. Returns 204 No Content on success.

Request and Response Examples

Below are minimal examples tailored to what the service accepts and returns.

Auth header example

curl -s -H "Authorization: Bearer $AUTH_SECRET" https://your-domain.example.com/scim/v2/ServiceProviderConfig

Create User

Request:

{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "[email protected]",
"name": { "formatted": "Jane Doe", "givenName": "Jane", "familyName": "Doe" },
"displayName": "Jane Doe",
"emails": [{ "value": "[email protected]", "type": "work", "primary": true }],
"active": true
}

Response (201):

{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "<user-id>",
"externalId": "<user-id>",
"userName": "[email protected]",
"name": { "formatted": "Jane Doe", "givenName": "Jane", "familyName": "Doe" },
"displayName": "Jane Doe",
"emails": [{ "value": "[email protected]", "type": "work", "primary": true }],
"active": true,
"meta": {
"resourceType": "User",
"created": "<iso>",
"lastModified": "<iso>",
"location": "https://your-domain.example.com/scim/v2/Users/<user-id>"
}
}

Filter Users by userName

curl -s \
-H "Authorization: Bearer $AUTH_SECRET" \
"https://your-domain.example.com/scim/v2/Users?filter=userName%20eq%20%5C"[email protected]%5C""

Patch User email

{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{ "op": "replace", "path": "emails[type eq \"work\"].value", "value": "[email protected]" }
]
}

Create Group with members

Request:

{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"displayName": "Developers",
"members": [
{ "value": "<user-id-1>" },
{ "value": "<user-id-2>" }
]
}

Patch Group members (add)

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

Error format

Errors follow SCIM Error schema:

{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
"detail": "<message>",
"status": "<http-status-as-string>"
}

Notes and Limitations

  • Bulk operations are not supported.
  • Sorting is not supported; filtering is limited to the expressions shown above.
  • active is accepted but not persisted in the underlying user model.
  • Group membership updates are performed via an internal mapping and reflected in the SCIM members property.

Mapping Overview

  • User id and externalId map to the internal user id; userName and emails[0].value map to the internal email.
  • Group displayName maps to internal name; members[].value maps to internal user_ids.