What is SCIM? The ultimate guide
What is SCIM, and why do you need to support it in your SaaS? We’ll discuss the SCIM standard in-depth, how it works, and how you can add SCIM support to your app.
Scaling user account management manually is impractical for large enterprises with an increasing number of employees using hundreds of cloud services. And, it’s not just the sheer volume of users; it’s also the complexity of managing different roles and access levels, which frequently change as the organization evolves.
To address these challenges, many organizations turn to standardized solutions like SCIM to automatically provision and deprovision their employees.
But what exactly is SCIM, and why do you need to support it in your SaaS?
In this article, we’ll discuss the SCIM standard in-depth, how it works, and how you can add SCIM support to your app.
What is SCIM?
SCIM (System for Cross-domain Identity Management) is a standard for exchanging user identity data between systems, primarily identity providers and service providers. Its primary purpose is to simplify user provisioning by enabling centralized control and automation of user account lifecycles from creating to updating to reading and deleting user identities.
What is provisioning?
Provisioning refers to creating, managing, and disabling user identities and related access permissions within and across systems. It ensures users have the right access to the necessary resources at the right times, and, just as importantly, that access is removed when it's no longer needed or when a user's role changes.
Provisioning can be implemented manually or automatically.
- Manual provisioning requires admins to create, manage, and deactivate user accounts and permissions. This process is time-consuming and prone to errors, and it becomes increasingly inefficient as the number of users grows and their permissions become more complex.
- Automated provisioning uses software, usually identity providers or HRIS systems, to automatically create, update, and deactivate user accounts and permissions across various systems and applications based on predefined rules and policies.
One of the most widely used standards for automating user provisioning is SCIM.
SCIM standardizes how user identity information is communicated across different IdPs and SPs, greatly reducing the need for custom integrations.
With SCIM provisioning, whenever a new user is added to an organization's identity provider, the IdP automatically sends a provisioning request with the user’s details to all connected systems and applications, which can then respond appropriately, for example, by creating an account for the new user.
Conversely, when a user leaves the organization or changes roles, the IdP sends a deprovisioning request to connected apps, which in turn closes all the active sessions associated with the user, almost in real-time.
SCIM also supports bulk operations enabling admins to provision multiple user accounts with a single request. This feature is particularly useful for large organizations or during significant events like company mergers, where it might be necessary to provision or update hundreds or thousands of user accounts at once.
How does SCIM work?
The SCIM protocol defines how SCIM clients (service providers) and servers (identity providers) communicate, using standard HTTP methods (GET, POST, PUT, PATCH, DELETE) to perform operations on resources.
Resources are the main building blocks used to exchange user information. There are two main types:
- Users: Individual user accounts.
- Groups: Collection of users who have something in common e.g. product managers, or engineers.
Each resource type has a predefined schema that provides a standardized model for how user data is structured. The schema defines a set of attributes for user and group resources, along with their data types, and constraints.
There are two main types of attributes:
- Standard attributes: Core attributes for User and Group resources predefined in the SCIM specification.
- Custom attributes: Defined by you to store extra details that might not be specified in the SCIM core schema. For example, you could use “isArchived” to indicate a group’s status.
For each User or Group resource, SCIM defines the following common attributes:
id
: A unique identifier for the user, issued by you (the service provider).externalId
: An identifier for the user, chosen by your customer, that may be used to correlate the SCIM resource with user records in their systems.meta
: Metadata about the resource, including the resource type, creation and modification timestamps, version, and the location of the resource. Defined by you (the service provider)
For more details on SCIM attributes see Each SCIM attribute explained.
SCIM also specifies several endpoints for accessing and managing resources. The two main ones are:
/Users
— For managing individual user entries./Groups
— For handling collections of users.
SCIM User schema
The SCIM User schema defines the attributes associated with individual user accounts. They include:
userName
: The user's primary identifier, such as a username or email address.
displayName
: User’s display name.
emails
: An array of email addresses associated with the user, each entry containing attributes like value (the email address itself), type (work, home, etc.), and primary (a Boolean indicating the primary email address).-
phoneNumbers
: A list of phone numbers associated with the user, with value and type (work, home, mobile, etc.).
roles
: Specifies the roles assigned to the user (e.g. admin, manager).
active
: A boolean value indicating whether the user's account is active or not.
groups
: An array indicating the groups to which the user belongs, typically including a reference to each group's value (ID) and $ref (URL).
Here’s an example of how a user’s data might be structured in a JSON payload according to the SCIM User schema:
SCIM Group schema
The SCIM Group schema defines attributes related to groups within the system. Key attributes of the SCIM Group schema include:
displayName
: The name of the group, used for display purposes.
members
: An array of members (either users or other groups) belonging to the group. Each member is represented as a complex object containing properties likevalue
(the member's unique identifier),$ref
(a reference to the member's resource), andtype
(indicating whether the member is a "User" or another "Group").
Below is an example of a SCIM Group resource:
Extensions and custom attributes
SCIM schemas are designed to be extensible, to allow additional custom attributes beyond the standard set.
While they offer a lot of flexibility, you should always use standard attributes where possible and reserve extensions for truly unique requirements to avoid creating overly complex or non-interoperable implementations.
For enterprises, first, check if you can use the enterprise User schema. This is an extension within the SCIM protocol designed specifically to accommodate additional attributes beyond what the standard SCIM User schema offers. These attributes include organizational roles, department names, employee numbers, and other employment-related details often required by enterprise organizations for managing user profiles
If you still need to create an extension, start by defining the custom attributes in a separate schema object.
For example, to add attributes for an employee's office location, badge number, and the languages they speak, the custom schema object will look like this:
To use this custom schema, incorporate it into a SCIM User resource by including its unique identifier in the schemas attribute and providing the values for the custom attributes as shown below:
SCIM operations
SCIM defines different operations for creating, reading, updating, and deleting (CRUD) user and group operations.
Here's a detailed overview of the primary SCIM operations.
Creating resources (POST)
This operation uses the /Users
and /Groups
endpoints to create a new User and Group resource respectively.
For example, an IdP may send a POST request to the /Users
endpoint of a SCIM server with a JSON payload containing the user’s attributes.
Reading resources (GET)
It’s used to retrieve information about resources. This can be a single resource (like a specific user) or a list of resources (like all users in a system).
For single resources, use endpoints like /Users/{id}
or /Groups/{id}
where {id}
is the unique identifier of the resource. For example:
To retrieve multiple resources, use endpoints without an identifier, such as /Users
or /Groups
. These requests are often paired with query parameters for filtering, sorting, and pagination. This allows IdPs to set criteria that limit the data set returned and manage large data sets by retrieving them in smaller, more manageable chunks.
Here’s an example that filters users by userName
:
Updating resources (PUT/PATCH)
PUT
and PATCH
methods are used to update existing resources but they do it differently.
PUT replaces the entire resource with the payload you provide. Any attributes not included in the request are removed or reverted to their default values. Here’s an example of updating a User
resource:
In this example, the user's email, display name, and nickname are updated, and any attributes not included (e.g., phone numbers, addresses) are removed or reset.
PATCH applies partial updates to a resource. You can specify the changes you want to make without affecting the rest of the resource via operations like replace (update to a new value, add (adding a completely new value), or remove (removing a value from the resource).
Here’s an example:
In this PATCH example:
- The work email is updated to a new value.
- A mobile phone number is added to the user's profile.
- The nickname is removed from the user's profile.
Similar to reading operations, updating operations target specific resources, like /Users/{id}
for updating a user.
Deleting resources (DELETE)
This operation removes resources from the system by targeting specific resources that need to be deleted, such as /Users/{id}
for deleting a user.
Instead of permanently deleting a user account, most IdPs opt to send a PATCH request to set the user's active status to false instead of outright deleting the user account.
This “soft delete” approach is usually preferred because:
- Data retention: Some organizations have policies or regulatory requirements that require retaining user data for a certain period. Deactivating an account keeps the user's data intact while preventing access.
- Audit and compliance: Keeping a record of past users can be crucial for audit trails and compliance with various regulations. It allows organizations to track who had access to what resources and when.
- Reactivation possibility: If a user leaves an organization and then returns, it’s simpler to reactivate their existing account rather than create a new one.
- Minimizing disruption: In some systems, deleting a user might disrupt data integrity, especially if the user is associated with other critical data or operations.
Besides the standard CRUD (Create, Read, Update, Delete) operations, SCIM also supports bulk operations which enables multiple CRUD operations in a single request.
A SCIM bulk operation is structured as a single HTTP POST request to the /Bulk
endpoint. The request body contains an array of operation requests, each specifying the operation type (e.g., POST for create, PUT for update, PATCH for partial update, DELETE for delete) and the data necessary for that operation.
Here's an example of such a request:
In this example:
- The first operation creates a new user with the username
newuser1
. - The second operation deactivates an existing user identified by their ID (
2819c223-7f76-453a-919d-413861904646
). - The third operation deletes a user by their ID (
842e2d92-3ab4-433b-86f0-1a5e0e4a6b1c
).
The SCIM spec doesn’t guarantee the order in which bulk operations are executed. It's crucial to design bulk requests with this in mind, especially when operation outcomes may depend on the order of execution.
What is SCIM used for?
SCIM is primarily used to automate user identity management. In enterprise environments, it helps organizations automatically create (provision), or remove (de-provision) user accounts in various systems when an employee joins, moves within, or leaves an organization.
Read more: How to provision users onto your SaaS app from Microsoft Entra, Google Workspace, and more.
Additionally, it helps synchronize user information across different platforms. If an employee's details change (e.g., a name change or department transfer), those changes are automatically updated in all connected systems.
Most SaaS apps will therefore support it to allow organizations to connect their IdPs to their app. Here are a few examples:
- Salesforce, a leading CRM, allows organizations to automatically provision and manage their employee’s accounts.
- Slack: As team members join or leave the organization, their access to Slack channels is appropriately managed via SCIM.
- Google Workspace: Google's suite of productivity tools supports SCIM for managing user identities across its applications, including Gmail, Docs, Drive, and Calendar.
- Dropbox: The cloud storage service supports SCIM for managing Dropbox Business accounts, allowing administrators to manage access to shared documents and data.
Why should you adopt SCIM?
Adopting SCIM is beneficial to your startup and your enterprise customers.
Benefits for startups:
- Closing more deals: Many large enterprises require SCIM support as a precondition for adoption, and it significantly impacts the sales success of your SaaS. This is especially true if you’re targeting enterprises managing a large number of user accounts across various cloud services.
- Adding more seats: If you’re aiming to scale within your client’s organizations, you need to support SCIM. As clients grow and onboard more employees, the ability to automatically provision them to your SaaS via SCIM becomes invaluable as they can easily add new user accounts in your SaaS.
- Reduced support costs: Automating user account management reduces the need for manual setup and maintenance, lowering support costs.
Benefits for enterprises:
- Streamlined identity management: Enterprises often deal with thousands of user identities across numerous cloud services and applications. SCIM automates the provisioning, updating, and de-provisioning of these identities, significantly reducing the administrative burden and minimizing the potential for human error. This also frees up IT resources which translates to time and cost savings.
- Enhanced security: Timely management of access rights is critical for security. Any delays or failures in updating these access rights can lead to security vulnerabilities, such as unauthorized access to sensitive data. SCIM enables automatic updates to user privileges and immediate deactivation of accounts when necessary, thus minimizing the risk of data breaches and ensuring compliance with data protection regulations.
- Improved user experience: SCIM provisioning ensures employees have access to the tools and resources they need from day one. Additionally, it simplifies the offboarding process for a smooth transition when employees leave.
- Compliance and audit readiness: SCIM implementations typically include logging mechanisms that record all actions taken on user identities and access rights. These logs offer a detailed, timestamped record of who did what and when. This information helps enterprises comply better with regulatory requirements and be well prepared for audits.
For more on this topic see You need a SCIM server — Here’s the easiest way to create one.
A brief history of SCIM
SCIM was developed to tackle the challenges of managing user identities in complex IT environments, which have grown due to the increasing number of cloud services and apps.
There are two main versions of SCIM: SCIM 1.1 and SCIM 2.0.
SCIM 1.1
SCIM 1.0 (now deprecated) was introduced in 2011 and was later followed by SCIM 1.1, which clarified the initial version and laid the foundation for a standardized identity management protocol.
It defined a core schema for representing users and groups and specified RESTful APIs for managing these resources (mainly Users and Groups) across systems. The goal was to automate the exchange of user identity information and reduce the need for custom integration work or manual provisioning processes.
SCIM 2.0
SCIM 2.0 was released in 2015 under the stewardship of the IETF (Internet Engineering Task Force) to add more flexibility and standardization to the SCIM standard.
SCIM 2.0 introduced several significant enhancements and refinements:
- Enhanced schema: SCIM 2.0 has new attributes — immutability, returned, and uniqueness.
- mutability: In SCIM 1.1, mutability is represented by the readOnly attribute which could either be true or false. SCIM 2.0 introduced a new attribute, mutability, with four possible values, immutable, readOnly, readWrite, and writeOnly which offered more flexibility.
- returned: A new attribute that controls if and when attributes are returned in a response. It has values like always, never, default, and request.
- uniqueness: This multi-valued attribute specifies whether an attribute must be unique and the scope of that uniqueness. Can be none, server, or global.
- Better filtering and pagination: SCIM 2.0 has more filtering and pagination options such as ne (not equal), ew (ends with), not, and [ ](complex attribute grouping) to enable complex queries.
- Standardization of PATCH request operations: SCIM 2.0 PATCH operations are more specific, and it introduces an Operations attribute for describing exactly what you want to change (e.g. add, remove, or replace).
- Standardized data format: SCIM 1.1 supports both JSON and XML, but SCIM 2.0 explicitly uses JSON.
- In SCIM 1.1, besides the /Users and /Groups endpoints, the only other endpoint available is
/ServiceProviderConfigs
. SCIM 2.0 includes two additional endpoints –/Schemas
and/ResourceTypes
. - In SCIM 1.1, the endpoint is pluralized as
/ServiceProviderConfigs
, whereas in SCIM 2.0, it’s not:/ServiceProviderConfig
. - Use of TLS: Unlike SCIM 1.1, which recommends TLS 1.0, SCIM 2.0 requires you to use TLS 1.2.
FastFed
FastFed was started in 2016 to simplify the onboarding experience for IT administrators. It was created to address the issues that came with the multiple ways of provisioning and federating identities. Some organizations might use SAML or OIDC to SSO users and then use SCIM to provision accounts.
The purpose of FastFed is to develop standard APIs and workflows that admins can use to federate an IdP and applications that support one or more standards.
SCIM Groups and deprovisioning accounts
SCIM Groups are a collection of users who share something in common like roles or needs.
While groups can serve various purposes across different platforms (such as mailing lists in email systems), within the context of SCIM, they’re usually used for role-based access control. Users are assigned to groups that represent their roles. For example, a "Finance" group might be granted access to accounting software, while an "Engineering" group might have access to development tools.
The use of groups as a vehicle for managing permissions is largely a matter of practicality and interoperability and not something that SCIM was specifically designed for. They are mainly used because groups are a widely supported and understood concept across various IdPs and SPs, making them the "lowest common denominator" for implementing access control mechanisms.
Here’s how it works. When a new user is onboarded and assigned to a specific group, they automatically inherit the access rights associated with that group. If the user's role changes or they leave the organization, removing them from a group automatically revokes their access to the associated resources.
Note that using groups for permissions is just the bare minimum. As the number of groups increases, managing them will become increasingly complex and your customer’s admins might find it challenging to keep track of which groups have access to what resources.
Plus, groups are inflexible for dynamic environments where user’s roles and access needs frequently change. Because of these challenges, organizations often need to complement group-based permissions with more fine-grained access control methods.
What to watch out for when working with SCIM groups
SCIM defines a standardized schema for groups which, in theory, should allow your app to process requests from different IdPs in a consistent manner.
Unfortunately, this is far from the case. Various IdPs interpret the protocol differently, so the SCIM implementation can differ from provider to provider. This is particularly evident when it comes to deprovisioning users who are part of groups.
Here are just a few examples of how each IdP handles deprovisioning users from SCIM Groups:
- Okta: If a user is suspended, and while they’re inactive there’s a change, Okta doesn’t communicate these changes if the same group is used for assignment and push.
- Microsoft Entra: A user is not suspended if they’re still a member of any provisioned groups.
- JumpCloud: A user is suspended only if they are removed from the group they were provisioned through.
- OneLogin: A user is deleted and not suspended. If they’re re-added they’ll be treated as a new user.
These variations create divergent sets of information your app needs to process, which is a problem, especially if you’re supporting multiple IdPs (which is likely the case). You’ll need different sets of logic flows to handle the same admin action.
This lack of standardization also poses a security risk.
For example, if a user mistakenly remains in a group they should no longer belong to, they might retain access to sensitive data. This not only creates security vulnerabilities but can also complicate compliance with regulatory standards. Worse still, these inconsistencies mean there’s no standard way of troubleshooting if things go wrong.
For more on this topic see SCIM challenges: navigating the idiosyncrasies of different providers.
SCIM vs JIT
JIT (Just-In-Time) provisioning is an alternative approach to managing user accounts where accounts are created on-the-fly.
SCIM, in contrast, pre-provisions accounts, ensuring that users have access before they even attempt to log in. SCIM offers more control over the lifecycle of user accounts, while JIT simplifies account creation but may offer less control over account attributes and lifecycle management.
For more on this topic see SCIM vs JIT: What’s the difference?
SCIM providers
Despite SCIM’s intent to standardize identity management, the reality is that identity providers (IdPs) often implement SCIM with slight variations.
If you want to integrate SCIM and support the myriad of IdPs your customers use, you face the challenge of accommodating these variations.
Here are just some of the hassles you might encounter:
- Platform-specific features: As noted, different IdPs might implement SCIM slightly differently. Some IdPs might extend the SCIM schema with custom attributes or extensions to add specific features of their platforms that are not part of the standard SCIM specification. For example, you might see different attributes referring to the same thing across different systems — such as surname and last_name.
- Scaling issues: Large enterprises with tens of thousands of employees may want to provision all these users to your app in just a day. Your SCIM implementation must be able to process these bulk requests and high-frequency updates without going down, as missing even a single request can have huge contractual or security consequences for your customer.
- Onboarding new customers: Because of the different ways IdPs handle SCIM, every time you onboard a new client, you’ll need to map any custom attributes they use to your app’s data model, configure the URLs where they’ll send requests, potentially write custom logic for their SCIM requests, and also make sure you’re properly authenticating these requests.
This process is usually tedious and requires constant back and forth with your customer’s IT admin team to ensure everything is working as expected.
For more on this topic see SCIM challenges: navigating the idiosyncrasies of different providers.
Due to these challenges, most developers prefer to use a dedicated SCIM provider to handle all the complexities of implementing SCIM.
But how do you choose which SCIM provider to use? Here are some of the factors to keep in mind:
- Broad support for IdPs: Look for a SCIM provider that supports a wide range of IdPs. This ensures that you can easily integrate with various identity systems, including the ones you currently use and any you might support in the future.
- Ease of integration: Evaluate how easily the SCIM solution integrates with your existing infrastructure. Providers offering well-documented APIs, SDKs, or integration guides can significantly reduce the effort and time required for integration.
- Scalability: The provider should be able to scale with your needs, handling everything from a few dozen to thousands of user identities without significant degradation in performance. Look for providers that go beyond webhooks support. Do they support event streaming? Can you process requests at your own pace?
- Configurable attribute mappings: Since different systems may use different attribute names or schemas, look for a provider that allows you to configure mappings between these attributes.
- Support and maintenance: Evaluate the provider’s reputation for customer support. Responsive, knowledgeable support can be invaluable, especially during the integration phase or in the event of a security issue.
- Easy customer onboarding: Prefer a provider that gives you a do-it-yourself admin portal you can send your customers to let them configure their SCIM connection themselves to avoid the constant back and forth with their IT team.
- Compliance: Check for compliance with relevant regulations (e.g., GDPR, HIPAA) and industry standards (e.g., ISO/IEC 27001). This is crucial if you operate in regulated industries or handle sensitive data.
- Transparent pricing: Providers generally offer MAU (monthly active users) or per-company pricing. Look for clear, transparent pricing models that align with your budget and scaling expectations. Avoid providers with opaque pricing or significant hidden costs.
For the most feature-complete, developer-friendly solution with per-company pricing, choose Directory Sync by WorkOS as your SCIM provider. Here’s why you’ll love it:
- Support for all the major corporate identity providers (such as Okta, Microsoft Entra (formerly Azure AD), OneLogin, etc.) and major HRIS (like BambooHR, Workday, Rippling, etc.). Plus, it normalizes the SCIM attributes used by these providers and presents them in a standardized format so you don’t have to do it yourself.
- SCIM Groups interoperability: As mentioned earlier, there are a lot of inconsistencies in how IdPs handle SCIM groups. WorkOS solves these problems by automatically removing users from all groups they are associated with when they’re deleted or suspended from your customer’s IdP. If the user is later reactivated, the admins are responsible for ensuring they have been reprovisioned back to their groups. This approach means you no longer have to juggle the various ways IdPs handle groups.
- An Events API for streaming real-time ordered events from your customer’s directories. This is unlike webhooks, where requests might arrive out of order which typically causes out-of-sync user states between your app and your customer’s IdPs.
- Flat-rate pricing of $125/month per company, unlike other providers who use MAU-based pricing mode. As you onboard more companies, the pricing becomes even more affordable.
- Developer-friendly with thorough documentation, easy-to-use APIs, and SDKs for most platforms.
- A self-serve admin portal that significantly simplifies the onboarding process. You can manually or programmatically send it to your customer’s IT team and have them configure their IdP to work with your app.
- Audit trails that are invaluable during compliance audits.
How to Implement SCIM for any IDP
Here’s how you can implement SCIM for any IdP with Directory Sync.
1. Create a WorkOS account
Sign in or create an account with WorkOS.
2. Install the WorkOS SDK
There’s an entire list of SDKs (both official and community libraries) to choose from.
3. Get the API key
To connect to WorkOS from your app, you’ll need a WORKOS API key. It identifies your app to WorkOS.
Grab it from your WorkOS dashboard and make sure to store it securely in a .env
file or another secure configuration file.
4. Create a connection to your customer’s IdP
You can configure this connection manually or invite an admin and let them configure their IdP themselves, which is a way faster approach without the need for the back and forth.
Once that’s done, you’re now ready to start processing SCIM events.
5. Handle events
Events refer to the changes in your customer’s directory like an admin creating a new user or updating their details. WorkOS records all these events as they happen. You can retrieve these events via webhooks or using the Events API.
Webhooks instantly notify you whenever there is a change in any of your customer’s IdPs. However, it’s not a guarantee that these notifications will arrive in the order the change happened and you might end up processing requests out of order. Additionally, WorkOS currently doesn’t support rate limiting for webhooks so your system needs to be robust enough to handle requests as they arrive.
The Events API is a better alternative — your events will always arrive in order and unlike webhooks, you can process these events at a pace your system can handle. There are several types of events, based on admin actions. They include dsync.user.created, dsync.user.updated, and dsync.user.deleted. How you process an event will depend on the type of event. For example, you might create a user account for each dsync.user.created event you receive.
For more on the topic of webhooks vs Events API see Why you should rethink your webhook strategy.
Next steps
Want to add SCIM support to your app?
Directory Sync by WorkOS allows you to quickly enable SCIM provisioning from all the major corporate identity providers, such as Okta, Microsoft Entra, and OneLogin, using a single API-based integration.
- Get started fast: With SDKs for every popular platform, and Slack-based support, you can implement Directory Sync in minutes rather than weeks.
- Events-based processing: While webhooks are also supported, WorkOS’s Events API means every SCIM request is processed in order, and in real-time. You’ll never miss a provisioning request again.
- Pricing that makes sense: Unlike competitors who price by monthly active users, WorkOS charges a flat rate for each company you onboard — whether they’re syncing 10 or 10,000 users with your app.