In this article
May 20, 2026
May 20, 2026

Keycloak's experimental SCIM API: What's in it and what's still missing

Keycloak SCIM vs. WorkOS Directory Sync: A deep dive into features, gaps, and production readiness.

Explore with AI
Open in ChatGPT
Open in Claude
Open in Perplexity

Keycloak shipped a SCIM Realm API as an experimental feature in 26.4. For teams that have been waiting for native SCIM support so an IdP can push users and groups directly into a realm, this is a notable addition. But the "experimental" label is doing real work here. This post maps what's actually in the release against what a production SCIM integration requires, using WorkOS Directory Sync as a reference point.

The problem SCIM is supposed to solve

Every B2B app that sells to mid-market and enterprise eventually gets the same request: provision users from Okta, Entra, or JumpCloud automatically, and deprovision them the moment HR offboards someone. That's SCIM, a standard REST API (RFC 7643/7644) that lets an IdP push user and group lifecycle events into an application.

The hard part isn't the spec. It's that every IdP interprets the spec slightly differently, schemas drift, PATCH semantics are subtle, and implementations need to handle bulk syncs, filtering, pagination, and custom attributes without breaking. The gap between "we support SCIM" and "we support SCIM the way Okta and Entra actually send it" is wide for exactly this reason.

What Keycloak shipped

The new scim-api feature flag turns a Keycloak realm into a SCIM 2.0 service provider. Enabling it at server start and setting scimApiEnabled=true on the realm exposes a SCIM base URL at /realms/{realm}/scim/v2. Authentication piggybacks on the existing Admin API: a service account client is provisioned with manage-users and view-realm, and a client-credentials token serves as the bearer.

What's included:

  • CRUD on /Users and /Groups via POST, GET, PUT, PATCH, DELETE
  • Core User, Enterprise User, and Group schemas
  • Group membership operations (add/remove via PATCH)
  • SCIM filtering and pagination
  • /ServiceProviderConfig, /Schemas, /ResourceTypes discovery endpoints
  • Mapping Keycloak user profile attributes to SCIM attributes via a kc.scim.schema.attribute annotation
  • Validation against the Microsoft Entra ID SCIM Validator

The Keycloak team targeted Entra compatibility first based on community feedback. Entra is one of the stricter major IdPs about spec adherence, which shaped what got prioritized in this release.

What's explicitly missing:

  • Bulk operations
  • Password management
  • Sorting
  • Service provider config management
  • Custom schemas and custom attributes
  • Admin console UI (configuration requires kcadm.sh or the REST API)
  • Organizations support
  • A dedicated SCIM permission model (the Admin API roles are reused)

How WorkOS Directory Sync compares

WorkOS Directory Sync is a managed service that handles directory synchronization, used in production across B2B apps. The architectural difference is worth stating clearly: Keycloak's SCIM API exposes a Keycloak realm as a SCIM target. WorkOS Directory Sync exposes an application as a SCIM target, with WorkOS normalizing IdP quirks into a single stable event stream and REST API.

Feature Keycloak SCIM API v26.4 experimental WorkOS Directory Sync managed service
Core SCIM operations
User CRUD (POST, GET, PUT, PATCH, DELETE) /Users endpoint
Group CRUD /Groups endpoint
Group membership operations Add/remove via PATCH
Bulk operations SCIM /Bulk endpoint Handled via upstream IdP batching; normalized to events
Password management
Schema and attributes
Core User schema
Enterprise User schema
Custom schemas and attributes roadmap via raw_attributes
Group attribute mapping Beyond displayName and members
Querying
Filtering
Pagination
Sorting
Discovery endpoints
ServiceProviderConfig, Schemas, ResourceTypes
Service provider config management
Authorization and multi-tenancy
Scoped SCIM permission model reuses Admin API roles per-directory bearer tokens
Multi-tenant support Per-customer SCIM endpoints per-realm only per-Organization by design
Organizations support not in initial release
IdP compatibility
Microsoft Entra validated
Okta, JumpCloud, OneLogin, Ping, Rippling Not validated in initial release
Non-SCIM directories Google Workspace, BambooHR normalized to same event model
Admin and configuration
Admin console UI kcadm.sh or REST API only

Schemas and attributes

Keycloak supports core User, Enterprise User, and Group schemas. Custom schemas and custom attributes are on the roadmap but not yet available. If a customer's IdP sends a custom attribute like costCenter or a department code the app needs, it can't be surfaced through the Keycloak SCIM endpoint until a future release.

WorkOS Directory Sync exposes the full set of attributes the upstream IdP sends, including core, enterprise, and custom, through a normalized Directory User object. Custom attributes appear in a raw_attributes field, so data isn't lost when an IdP sends something outside the standard schema. Group attributes get the same treatment, which addresses a gap Keycloak's own documentation acknowledges: groups have no equivalent to the user profile feature, so group attribute mapping is essentially limited to displayName and members.

Bulk operations

Keycloak doesn't support SCIM bulk operations yet. Most IdPs issue individual requests per resource rather than using /Bulk, so the immediate impact is limited, but it matters for large initial syncs from IdPs that do batch.

WorkOS handles initial syncs by batching upstream IdP API pulls and emitting normalized events. There's no need to deal with SCIM bulk semantics directly; applications consume dsync.user.created events from a webhook or list users via the WorkOS API.

Filtering, pagination, sorting

Keycloak supports filtering and pagination. Sorting is not implemented. This is a gap for IdPs that issue sortBy/sortOrder query parameters, which Entra does in some sync scenarios.

WorkOS abstracts this away. Developers query the WorkOS API rather than the SCIM endpoint directly, which provides stable pagination and consistent ordering regardless of what the upstream IdP supports.

Authorization model

Keycloak's SCIM API reuses the Admin API permission model. There's no SCIM-specific role yet. Granting manage-users and view-realm to a service account means that account can perform everything those roles allow across the Admin API, not just SCIM-scoped calls. Fine-grained Admin Permissions can narrow the blast radius, but that's left to the operator to configure.

WorkOS uses scoped API keys and per-directory bearer tokens. Each directory connection is scoped to a single organization, so a compromised token from one customer's directory can't access another customer's directory data.

Multi-tenancy and organizations

Keycloak's SCIM API operates per-realm. Building a B2B SaaS where each customer needs its own SCIM endpoint mapped to its own tenant would require a realm per customer, and Organizations support inside a single realm isn't part of this initial SCIM release.

WorkOS Directory Sync is multi-tenant by design. Every directory connection lives inside a WorkOS Organization, which maps to a customer or tenant in the application. Each customer's IT admin gets a unique SCIM endpoint and bearer token, and the application receives a stream of events tagged with the correct organization ID.

IdP compatibility

Keycloak's initial release was validated against Entra. SCIM in production means Okta, Entra, JumpCloud, Google Workspace, Rippling, OneLogin, Ping, and others, each with subtle differences in PATCH semantics, attribute casing, and group sync behavior.

WorkOS Directory Sync ships tested integrations with all of those, plus non-SCIM directories like Google Workspace and BambooHR, normalized into the same event model.

Use case fit

Keycloak's new SCIM API is most relevant for teams running Keycloak as their identity store who want an upstream IdP to push users into Keycloak for SSO into downstream apps. The realm acts as an identity sink in that pattern.

It's a poor fit if:

  • The goal is accepting SCIM from many customer IdPs into many tenants in a B2B SaaS
  • Custom attributes are required now rather than in a future release
  • Support is needed for more IdPs than Entra without writing per-IdP handling
  • The team doesn't want to operate Keycloak, manage realms, and track experimental feature flags through upgrades

Where things stand

SCIM is baseline requirement for selling to enterprise buyers, and the gap between implementing the spec and handling how major IdPs actually behave in production is significant. Keycloak's experimental endpoint covers the basics for a narrow set of use cases, with notable gaps around multi-tenancy, custom attributes, and IdP breadth still to be addressed.