Back to Compendiums

SCIM 2.0 open standard

The Protocol for automated user provisioning across apps, its specifications and implementation considerations at a glance.

by matsjfunke

SCIM (System for Cross-domain Identity Management) allows organizations to have a single source of truth and management for user and group data across different applications / services.

All that the SCIM standard does is define an API for handling users and groups.

The following will outline what is needed to build a SCIM API server (application / SaaS service that exposes SCIM endpoints and receives requests), to be able to integrate with a SCIM client (application using SCIM to manage users and groups).

Authentication

Authentication in SCIM is performed using a bearer token (API key), which is generated by the SCIM client (such as your identity provider: Okta, Azure AD, etc.).

An administrator typically copies this token from the client and manually enters it into your application, where it should be securely stored for authenticating incoming SCIM requests.

  • Implementation consideration you should encourage your users to rotate the token regularly, as it is a good practice to do so. It goes without saying that communication should happen via HTTPS.
http
1Authorization: Bearer YOUR_SCIM_TOKEN
2

Resource Schemas

SCIM defines standard schemas for resources like User and Group. Each schema specifies required and optional attributes.

  • When building a SCIM server, your API should at least support the core attributes for these resources, although you can extend the schemas to support more attributes.

User Resource Schema

AttributeRequiredTypeDescription
idYesStringUnique identifier (server-side)
userNameYesStringUnique username (login)
nameNoComplexFull name (familyName, givenName)
displayNameNoStringDisplay name
emailsNoArrayEmail addresses
activeNoBooleanUser's active status
groupsNoArrayGroups the user belongs to
metaNoComplexResource metadata

Group Resource Schema

AttributeRequiredTypeDescription
idYesStringUnique identifier (server-side)
displayNameYesStringDisplay name
membersNoArrayMembers of the group
metaNoComplexResource metadata

Request Format

All mutating SCIM requests (POST, PUT, PATCH) require a Content-Type: application/scim+json header along with schemas attribute which defines the schema of the request body.

http
1POST /scim/v2/Users
2Content-Type: application/scim+json
3Authorization: Bearer YOUR_SCIM_TOKEN
4
5{
6    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
7    "userName": "john.doe@company.com",
8    "displayName": "John Doe",
9    "active": true
10}
11

For partail updates there are Operations to modify attributes through PATCH requests, allowing granular updates without replacing entire resources.

Operation Types

OperationDescriptionUsage
addAdd a new attribute value or add a value to a multi-valued attributeCreating new attributes or adding to existing arrays
removeRemove an attribute or specific value from a multi-valued attributeDeleting attributes or removing specific values
replaceReplace an attribute value entirelyUpdating existing attributes with new values
json
1{
2  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
3  "Operations": [
4    {
5      "op": "replace",
6      "path": "displayName",
7      "value": "New Name"
8    },
9    {
10      "op": "add",
11      "path": "emails",
12      "value": [
13        {
14          "type": "work",
15          "value": "john.doe@company.com",
16          "primary": true
17        }
18      ]
19    },
20    {
21      "op": "remove",
22      "path": "emails[type eq \"personal\"]"
23    }
24  ]
25}
26
  • Implementation consideration You will need to handle a varitey of body types, depending on the application you are integrating with. SCIM supports filtering, sorting, and pagination so will need to handle this in your application (like in the remove operation in the example above).

SCIM API Endpoints

These are the most common REST endpoints for SCIM.

User Endpoints

MethodEndpointPurposeResponseError Cases
GET/api/scim/v2/UsersList users200 OK (paginated)400 (invalid filter)
POST/api/scim/v2/UsersCreate/ add user201 Created409 (conflict)
GET/api/scim/v2/Users/{id}Get user by ID200 OK404 (not found)
PUT/api/scim/v2/Users/{id}Replace user (full update)200 OK404 (not found)
PATCH/api/scim/v2/Users/{id}Update user (partial update)200 OK404 (not found)
DELETE/api/scim/v2/Users/{id}Delete user204 No Content404 (not found)

Group Endpoints

MethodEndpointPurposeResponseError Cases
GET/api/scim/v2/GroupsList groups200 OK (paginated)400 (invalid filter)
POST/api/scim/v2/GroupsCreate / add group201 Created409 (conflict)
GET/api/scim/v2/Groups/{id}Get group by ID200 OK404 (not found)
PUT/api/scim/v2/Groups/{id}Replace group (full update)200 OK404 (not found)
PATCH/api/scim/v2/Groups/{id}Update group (partial update)200 OK404 (not found)
DELETE/api/scim/v2/Groups/{id}Delete group204 No Content404 (not found)

Error Cases

  • 401 Unauthorized - Missing authentication token or invalid token
  • 403 Forbidden - Valid token but insufficient permissions
  • 422 Unprocessable Entity - Valid syntax but semantic errors
  • 429 Too Many Requests - Rate limiting
  • 500 Internal Server Error - Server-side errors

Considerations

One thing to keep in mind when implementing a SCIM server is that you should not return errors for unsupported attributes or operations, as the SCIM specification expects you to ignore unsupported attributes or operations, rather than returning errors. Specifically, if a request contains attributes that your implementation does not support, you should not fail the whole request. Instead, you should process the supported parts and respond with a success status (such as 200 OK), returning the current state of the resource (which will not include the unsupported attributes)

Another important consideration you have to make is what attributes / operations you want to support. As SCIM could interfere with existing user management.

Discovery: SCIM Service Provider Configuration endpoint (/ServiceProviderConfig) or the /Schemas and /ResourceTypes endpoints. These are part of the SCIM specification and help clients discover what the server supports (e.g., supported features, schema extensions, etc.).