The System for Cross-domain Identity Management (SCIM) is an open standard that supports synchronization of user provisioning from one system to another. SCIM enables the exchange of identity data between cloud services and identity providers (IdPs), allowing companies to automate user provisioning across these systems.
For organizations managing hundreds or thousands of user accounts, manually creating, updating, and removing users across multiple apps does not scale. SCIM provides the same foundational benefits that single sign-on offers for authentication, including interoperability across identity providers, clear implementation guidance, existing tooling, and broad support across modern SaaS platforms.
In this guide, you’ll learn what SCIM provisioning is, how it works, common workflows, security considerations, real-world limitations, and how SCIM fits into modern access management.
What Are the Benefits of SCIM Provisioning?
Before learning the specifics of SCIM, you should know how it can help your organization and customers.
Scalable User Management
SCIM provisioning automates user management across apps by synchronizing user accounts, group membership, and permissions from the identity provider to destination systems. This removes manual effort for IT teams and reduces delays during onboarding and offboarding.
For SaaS and B2B platforms, supporting SCIM provisioning ensures compatibility with enterprise customers using Okta, Microsoft Entra ID, and other identity providers, each with their own requirements for lifecycle management.
Enhanced Security and Compliance
Automated SCIM provisioning reduces human error by enforcing consistent access controls and permissions across systems. By limiting who can provision, modify, or deactivate users manually, organizations reduce the risk of unauthorized access and configuration drift.
SCIM also strengthens compliance by ensuring deprovisioning happens reliably when a user leaves or changes roles, reducing the risk of lingering access.
Full User Provisioning Solution
Before SCIM gained popularity and wider use, organizations would often use SAML just-in-time (JIT) provisioning to provision users. This is a great starting point.
However, with SAML JIT provisioning, a user has to sign in to your system before changes from the IdP are synchronized. With SCIM, changes in one system will propagate to other systems automatically. For example, deactivating a user in your IdP will propagate immediately to your SCIM-enabled application.
SCIM is a full solution for user provisioning that gives you tighter security, a better user experience, and full provisioning functionality.
How Does SCIM Provisioning Work?
SCIM is an HTTP API standard that defines various HTTP endpoints to synchronize identities between systems. There are two resources that are available to interact with: User and Group. Each resource has a given schema.
The SCIM standard as a whole has two core parts, consisting of a schema and protocol.
Schema
The schema defines the types of attributes that are expected and required when implementing your own SCIM API. Here, you’ll define email addresses, which tenant the user belongs to, the person’s name, and so on. Most SCIM implementations keep the schema simple, but the standard includes many optional attributes.
For example, here are Amazon’s required attributes.
For SCIM synchronization to work, every user must have a first name, last name, username, and display name value specified. If any of these values are missing from a user, that user will not be provisioned.
SCIM defines many attributes—here are some of the important ones you should know about:
id: A unique identifier that your system generates for every specific SCIM resource. The value must be unique across all SCIM resources in your system (e.g., across all tenants).externalId: An identifier that comes from the IDP or source system. Usually, this is a SAML identifier or some IDP-specific value. This is optional but can help to link your SCIM users with users who sign in to your system via SSO.userName: Your system’s unique identifier for the given user. This is usually an email address, username, or an integer or UUID.meta: An object holding various metadata attributes about the resource.schemas: SCIM has different schemas that define various attributes. For example, there’s a core user schema, an enterprise user schema extension that defines even more attributes for users, and a core group schema.
There are more schemas and ways to add your own. Check out the standard for more on these.
Protocol
The SCIM protocol defines the various functions (as HTTP endpoints) that you need to implement.
Because the SCIM protocol specification is fairly long, wordy, and covers mostly optional SCIM functionality, it’s not the best place to begin learning about how the SCIM protocol works. Instead, let’s start by looking at Amazon’s implementation of SCIM.
This is an excellent starting point because Amazon’s documentation is concise yet sufficient. Its implementation of SCIM covers only the necessary parts of the standard and nothing more. It’s a great real-world implementation example instead of a theoretical blueprint.
Here are all the actions available via its SCIM implementation:
CreateUserGetUserListUsersDeleteUserPutUserPatchUserCreateGroupGetGroupListGroupsDeleteGroupPatchGroupServiceProviderConfig
Note that PutUser and PatchUser can be used to update the active attribute to activate or deactivate a user. This is different from the DeleteUser endpoint. See the standard for more.
CreateUser SCIM Endpoint
Here’s what a basic request to the CreateUser endpoint might look like:
{
"externalId": "701984",
"userName": "bjensen",
"name": {
"formatted": "Ms. Barbara J Jensen, III",
"familyName": "Jensen",
"givenName": "Barbara",
"middleName": "Jane",
"honorificPrefix": "Ms.",
"honorificSuffix": "III"
},
"displayName": "Babs Jensen",
"emails": [
{
"value": "bjensen@example.com",
"type": "work",
"primary": true
}
],
"active": true
}
Here’s a sample of a successful response to that request:
{
"id": "9067729b3d-94f1e0b3-c394-48d5-8ab1-2c122a167074",
"externalId": "701984",
"meta": {
"resourceType": "User",
"created": "2020-03-31T02:36:15Z",
"lastModified": "2020-03-31T02:36:15Z"
},
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User",
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
],
"userName": "bjensen",
"name": {
"formatted": "Ms. Barbara J Jensen, III",
"familyName": "Jensen",
"givenName": "Barbara",
"middleName": "Jane",
"honorificPrefix": "Ms.",
"honorificSuffix": "III"
},
"displayName": "Babs Jensen",
"active": true,
"emails": [
{
"value": "bjensen@example.com",
"type": "work",
"primary": true
}
]
}
Notice that the response mostly echoes the attributes sent in the request. However, there are a few new attributes that the destination system generated: id, meta, and schemas.
ServiceProviderConfig SCIM Endpoint
The ServiceProviderConfig API endpoint is how an IDP discovers what SCIM functionality your API provides. As there are many optional pieces to SCIM, an IDP may change how it interacts with your API depending on what your API supports. For example, if your API supports HTTP PATCH requests, then the IDP may choose not to use HTTP PUT at all. Some IDPs may ignore this altogether.
Here is a sample HTTP response from Amazon’s documentation that lists other supported and unsupported optional features, including HTTP PATCH operations, bulk operations, the ability to change passwords, and filtering:
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"
],
"documentationUri": "https://docs.aws.amazon.com/singlesignon/ latest/userguide/manage-your-identity-source-idp.html",
"authenticationSchemes": [
{
"type": "oauthbearertoken",
"name": "OAuth Bearer Token",
"description": "Authentication scheme using the OAuth Bearer Token Standard",
"specUri": "https://www.rfc-editor.org/info/rfc6750",
"documentationUri": "https://docs.aws.amazon.com/singlesignon/ latest/userguide/provision-automatically.html",
"primary": true
}
],
"patch": {
"supported": true
},
"bulk": {
"supported": false,
"maxOperations": 1,
"maxPayloadSize": 1048576
},
"filter": {
"supported": true,
"maxResults": 50
},
"changePassword": {
"supported": false
},
"sort": {
"supported": false
},
"etag": {
"supported": false
}
}
Basic Workflow
While each IDP has its own SCIM lifecycle that depends on the specific implementation, the following is the basic lifecycle of a user that is provisioned via SCIM:
- The IDP checks if the user exists already.
- If the user does not exist, the IDP sends an HTTP POST request to
/scim/Users. - If the user exists, the IDP will update your system by sending an HTTP PATCH or PUT request to
/scim/Users.
- If the user does not exist, the IDP sends an HTTP POST request to
- If the user is changed in the IDP, it will send an HTTP PATCH or PUT request to
/scim/Users. - If the user is deleted in the IDP, it will send an HTTP DELETE request to
/scim/Users.

For an example of a real IDP’s lifecycle, take a look at the Microsoft AD SCIM provisioning lifecycle. There are other factors involved, such as error handling, quarantining failed synchronizations, lifecycle for user creation, lifecycle for updating a user, lifecycle for deletion, and hard vs. soft delete (eg deactivation vs. full removal).
In practice: SCIM provisioning works best when paired with modern access management tooling. Platforms like ConductorOne sit alongside your identity provider to control who can configure SCIM integrations, manage provisioning permissions, and audit changes to identity and access settings across applications.
Limitations and Problems with SCIM
Using a standard for user provisioning has many benefits, but SCIM isn’t perfect.
Loose Standard
SCIM offers different ways to implement certain operations, resulting in IDPs having different requirements for what your SCIM API needs to support in order to work with them. Ideally, this is what a standard is supposed to avoid.
For example, when updating a User and Group, some IDPs support HTTP PATCH, while others may only support HTTP UPDATE. Okta uses HTTP PATCH only for user activation/deactivation and password sync. According to the Okta documentation, “All other updates to User objects are handled through a PUT method request.” Microsoft Entra ID (formerly Azure Active Directory), on the other hand, doesn’t support PUT at all and only supports updates via HTTP PATCH. This variability increases implementation effort and complicates interoperability across SaaS apps.
Nonconformance
Sometimes, an IDP’s first implementation didn’t follow the SCIM standard. For example, Microsoft Entra has cases where it didn’t previously conform to SCIM and has special flags that need to be included with HTTP requests. These flags can change how SCIM behaves and are extra pieces of information you must know about.
Group Members Array
The members attribute in the Group resource can cause significant problems. Your SCIM API defines the members attribute as a JSON array that lists all the users who are members of a given security group. As groups can have many members (possibly thousands) and JSON attributes cannot be paginated, the HTTP responses for large groups can become massive and slow down the API’s performance.
Most SCIM APIs have handled this by setting a hard limit on how many records they return in that attribute. Either they return an empty array all of the time or don’t return the attribute at all.
For example, the FastFed profile (which you’ll learn about later) mandates that the IDP calling your SCIM API must explicitly request the exclusion of this attribute because it’s so problematic.
Likewise, Amazon’s SCIM API just never returns the attribute.
User Invitation Process
The SCIM standard mandates that the CreateUser request must return the details of a successful user that was added to the destination system:
When the service provider successfully creates the new resource, an HTTP response SHALL be returned with HTTP status code 201 (Created).
However, many applications have a user provisioning process whereby a user is first invited via their email address and then has to verify that invitation before their account is created.
Do you return a fake user to the IDP on the CreateUser response? What happens when the IDP queries your SCIM API to sync all users, but some users in your system have not completed the invitation process yet?
This scenario also applies to systems where users are provisioned via asynchronous background processing in the destination system. Does the SCIM API just return a fake user since it doesn’t exist yet?
There’s no guidance in the SCIM standard, and this is a blind spot for such a common use case. For an example of how to think about this scenario, take a look at how GitHub handles it.
This creates challenges for lifecycle management, especially during onboarding workflows that rely on asynchronous user creation.
Security Best Practices for SCIM Provisioning
A SCIM API is like any other HTTP API. Bad actors can and will attempt to find vulnerabilities in your API and attempt to attack your system. Therefore, standard HTTP API security concerns also apply to SCIM APIs:
- Are you defending against denial-of-service (DoS) attacks?
- Is your authentication mechanism robust and secure?
- Are you prone to man-in-the-middle attacks?
Authentication
With SCIM, the most likely choice for authentication is a bearer token. In fact, most IDPs only give you this option.
Standard API token security best practices apply here:
- Rotate your tokens
- Make sure your tokens expire
- Ensure your SCIM token only has authorization to access SCIM functionality and no other APIs or functionality in your system (principle of least privilege)
- Limit who can access and generate SCIM tokens
- Consider using a JIT access request tool to limit access to those who can generate SCIM tokens even further
Other Security Considerations
There are still more security hardening measures to be considered. For example, OWASP has published a great guide on REST API security that you can refer to for more information. Here are a few other important security measures to consider for your SCIM APIs:
- Enforce HTTPS for your entire SCIM API
- Implement some form of rate limiting to defend against DoS attacks or aggressive IDPs
- Consider not synchronizing passwords via SCIM
- Some IDPs have the option to push passwords to other systems. Even if your API is using HTTPS and has other protections, is there another way to do what you want? Chances are your customers are using SSO anyway.
The Future of SCIM
SCIM is a relatively young standard. Because of this, the standard is open to revision through real-world usage. The organization that manages the SCIM specification, the Internet Engineering Task Force, has documented in RFC 7642 a first round of learnings that detail common SCIM workflows.
There is also a larger specification being worked on that includes various authentication and federation-related standards called FastFed. FastFed aims to reduce ambiguity in SCIM implementations by standardizing how identity providers, service providers, and access management systems interoperate during provisioning and federation. Part of this standard includes guidance on an opinionated way to implement SCIM.
However, a consequence of the flexibility [of SCIM] is that two providers may find themselves incompatible despite sharing the same protocols.
To deliver the simplified experience that is the goal of FastFed, it is important that two FastFed-enabled providers have confidence that they can interoperate when sharing the same protocols.
In other words, the FastFed SCIM profile is a boiled-down, opinionated approach to implementing SCIM that makes it closer to a true standard. It also defines overarching standards so that various tools like SCIM and SSO can reuse the same authentication and access management functionalities.
Amazon’s SCIM implementation, discussed in this article, serves as an excellent foundation and is based on the FastFed profile.
Conclusion
SCIM provides a standardized way to synchronize user identities, permissions, and lifecycle changes across systems. By adopting SCIM provisioning, organizations can automate onboarding and deprovisioning, reduce human error, and improve the security and reliability of user management across SaaS applications.
Because SCIM integrations rely on powerful bearer tokens and provisioning permissions, securing access to SCIM configuration is critical. ConductorOne helps teams control and audit who can manage SCIM integrations, generate tokens, and modify identity provider settings using just-in-time access and approval workflows. Combined with SCIM, this approach strengthens access management without slowing down IT teams.
SCIM FAQs
What is the difference between SAML and SCIM provisioning?
SAML handles authentication and single sign-on. SCIM handles user provisioning, updates, and deprovisioning. They are complementary, not interchangeable. Watch our video to learn more:
Is SCIM the same as SSO?
No. SSO controls how users sign in. SCIM controls how user accounts, permissions, and lifecycle changes are managed across apps.
What is the purpose of SCIM?
SCIM standardizes how identity providers provision and manage user accounts across systems, reducing manual work and improving security.
When should you implement SCIM?
You should implement SCIM when you need reliable onboarding, offboarding, and permission management across multiple SaaS apps at scale.




