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
Bearerprefix, sending the raw token inAuthorizationis also accepted. - On failure, endpoints return a SCIM‑formatted error with
401andWWW-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:
UserandGroup.
- Lists resource types supported by this service:
-
GET /scim/v2/Schemas- Returns the SCIM schemas for
UserandGroupused by the service.
- Returns the SCIM schemas for
Users
-
GET /scim/v2/Users- Query params:
startIndex(default1),count(default100),filter. - Supported filter:
userName eq "<email>"anduserName sw "<prefix>". - Returns SCIM ListResponse of Users.
- Query params:
-
POST /scim/v2/Users- Creates a user. Extracts
emails[0].value(email) andname.formattedordisplayName(fallback togivenName + familyNameoruserName). - Response:
201 Createdwith SCIM User.
- Creates a user. Extracts
-
GET /scim/v2/Users/{id}- Fetches a specific user by
id. The implementation attempts lookup by email and by id.
- Fetches a specific user by
-
PATCH /scim/v2/Users/{id}- Supports
replaceoperations forname.formatted,displayName,userName, andemails[type eq "work"].value. - Also accepts direct payloads with
name.formatted/displayNameanduserName/emails[0].valueif not using SCIMOperations.
- Supports
-
DELETE /scim/v2/Users/{id}- Deletes a user. Returns
204 No Contenton success.
- Deletes a user. Returns
Groups
-
GET /scim/v2/Groups- Query params:
startIndex,count,filter. - Supported filter:
displayName eq "<name>"anddisplayName sw "<prefix>". - Returns SCIM ListResponse of Groups with
members.
- Query params:
-
POST /scim/v2/Groups- Creates a group with
displayName. Ifmembersare provided, it will setuser_idsvia a follow‑up call. - Response:
201 Createdwith SCIM Group.
- Creates a group with
-
GET /scim/v2/Groups/{id}- Fetches a specific group.
-
PATCH /scim/v2/Groups/{id}- Supports
replaceondisplayNameand fullmembersreplacement. - Supports
addandremoveonmembersincluding path expressionsmembers[value eq "<userId>"].
- Supports
-
DELETE /scim/v2/Groups/{id}- Deletes a group. Returns
204 No Contenton success.
- Deletes a group. Returns
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.
activeis accepted but not persisted in the underlying user model.- Group membership updates are performed via an internal mapping and reflected in the SCIM
membersproperty.
Mapping Overview
- User
idandexternalIdmap to the internal user id;userNameandemails[0].valuemap to the internal email. - Group
displayNamemaps to internalname;members[].valuemaps to internaluser_ids.