cyber-security identity provisioning claude-curated
System for Cross-domain Identity Management — a standard protocol (RFC 7643/7644) for provisioning and deprovisioning users and groups across SaaS applications. SCIM replaces fragile per-app integrations like nightly CSV imports, ad-hoc admin scripts, and bespoke directory-sync code with a single well-defined REST contract.
Why SCIM exists
Before SCIM, every SaaS vendor invented its own user import format. Identity teams ended up maintaining dozens of brittle pipelines — CSV uploads on a cron, custom scripts hitting vendor APIs, manual offboarding tickets. Joiners got access weeks late, leavers kept access for months. SCIM standardises the contract so an identity provider speaks one protocol to every app that supports it.
Roles
- Identity Provider (IdP) — source of truth for user identity. Common ones: Okta, Microsoft Entra ID (formerly Azure AD), OneLogin, Google Workspace, JumpCloud.
- Service Provider (SP) — the SaaS app receiving user data. Implements SCIM endpoints; the IdP calls them.
The IdP pushes changes to SPs. SCIM is generally a one-way sync from IdP to SP, though some SPs expose read endpoints for reconciliation.
Endpoints
A SCIM 2.0 service provider exposes a small set of REST endpoints under a base URL:
| Endpoint | Purpose |
|---|---|
/Users | CRUD for user resources |
/Groups | CRUD for group resources |
/ServiceProviderConfig | Capabilities advertised by the SP (filter support, bulk ops, PATCH semantics) |
/Schemas | Resource schema definitions |
/ResourceTypes | Available resource types |
/Bulk | Optional bulk operations endpoint |
Resources are JSON, schema-driven, and identified by a stable id assigned by the SP. The IdP’s view of the user is identified by externalId.
Operations
| Method | Use |
|---|---|
| GET | Read a user/group, list with filters |
| POST | Create a new user/group |
| PUT | Replace the entire resource |
| PATCH | Partial update (add/replace/remove attributes) |
| DELETE | Remove the resource (often soft-delete) |
PATCH is the workhorse — IdPs use it for incremental changes like adding a user to a group or flipping active to false. PATCH semantics in SCIM are notoriously tricky; the spec allows multiple operation types per request and SPs vary in what they actually support.
Authentication
Bearer token is overwhelmingly the most common scheme. The IdP stores a long-lived token issued by the SP and includes it on every request. Some SPs offer OAuth 2.0 client credentials flow, but bearer tokens dominate in practice.
Token rotation requires coordination — the SP issues a new token, the operator pastes it into the IdP’s connector config. There is no standard rotation handshake.
Provisioning lifecycle
A typical joiner flow:
- User created in IdP, assigned to an app.
- IdP calls
POST /Userson the SP with the user payload. - SP returns the new resource with its assigned
id. - IdP stores the mapping
externalId→ SPid. - IdP calls
PATCH /Groups/{id}to add the user to relevant groups.
A leaver flow is the same in reverse, but with caveats below.
Deprovisioning gotchas
This is where SCIM integrations most often go wrong.
- Soft delete vs hard delete — most SPs implement DELETE as a soft delete: the user is deactivated (
active: false) but the record remains. This preserves audit trails and user-owned content. If the IdP expects a hard delete, behaviour diverges silently. - Group membership removal — deactivating a user does not always remove them from groups. Group claims may still appear elsewhere. Some IdPs send a separate PATCH to strip group memberships before deactivating.
- Token rotation — rotating a bearer token without updating the IdP connector breaks sync silently. The IdP retries, fails, and provisioning queues stall. Monitoring should alert on prolonged provisioning failures. See also Rate Limiting.
- Race conditions — a user deactivated in the IdP while holding an active session on the SP may keep that session until it expires. SCIM does not revoke sessions; the SP must enforce session checks against current
activestate. - Cascade behaviour — what happens to user-owned data on deprovisioning? Is content reassigned to a manager, archived, or orphaned? SCIM says nothing about this; it is per-SP policy.
- Reactivation — if a leaver returns, reactivating via PATCH is usually safe. But if the IdP issued a new
externalId(e.g. for a contractor coming back as an employee), the SP sees a brand-new user and the old data stays orphaned.
Schema extensions
SCIM defines a core User schema with attributes like userName, name, emails, active. The Enterprise User extension adds employeeNumber, department, manager. Vendors can register custom schemas under their own URN — useful for SaaS apps that need attributes the core schema does not cover.
Filtering
SCIM supports a query language on list endpoints:
GET /Users?filter=userName eq "alice@example.com"
GET /Users?filter=active eq true and emails.value co "@example.com"
SP support varies. ServiceProviderConfig advertises which operators are supported.
Testing
Hard to test in production. Useful tools:
- SCIM playground sites — public test SPs that echo requests back.
- Postman collections — vendors often publish collections covering common operations.
- IdP test mode — most IdPs let you dry-run a sync without actually pushing.
- Local mock SP — for SaaS app developers, a small mock that logs requests is faster than spinning up a real IdP.
See also
- MFA
- Least Privilages
- JIT
- JeP
- Azure AD SSO Patterns
- OAuth Redirect URL Management
- just-in-time provisioning
- CloudTrail Auditing
- SIEM