Most people who’ve heard of SCIM describe it as “the protocol that syncs users.” That’s not wrong, exactly. But it’s incomplete enough to cause real problems when you’re building a provisioning pipeline and suddenly wondering why your app has ghost accounts, delayed deprovisioning, and a sync that only kind of works.
Let me attempt to help clear this up.
SCIM Is a Provisioning Protocol, Not an Identity Protocol
SCIM (System for Cross-domain Identity Management) only really does one thing: it moves identity data between systems. Create a user here, update an attribute there, delete an account when someone leaves. That’s it. It is not authentication. It is not authorization. It does not care who you are, only that a record of you exists somewhere it needs to exist.
This matters because I’ve seen teams bolt SCIM onto a system and then act surprised when it doesn’t handle SSO. It won’t. That’s OIDC or SAML’s job. Don’t use a hammer to screw in a nail. Different tool, different problem.
What SCIM Actually Does Well
SCIM excels at the lifecycle stuff that nobody wants to build from scratch. User provisioning, group sync, attribute mapping, deprovisioning. If your IdP supports it and your app supports it, you can get automated account management without writing a custom integration for every downstream system.
The spec (RFC 7643 and 7644, if you’re a spec nerd and want the homework) defines a RESTful API with a standard schema. JSON in, JSON out. You can extend the schema for custom attributes if you need, but every base schema will stay the same.
Where It Falls Apart
All this does not mean it’s perfect.. SCIM assumes a level of implementation consistency that vendors absolutely do not deliver (See how standard is highlighted above? That’s for YOU VENDORS WHO APPARENTLY DON’T KNOW WHAT A STANDARD IS) . The spec leaves enough room for interpretation that two “SCIM-compliant” systems can behave completely differently at the edges. For example: patch vs. put semantics, how they handle bulk operations, what actually triggers a sync. You will hit these edges if you implement SCIM, and you should plan for that.
Deprovisioning is also where teams get lazy and it bites them later. SCIM can disable or delete accounts, but only if something is actually triggering that endpoint when an off-boarding event fires. If your HR system doesn’t have a workflow that triggers deprovisioning, SCIM doesn’t care. The account sits there forever and that’s a you problem, not a SCIM problem.
SCIM vs. LDAP vs. “Just Use the API”
Ok, going to go on a quick rant here. I still run into teams syncing users via scheduled LDAP queries or hand-rolled REST calls to downstream apps because “we already have LDAP” or “it only takes a few hours to write.” Nope. Do not past go. Stop. Straight to jail. SCIM exists specifically so you don’t have to do that. The maintenance cost of custom sync logic compounds fast and the failure modes are ugly and, if you’re lucky, quiet.
Do not hear what I’m not saying.. LDAP has its place. I think it always will. It’s not going anywhere in enterprise environments, but SCIM is purpose-built for cross-domain provisioning over HTTP. If your stack supports it, use it.
TL;DR
- SCIM handles user lifecycle management like provisioning, updates, deprovisioning. It is not SSO, not auth, and not a replacement for OIDC/SAML.
- The spec is reasonable, but open to interpretation. Because of this, vendor implementations are not always consistent at the edges. Test the boundaries.
- Deprovisioning only works if something actually calls the delete/disable endpoint. Wire up your off-boarding triggers and harden them so they fail as few times as possible.
- If you’re still doing custom sync scripts instead of SCIM, stop. The maintenance debt isn’t worth it.