Simplify Identity Lifecycle Management with SCIM

In a growing world of apps, SCIM helps with the struggles of user provisioning

Every app developer hopes their app goes viral. Build an app, let it loose, and watch it grow. In the consumer world, apps organically grow in popularity as people share. In the enterprise world, however, IT needs tight control over who has access to what applications.

As the number of applications used in an organization grows, managing access to each app becomes a challenge. IT must be a gatekeeper, but user provisioning can be a tremendous burden.

Either IT must manually provision every account, or build custom API-based solutions for provisioning. Most apps provide user APIs that allow for basic CRUD operations. However, maintaining custom integrations between a central user store (typically an identity provider), and each application used in an organization becomes untenable for an IT administrator. This is where the SCIM standard comes into play.

How Can SCIM Simplify Provisioning?

SCIM uses modern protocols such as REST and JSON to define a core user schema and the APIs needed to manage user operations. The SCIM standard defines a client, typically an identity provider such as Azure Active Directory and server role, usually an app such as Zscaler, Workplace by Facebook, or Dropbox.

In SCIM, there are three required attributes for a user (id, externalId, and meta), a set of commonly used optional user attributes (e.g., name, emails, jobTitle), and a framework for extending the attributes of a user based on the application’s requirements. This model provides a common language for applications and identity providers to communicate while providing the flexibility needed to meet application-specific requirements.

Understanding the SCIM Standard

The SCIM standard can be a lot to consume, so I’ve broken down some of the key concepts. Remember that much of the SCIM standard is optional. You can get started with a simple /User endpoint that allows creating, updating, and deleting a user.

Resources defined in the SCIM standard

The SCIM standard provides a default schema for managing users and groups. The core user schema requires three attributes at a minimum: id, externalId, and meta. All other attributes are optional. The enterprise user schema extends the core schema to include additional commonly used user properties. If, for example, your application processes payments, you can use the enterprise user schema to collect the cost center associated with the user.

Core user schema (urn:ietf:params:scim:schemas:core:2.0:User)

name locale photos
displayName timezone addresses
nickname active groups
profileUrl password entitlements
title emails roles
userType phoneNumbers phoneNumbers
X509Certificates
userName preferredLanguage ims

Enterprise user schema (urn:ietf:params:scim:schemas:extension:enterprise:2.0:User)

employeeNumber costCenter organization
division department manager

Authentication & Authorization

The SCIM standard leaves authentication and authorization relatively open. You could use cookies, basic authentication, TLS client authentication, or some of the other methods listed here. Security considerations and industry best practices should be taken into consideration when choosing an authentication/authorization method. Avoid insecure methods such as username and password in favor of more secure methods such as bearer tokens.

Endpoints

There are several endpoints defined in the SCIM RFC. You can get started with the /User endpoint and then expand out from there. The /Schemas endpoint is helpful when using custom attributes or if your schema changes frequently. It enables a client to retrieve the most up to date schema automatically. The /Bulk endpoint is especially helpful when supporting groups. It enables you to batch requests.

Endpoint Description
/User Perform CRUD operations on a user object.
/Group Perform CRUD operations on a group object.
/ServiceProviderConfig Provides details about the features of the SCIM standard that are supported. For example it would indicate what resources are supported and the authentication method.
/ResourceTypes Specifies metadata about each resource
/Schemas The set of attributes supported by each client and service provider can vary. While one service provider may include “name”, “title”, and “emails” another service provider may use “name”, “title”, and “phoneNumbers”. The schemas endpoint allows for discovery of the attributes supported.
/Bulk Bulk operations allow you to perform operations on a large collection of resource objects in a single operation (e.g. update memberships for a large group)

The set of attributes supported by each client and service provider can vary. While one service provider may include name, title, and emails, another service provider may use name, title, and phoneNumbers. The schemas endpoint allows for the discovery of the attributes supported.

Best Practices

There are certain best practices for using SCIM. For example, performance is paramount for large organizations. To help improve performance, especially when dealing with large tenants, ensure that PATCH operations are enabled if supporting Groups. Also, ensure that your endpoint has a rate limit above 50 requests/sec. This will allow large organizations to quickly onboard to your application. Other best practices include:

  • Every response that returns a resource should ensure each resource has the id property, except for ListResponse with zero members.
  • Response to a query/filter request should always be a ListResponse
  • Don’t require a case-sensitive match on structural elements in SCIM. In particular, PATCH op operation values.

Mistakes happen, so anticipating these errors is a good idea. To enable easier recovery, consider supporting soft deleting or suspending user objects to allow for rolling back accidental deletes. The SCIM RFC supports setting a user object to inactive and later activating the user. This helps ensure that users who were accidentally deleted by the client can be recovered.

Example CRUD Operations on a User

In the images below, you can see some example requests and responses for creating, reading, and deleting a user. SCIM standardizes these operations for two reasons. First, so that every client will provide a request in the same format. Second, so that the service providers will return the object in the same format. This ensures that an app developer only has to build an endpoint once. After this, it will work seamlessly with all other clients or identity providers.

Request
POST/Users

{
	"schemas": [
	    "urn:ietf:params:scim:schemas:core:2.0:User",
	    "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],
	"externalId": "0a21f0f2-8d2a-4f8e-bf98-7363c4aed4ef",
	"userName": "Test_User_ab6490ee-1e48-479e-a20b-2d77186b5dd1",
	"active": true,
	"emails": [{
		"primary": true,
		"type": "work",
		"value": "Test_User_fd0ea19b-0777-472c-9f96-4f70d2226f2e@testuser.com"
	}],
	"meta": {
		"resourceType": "User"
	},
	"name": {
		"formatted": "givenName familyName",
		"familyName": "familyName",
		"givenName": "givenName"
	},
	"roles": []
}

Response

TTP/1.1 201 Created
{
	"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
	"id": "48af03ac28ad4fb88478",
	"externalId": "0a21f0f2-8d2a-4f8e-bf98-7363c4aed4ef",
	"meta": {
		"resourceType": "User",
		"created": "2018-03-27T19:59:26.000Z",
		"lastModified": "2018-03-27T19:59:26.000Z"
	},
	"userName": "Test_User_ab6490ee-1e48-479e-a20b-2d77186b5dd1",
	"name": {
		"formatted": "givenName familyName",
		"familyName": "familyName",
		"givenName": "givenName",
	},
	"active": true,
	"emails": [{
		"value": "Test_User_fd0ea19b-0777-472c-9f96-4f70d2226f2e@testuser.com",
		"type": "work",
		"primary": true
	}]
}

Request
GET/User

GET / Users/5d480a8e9f04aa38008
Response
HTTP/1.1 200 OK
 {
	"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
	"id": "5d48a0a8e9f04aa38008",
	"externalId": "58342554-38d6-4ec8-948c-50044d0a33fd",
	"meta": {
		"resourceType": "User",
		"created": "2018-03-27T19:59:26.000Z",
		"lastModified": "2018-03-27T19:59:26.000Z"
	},
	"userName": "Test_User_feed3ace-693c-4e5a-82e2-694be1b39934",
	"name": {
		"formatted": "givenName familyName",
		"familyName": "familyName",
		"givenName": "givenName",
	},
	"active": true,
	"emails": [{
		"value": "Test_User_22370c1a-9012-42b2-bf64-86099c2a1c22@testuser.com",
		"type": "work",
		"primary": true
	}]
}

Request
Delete/User

DELETE /Users/5171a35d82074e068ce2 HTTP/1.1

Response

HTTP/1.1 204 No Content

How to Integrate a SCIM Endpoint With an Identity Provider

Once you’ve built your SCIM 2.0 compliant endpoint(s), it will be compatible with a number of identity providers. I’ll walk through how to integrate with Azure Active Directory:

1. Sign up for an Azure Active Directory developer tenant

2. Sign in to the Azure Active Directory portal.

3. Select Enterprise applications from the left pane.

4. Select + New application > All > New-gallery application

5. Add a name for your application, and select Add to create an app object. The new app is added to the list of enterprise applications and opens to its app management screen.

6. In the app management screen, select Provisioning in the left panel.

7. In the Provisioning Mode menu, select Automatic.

8. In the Tenant URL field, enter the URL of the application’s SCIM endpoint. Example: https://api.contoso.com/scim

9. Enter an OAuth bearer token into the Secret Token field

10. Select Test Connection to have Azure Active Directory attempt to connect to the SCIM endpoint and click Save.

11. In the Mappings section, there are two selectable sets of attribute mappings: one for user objects and one for group objects. Select each one to review the attributes that are provisioned from Azure Active Directory to your app.

12. Under Settings, the Scope field defines which users and groups are provisioned. Select Sync only assigned users and groups when testing. Be sure to ensure that your users are assigned to the application.

If your SCIM endpoint is applicable to more than one organization, you can request that a connector be published in the Azure AD application gallery. This allows admins to integrate with your endpoint and provision users/groups quickly.

Helpful resources to get started