SCIM (System for Cross-domain Identity Management) is an open standard that lets an identity provider, such as Okta or Microsoft Entra ID, automatically create, update, deactivate and remove user accounts and groups in other applications. Instead of an administrator repeating every directory change in each app, the directory sends standardized REST requests and the app applies them.
SCIM at a glance
- Full name: System for Cross-domain Identity Management
- Current version: SCIM 2.0
- Standards: RFC 7643 (core schema), RFC 7644 (protocol), RFC 7642 (concepts and requirements)
- Format: JSON over HTTPS, using standard REST methods
- Two roles: the SCIM client (usually the identity provider) and the SCIM service provider (the application that receives changes)
- Main resources: Users and Groups, plus the Enterprise User extension for attributes such as department and manager
- SCIM provisioning: automatic creation, update and deprovisioning of app accounts, driven by the customer’s directory
- SCIM vs. SAML: SAML signs users in; SCIM creates and removes their accounts. Enterprises usually want both.
What is SCIM?
SCIM is a specification for keeping user identities in sync across systems. A company keeps its employees in one directory. When someone joins, changes team or leaves, SCIM carries that change to every connected application. Access starts and ends without manual tickets.
The standard defines two things:
- a common schema for describing users and groups, with attributes such as
userName,name,emails,activeand groupmembers - a REST protocol for creating, reading, updating and deleting those resources
Because both sides speak the same format, an identity provider can connect to many applications without a custom integration for each one.
For a B2B SaaS company, SCIM usually arrives as a customer requirement: an enterprise’s IT team wants its directory to provision and deprovision your app automatically. Your application then acts as a SCIM service provider for many customer directories at once. That adds a tenant dimension the standard itself does not define.
What is SCIM provisioning?
SCIM provisioning is the automated creation and maintenance of user accounts in an application, driven by the identity provider over SCIM. It covers the whole lifecycle:
- creating accounts before a user’s first login
- keeping attributes and group memberships current
- deprovisioning: disabling or removing access when someone leaves or loses the right to use the app
Deprovisioning is the security-critical part. Disabling a user in the identity provider stops new SSO logins. But the application account, active sessions, API tokens and paid seats remain until something removes them. SCIM pushes that change from the directory.
How does SCIM work?
The SCIM client sends HTTP requests to the application’s SCIM base URL, authenticated with a credential the customer configured. The application validates each request and applies it to its user, group and membership records.
A typical lifecycle:
- An administrator configures a SCIM connection between the organization’s directory and the application, usually by pasting the app’s SCIM base URL and a token into the identity provider.
- The directory checks whether a user already exists, then sends a request to create the user or group.
- The application validates the request and maps the external identity to an internal record.
- Later directory changes update user attributes, group membership or account status.
- When access should end, the directory deactivates or removes the corresponding account or membership.
SCIM resources and endpoints
SCIM represents people as User resources and collections of people as Group resources. It also defines three discovery endpoints: /ServiceProviderConfig, /ResourceTypes and /Schemas. They tell clients which features the service provider supports.
| Method | Typical path | What it does |
|---|---|---|
POST |
/Users, /Groups |
Create a resource |
GET |
/Users?filter=... |
Retrieve or search resources |
PUT |
/Users/{id}, /Groups/{id} |
Replace a resource |
PATCH |
/Users/{id}, /Groups/{id} |
Update selected attributes or group membership |
DELETE |
/Users/{id}, /Groups/{id} |
Remove a resource |
Paths are relative to the SCIM base URL, for example https://app.example.com/scim/v2.
SCIM defines the framework. Each application documents which schemas, filters, PATCH behaviors and authentication methods it supports, and what deprovisioning means in its own data model.
Example SCIM requests
These examples follow the request shapes in RFC 7644. Field values are placeholders.
Create a user
POST /Users
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "alex@example.com",
"name": { "givenName": "Alex", "familyName": "Doe" },
"emails": [{ "value": "alex@example.com", "type": "work", "primary": true }],
"active": true
}
The service provider returns 201 Created with the new resource, including the id the client uses in later requests.
Look up a user before creating one
GET /Users?filter=userName eq "alex@example.com"
If nothing matches, return an empty list rather than a 404:
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"totalResults": 0,
"Resources": []
}
Deactivate a user
PATCH /Users/2819c223-7f76-453a-919d-413861904646
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{ "op": "replace", "path": "active", "value": false }
]
}
Setting active to false marks the account as inactive. It is not a delete. RFC 7643 leaves the exact meaning to the application, which might suspend the account, remove a membership or do something else.
Add a user to a group
PATCH /Groups/e9e30dba-f08f-4109-8486-d5c6a331660a
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{ "op": "add", "path": "members", "value": [ { "value": "2819c223-7f76-453a-919d-413861904646" } ] }
]
}
Delete a user
DELETE /Users/2819c223-7f76-453a-919d-413861904646
A successful delete returns 204 No Content. Some identity providers deactivate users instead of sending it (see below).
What a SCIM endpoint must handle
- Authentication. RFC 7644 doesn’t mandate a method. Identity providers commonly send a long-lived token in the
Authorizationheader, entered in their provisioning settings. - Filters. Support at least
userName eq "...". Under RFC 7644, attribute names and operators in filters are case-insensitive. - Duplicates. A
POSTfor auserNamethat already exists should return409 ConflictwithscimType: "uniqueness", as RFC 7644 requires. The client can then look the user up and reconcile. - Errors. Return the SCIM error schema,
urn:ietf:params:scim:api:messages:2.0:Error, withstatusand, where relevant,scimType. - Paging. Large directories are read in pages with
startIndexandcount; returntotalResults. - Enterprise attributes. Expect the Enterprise User extension,
urn:ietf:params:scim:schemas:extension:enterprise:2.0:User, with attributes such as department, manager and employee number. - Testing. Microsoft and Okta both publish SCIM test tooling and guidance for app integrations. Run your endpoint against them before customers do.
How Okta and Microsoft Entra ID send SCIM requests
Identity providers implement SCIM differently. An endpoint that handles only the RFC examples will fail with some clients. Documented behaviors to design for:
- Okta checks before it creates. Before creating a user, Okta checks whether it exists with
GET /Users?filter=userName eq "...". Okta’s SCIM FAQ says the endpoint must support this filter. Okta also reads large user lists in pages. - Okta deactivates users instead of deleting them. Okta doesn’t send
DELETEto remove a user. It updates the user withactiveset tofalse. An app that removes access only onDELETEwill never deprovision Okta users. - Okta uses both
PUTandPATCH. It depends on how the integration was built:- App Integration Wizard: every user and group change is sent with
PUT, including deactivation and group membership changes. - Okta Integration Network: user attribute updates use
PUT; user activation and deactivation, and group name and membership changes, usePATCH.
- App Integration Wizard: every user and group change is sent with
- Microsoft Entra ID’s default PATCH format differs from RFC 7644.
- Unless the
aadOptscim062020feature flag is added to a custom (non-gallery) application’s tenant URL, Entra sends capitalized operations such as"op": "Replace". It also sends booleans as strings, for example"value": "False"when disabling a user. - Group member removals differ too. Without the flag, Entra sends a
valuearray; with it, amembers[value eq "..."]path filter. - Microsoft documents the flag as the fix. It says the compliant behavior will become the default but gives no date, so handle both formats.
- Unless the
In practice:
- Accept case-insensitive PATCH
opvalues and string booleans where a client sends them. - Support both member-removal formats.
- Treat
active: falseas a deprovisioning signal, whether it arrives byPUTorPATCH. - Test against each identity provider your customers use.
SCIM vs. SSO and SAML
SCIM manages the account lifecycle; single sign-on (SSO) manages the login. SSO, typically implemented with SAML or OpenID Connect, proves who a user is when they sign in. SCIM creates, updates and removes the account they sign into, whether or not they are signing in at that moment.
| Question | SCIM | SAML (SSO) |
|---|---|---|
| Primary purpose | Provisioning and deprovisioning | Federated authentication |
| Typical data | Users, groups, attributes, active status | Authentication assertion and selected claims |
| Main trigger | Directory lifecycle event | User login |
| Maintains an application account | Yes | Not by itself |
| Removes the account and memberships when someone leaves | Yes | No. It can block new SSO logins, but the account, sessions and seats remain |
Enterprise customers commonly ask for both: SSO so employees sign in with corporate credentials, and SCIM so accounts are created and removed automatically. The standards don’t require each other, although many products, Frontegg included, expect SCIM-provisioned users to sign in through the customer’s SSO connection.
SCIM vs. just-in-time provisioning
Just-in-time (JIT) provisioning creates an account the first time a user signs in through SSO. SCIM creates and maintains accounts from the directory, before and after login.
| Criterion | SCIM | Just-in-time provisioning |
|---|---|---|
| Trigger | Directory pushes a lifecycle change | User successfully signs in |
| Creates users before first login | Yes | No |
| Updates attributes and groups | Yes, when supported and mapped | Usually limited to login claims |
| Deprovisions users who never return | Yes | No |
| Best use | Enterprise lifecycle management | Fast onboarding for authenticated users |
The two can coexist. Teams that use both should decide which source owns each mutable attribute and group membership.
SCIM in a multi-tenant SaaS application
A multi-tenant application must resolve every SCIM connection and every request to one authorized customer. Derive that customer from the authenticated connection and the application’s own configuration, never from a field in the request body.
- Create or identify the customer organization. Assign a stable internal tenant or account ID before provisioning users.
- Bind the directory connection to that tenant. Credentials, external directory identifiers, schemas and mappings must resolve to one customer.
- Validate and normalize incoming resources. Enforce connection authentication, schema rules, attribute types and accepted values.
- Prevent duplicate identities. Match stable identifiers such as
externalIdand normalizeduserName. Return409 Conflictfor duplicate creates, and make updates and deprovisioning safe to repeat. - Process groups separately from roles. An identity-provider group is not automatically an application role. Keep group-to-role mapping explicit and reviewable, and verify that a group change cannot grant an unintended role.
- Handle suspension and deprovisioning deliberately. Distinguish disabling access, removing one tenant membership and deleting a global identity.
- Reconcile failures. Record correlation IDs and outcomes, expose actionable errors, retry only safe operations, and compare directory state with application state when needed. Test duplicate, delayed, out-of-order and partially failed operations.
- Protect and audit the connection. Use TLS and scoped credentials, never log tokens or unnecessary directory attributes, and record which connection, tenant and resource each change affected.
Example: one person in two customer organizations. Suppose Alex belongs to both Acme and Beta, and each customer’s directory controls only its own membership. When Acme’s directory deactivates or removes Alex, the application should end Alex’s access to the Acme account without touching Alex’s membership, roles or access in Beta.
SCIM provisioning with Frontegg
Frontegg provides tenant-scoped SCIM 2.0 provisioning for B2B SaaS applications. SCIM connections are created per customer account, and each connection has its own authorization token, scoped to that account.
- Self-service setup for your customers’ IT admins.
- From the embedded admin portal, a customer admin creates a provisioning connection, then copies the provisioning URL and authorization token into their identity provider.
- Guided walkthroughs cover Microsoft Entra ID and Okta. Any other SCIM 2.0 identity provider can connect with Custom SCIM.
- Enable SCIM Provisioning in the admin portal builder. Older SDK versions only display connection details, so check the minimum versions in the self-service docs.
- Users and groups. Frontegg’s SCIM support covers provisioning, updating and deprovisioning users and groups, and assigning and unassigning users to groups.
- Sign-in through SSO. In Frontegg, SCIM handles the user lifecycle and the account’s SSO connection handles sign-in. Users provisioned by SCIM receive the environment’s default role, plus the SSO connection’s default role when they sign in.
- Group-to-role mapping.
- Customer admins (in the self-service portal) or your team (in the management portal) assign roles to SCIM groups.
- At every login, Frontegg calculates roles from SCIM group memberships and adds them to the user’s JWT, on top of the user’s existing role.
- These roles aren’t stored, and they aren’t shown in the management portal.
- Connection management. Your team can create and delete SCIM connections for each customer account from the Frontegg dashboard or the API. Deleting a connection from the dashboard removes its provisioned users and groups by default; deleting it through the API does not.
- One behavior to plan for: if a user’s email changes in the identity provider, Frontegg creates a new user rather than updating the original one.
- Plans: Self-service SCIM is available on Pay as you go (5 enterprise SSO/SCIM connections) and Enterprise; see pricing.
Learn more about SSO and SCIM in Frontegg, or read the SCIM provisioning docs.
For the broader identity model behind tenant-aware provisioning, see B2B user management and SaaS multitenancy.
FAQ
What does SCIM stand for?
System for Cross-domain Identity Management. Version 2.0 is defined in RFC 7643 and RFC 7644.
Is SCIM the same as SSO?
No. SSO signs a user in; SCIM creates, updates and removes the user’s account. Most enterprise customers use both.
What is a SCIM endpoint?
The base URL of an application’s SCIM API, for example https://app.example.com/scim/v2. Identity providers call it to manage /Users and /Groups.
Does deactivating a user in SCIM delete them?
Not necessarily. active: false marks the account inactive, and deletion is a separate DELETE request. Some identity providers, including Okta, deactivate users instead of sending one.
Put this into practice with Frontegg
Frontegg is customer identity and access management (CIAM) for B2B SaaS. It's free up to 7,500 monthly active users, including 5 SSO/SCIM connections.
Start for freeThe Complete Guide to SaaS Multi-Tenant Architecture
Read the guide