How to create, read, update and delete (CRUD) users with the help of the System for Cross-domain Identity Management (SCIM).

Managing Users With SCIM

On this page

System for Cross-domain Identity Management (SCIM) is a REST-based protocol used to perform user management actions across multiple IT systems or domains. This article will cover the most common actions performed with SCIM: Create, Read, Update and Delete (CRUD). General details on SCIM and its use is outlined in User Provisioning With SCIM.

Although this article contains examples of user resources, the same concepts could apply to other SCIM resources as well.

Curity configuration

The User management with SCIM article outlines how to configure the Curity Identity Server to enable the SCIM service.

Schema

SCIM defines a minimum attribute-based core schema. Each attribute is defined by its type, mutability, cardinality, and returnability. It is up to the recipient of the SCIM request to validate the request against the appropriate schema. For example, a SCIM server receiving a request to modify an existing user would validate that request against the mutability schema for a user object. The SCIM specification provides a minimal schema for users, and the specification also provides details on how to extend the schema as needed.

Attributes

A SCIM Resource is defined by a collection of attributes typically organized by resource type, such as User. The attributes are defined by the schemas discussed above. They can also be defined by more than one schema, such as when a core user schema is extended to create a custom enterprise schema.

Attributes are case insensitive and are typically camel-cased (e.g., userName).

The following attribute data types are supported:

  • String
  • Boolean
  • Decimal
  • Integer
  • DateTime
  • Binary
  • Reference
  • Complex

The SCIM Protocol

The SCIM Core Schema defines the attributes, resources, and overall schema. The SCIM Protocol specification defines the protocol and specification of CRUD actions. Let's explore these CRUD actions, one by one.

Create

In SCIM, a user is created by submitting a POST request to the SCIM endpoint. Below is a simple request body that will create a user with a few attributes. Note that this request defines which schema will be used for the resource that is to be created. The schema definition is mandatory.

http
123456789101112131415161718
POST /um/admin/Users HTTP/1.1
Host: idsvr.example.com
Accept: application/scim+json
Authorization: Bearer ec2979e4-f766-4c79-85f9-58f6c72e224f
Content-Type: application/scim+json
 
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"userName": "bob",
"emails": [
{
"value": "bob@example.com",
"primary": true
}
]
}

The response will provide additional information on the resource created. Note here that the server generates an id. This id is unique to the resource and will be used later in the article to showcase how to list information for a specific user.

json
1234567891011121314151617181920
{
"active": false,
"userName": "bob",
"emails": [
{
"value": "bob@example.com",
"primary": true
}
],
"meta": {
"resourceType": "User",
"created": "2021-03-03T17:39:59Z",
"lastModified": "2021-03-03T17:39:59Z",
"location": "https://idsvr.example.com/um/admin/Users/VVNFUjphNGMyZjEzNGY4NjE0MmFhYTkzYzY4ZGEwNmE5MjRiZQ"
},
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"id": "VVNFUjphNGMyZjEzNGY4NjE0MmFhYTkzYzY4ZGEwNmE5MjRiZQ"
}

Read

There are several ways to read resources with SCIM.

List All Resources

You can retrieve a list of all resources by making a simple GET request to the Users endpoint.

http
12344
GET /um/admin/Users HTTP/1.1
Host: idsvr.example.com
Accept: application/scim+json
Authorization: Bearer ec2979e4-f766-4c79-85f9-58f6c72e224f

This request will return a list of users with their attributes along with some metadata. Note that the example response below is truncated for readability. Each object in the Resources array will match what's represented when a specific resource is retrieved, as discussed in the next section.

json
123456789
{
"totalResults": 389,
"startIndex": 1,
"itemsPerPage": 50,
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:ListResponse"
],
"Resources": [...]
}

Get a Specific Resource

To retrieve a specific resource, the id of a user can be appended to the path of the above request.

http
12344
GET /um/admin/Users/VVNFUjo4MjUzZTljN2FkMGY0ZDJjOWFiNGRkMTAxYmExN2E0OA HTTP/1.1
Host: idsvr.example.com
Accept: application/scim+json
Authorization: Bearer ec2979e4-f766-4c79-85f9-58f6c72e224f

This returns all of the attributes defining that specific user. Below is an example of a user and the data in the Resources array mentioned above.

json
1234567891011121314151617181920212223242526272829303132
{
"agreeToTerms": "on",
"active": true,
"userName": "alice",
"phoneNumbers": [
{
"value": "5551231234",
"primary": true
}
],
"emails": [
{
"value": "alice@example.com",
"primary": true
}
],
"urn:se:curity:scim:2.0:Devices": [],
"meta": {
"resourceType": "User",
"created": "2021-02-22T22:32:32Z",
"lastModified": "2021-02-22T22:32:32Z",
"location": "https://idsvr.example.com/um/admin/Users/VVNFUjo4MjUzZTljN2FkMGY0ZDJjOWFiNGRkMTAxYmExN2E0OA"
},
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"name": {
"givenName": "alice",
"familyName": "anderson"
},
"id": "VVNFUjo4MjUzZTljN2FkMGY0ZDJjOWFiNGRkMTAxYmExN2E0OA"
}

Searching for Users

If the user's ID is unknown, an alternative approach is to search for a resource. This can be achieved with either a GET or POST request that defines a search criteria.

An example GET request that filters the search based on the userName would look like this:

http
12344
GET /um/admin/Users?filter=userName+eq+\"bob\" HTTP/1.1
Host: idsvr.example.com
Accept: application/scim+json
Authorization: Bearer ec2979e4-f766-4c79-85f9-58f6c72e224f

Different operators can be used in the search filter. The example above uses eq, short for equals. A full list of supported operators can be found in section 3.4.2.2 of the SCIM protocol specification.

If sensitive data is used in a query, it is also possible to POST a search request to the .search endpoint.

http
123456789101111
POST /um/admin/Users/.search HTTP/1.1
Host: idsvr.example.com
Accept: application/scim+json
Authorization: Bearer ec2979e4-f766-4c79-85f9-58f6c72e224f
Content-Type: application/scim+json
 
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:SearchRequest"],
"filter": "userName eq \"bob\"",
"attributes" : ["userName", "emails.value"]
}

In this search query, attributes to be looked up are also added in addition to the actual search filter. This is helpful when working with large resources where only specific attributes are relevant to the search. Below, only the userName and emails.value attributes are returned in addition to the standard id and schemas attributes.

json
1234567891011121314151617181920212222
{
"totalResults": 1,
"startIndex": 1,
"itemsPerPage": 50,
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:ListResponse"
],
"Resources": [
{
"id": "VVNFUjphNGMyZjEzNGY4NjE0MmFhYTkzYzY4ZGEwNmE5MjRiZQ",
"userName": "bob",
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"emails": [
{
"value": "bob@example.com"
}
]
}
]
}

Update

Updating a SCIM resource can be achieved using the PATCH or PUT methods.

PATCH

The PATCH method can add, remove or replace attributes in a resource. The attributes affected and the action (op) is sent in a PATCH request together with the PatchOp schema and the path that defines the target of the attributes to update.

In this case, the previously created user (bob) was generated with a basic set of attributes. The below example shows how the user can be updated with a set of additional attributes added using the PATCH method.

http
12345678910111213141516171819202122232424
PATCH /um/admin/Users/VVNFUjpjYzVjNWQzYWE3MzQ0ZmViYjhkZThlZTA5MzJjMzJjNg HTTP/1.1
Host: idsvr.example.com
Accept: application/scim+json
Authorization: Bearer ec2979e4-f766-4c79-85f9-58f6c72e224f
Content-Type: application/scim+json
 
{
"schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations":[{
"op":"add",
"value":[{
"phoneNumbers": [
{
"value": "5551113333",
"primary": true
}
],
"name": {
"givenName": "bob",
"familyName": "builder"
}
}]
}]
}

Note that the Operations attribute is an array and that multiple operation objects can be passed in the array to perform multiple updates with different actions in one request.

PUT

This example uses the PUT method to change a user attribute. The emails.value attribute is changed to bob-new-email@example.com. The PUT method of changing a resource assumes a complete resource. If the phoneNumbers and name attributes were omitted from the request in this example below, they would be removed from the resource.

http
123456789101112131415161718192021222324252627282929
PUT /um/admin/Users/VVNFUjphNGMyZjEzNGY4NjE0MmFhYTkzYzY4ZGEwNmE5MjRiZQ HTTP/1.1
Host: idsvr.example.com
Accept: application/scim+json
Authorization: Bearer ec2979e4-f766-4c79-85f9-58f6c72e224f
Content-Type: application/scim+json
 
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"id": "VVNFUjphNGMyZjEzNGY4NjE0MmFhYTkzYzY4ZGEwNmE5MjRiZQ",
"userName": "bob",
"emails": [
{
"value": "bob-new-email@example.com",
"primary": true
}
],
"phoneNumbers": [
{
"value": "5551113333",
"primary": true
}
],
"name": {
"givenName": "bob",
"familyName": "builder"
}
}

Delete

Deleting a resource can be achieved using the DELETE method. Simply specify the id of the resource to delete, and the response should be 204 No Content.

http
1233
DELETE /um/admin/Users/VVNFUjphNGMyZjEzNGY4NjE0MmFhYTkzYzY4ZGEwNmE5MjRiZQ HTTP/1.1
Host: idsvr.example.com
Authorization: Bearer ec2979e4-f766-4c79-85f9-58f6c72e224f

References

Photo of Jonas Iggbom

Jonas Iggbom

Director of Sales Engineering at Curity

Join our Newsletter

Get the latest on identity management, API Security and authentication straight to your inbox.

Start Free Trial

Try the Curity Identity Server for Free. Get up and running in 10 minutes.

Start Free Trial