Skip to content

blog: SCIM explained — what it is, when you need it, and Keycloak's native API - #357

Draft
xgp wants to merge 2 commits into
mainfrom
content/2026-w1-scim-explained
Draft

blog: SCIM explained — what it is, when you need it, and Keycloak's native API#357
xgp wants to merge 2 commits into
mainfrom
content/2026-w1-scim-explained

Conversation

@xgp

@xgp xgp commented Aug 31, 2026

Copy link
Copy Markdown
Member

SCIM Explained — what it is, when you need it, and Keycloak's native API

Queue item D1. Half concept explainer, half working walkthrough of Keycloak's native SCIM API.

Why this one matters

SCIM is one of the largest topics in our category and we cover it nowhere. It's also a topic where a generic explainer adds nothing — there are dozens. What doesn't exist anywhere is a tested walkthrough of Keycloak's own SCIM implementation.

Tested end to end on Keycloak 26.7.3

Three findings that aren't written down anywhere, each of which costs real time to discover:

1. Two separate enablement steps. scim-api is a preview feature and needs a per-realm scimApiEnabled flag. With only the feature flag, every endpoint returns 404 and the reason appears solely in the server log:

WARN [org.keycloak.scim.services.ScimRealmResourceFactory] SCIM API is not enabled for realm 'myrealm'

2. The token audience must be the SCIM base URL itself. Not the client id. We tried scim, scim-api, urn:keycloak:scim, and the client id — all return:

{"schemas":["urn:ietf:params:scim:api:messages:2.0:Error"],
 "status":"401","detail":"Invalid token audience"}

Only {server}/realms/{realm}/scim/v2 works. This is the kind of thing that eats an afternoon.

3. ServiceProviderConfig reports meaningful limitations, and you want them before you build:

Capability Supported
patch yes
filter yes, max 100 results
bulk no
sort no
etag no
changePassword no

No bulk endpoint means an IdP syncing 10,000 users makes 10,000 calls.

The post includes real request/response payloads for user creation and filtering, and confirms SCIM-created users are ordinary Keycloak users rather than a parallel store.

The honest bits

  • "Do you actually need this?" — JIT provisioning covers a lot of ground at almost no cost. The dividing line is deprovisioning: a leaver simply never logs in again, so JIT can't help. If you need deprovisioning, you need SCIM.
  • SCIM deactivates, it doesn't delete — most IdPs send active: false, and implementations that treat deprovisioning as deletion lose audit history.
  • Six questions for evaluating anyone's SCIM support — depth varies enormously behind the same checkbox, and PATCH-vs-PUT in particular causes data loss with Okta and Entra ID.
  • Native SCIM is preview, so it may change. Said plainly rather than glossed.

Product tie-in

One paragraph at the end, on the gap the native API genuinely doesn't close: multi-tenant B2B SaaS needs per-organization SCIM endpoints and credentials so one customer's IdP can't touch another's users. Links to our Organizations SCIM docs. It's a real architectural distinction, not a bolted-on pitch.

Verification

  • pnpm build passes (the broken-anchor warning is the pre-existing site-wide /product/sso/#idp-wizard nav link, present on main)
  • 1,467 words
  • Named byline; direct-answer definition in the opening line for snippet and AI extraction
  • Every code block run against a live server

…ative API

Queue item D1. Covers the concept properly and then walks Keycloak's native SCIM
API, which arrived as a preview feature and is barely documented outside the
reference pages.

Tested end to end against Keycloak 26.7.3. Findings that are not written down
anywhere else:

- scim-api is a preview feature AND needs a separate per-realm scimApiEnabled
  flag. The feature flag alone returns 404 on every endpoint, with the reason
  only visible in the server log.
- The service-account token audience must be the SCIM base URL itself
  ({server}/realms/{realm}/scim/v2). We tried "scim", "scim-api",
  "urn:keycloak:scim" and the client id; all return 401 "Invalid token audience".
  This is an afternoon lost if you don't know it.
- ServiceProviderConfig reports bulk, sort, etag and changePassword all
  unsupported, and caps filters at 100 results. Worth knowing before you build
  against it — an IdP syncing 10k users with no bulk endpoint makes 10k calls.

Includes real request/response payloads for user creation and filtering, and
confirms SCIM-created users are ordinary Keycloak users rather than a parallel
store.

Also gives an honest "do you actually need this?" section — JIT provisioning
covers most cases, and the dividing line is whether you need deprovisioning —
plus six questions for evaluating anyone else's SCIM support.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 31, 2026

Copy link
Copy Markdown

Deploying phasetwo-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 7d345ab
Status: ✅  Deploy successful!
Preview URL: https://9fd58237.phasetwo-docs.pages.dev
Branch Preview URL: https://content-2026-w1-scim-explain.phasetwo-docs.pages.dev

View logs

Moves the publication date forward to Thursday 3 September.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant