SCIM

SCIM 2.0 provisioning — Users + Groups REST endpoints so an enterprise IdP (Okta, Entra, OneLogin) can create / update / deactivate users in your app.

@voltro/plugin-scim exposes the SCIM 2.0 endpoints enterprise IdPs use to provision users into your app. When an admin adds someone to your app in Okta/Entra, the IdP POSTs to your /scim/v2/Users endpoint; when they remove them, it PATCHes active: false. This is a hard requirement in most enterprise procurement.

Wiring

// app.config.ts
import { scimPlugin } from '@voltro/plugin-scim'

export default {
  type: 'api' as const, name: 'api',
  plugins: [scimPlugin({ token: process.env.SCIM_TOKEN! })],   // basePath defaults to /scim/v2
}

Mounts /scim/v2/Users + /scim/v2/Groups, bearer-gated by token (paste it into the IdP's SCIM config). Contributes the scim_users + scim_groups tables.

Endpoints

Method + path SCIM operation
GET /scim/v2/Users?filter=userName eq "x" list / find a user (userName / externalId eq filters, startIndex/count pagination)
GET /scim/v2/Users/<id> read a user
POST /scim/v2/Users create (provision) — duplicate userName answers 409 uniqueness (DB-unique, IdP-retry-safe)
PUT /scim/v2/Users/<id> replace
PATCH /scim/v2/Users/<id> partial update — incl. the active:false deactivation IdPs send
DELETE /scim/v2/Users/<id> delete
GET/POST/DELETE /scim/v2/Groups list (displayName / externalId eq filters, paginated) / create / delete groups
PUT/PATCH /scim/v2/Groups/<id> replace / membership add-remove-replace (how Okta/Entra push membership changes)
GET /scim/v2/ServiceProviderConfig · /Schemas · /ResourceTypes the RFC 7644 §4 discovery trio IdPs probe at connector setup

Requests + responses use the SCIM JSON envelope (schemas, id, meta, ListResponse); an unsupported filter is answered 400 invalidFilter (never silently unfiltered). The pure mapping (toScimUser, fromScimUser, applyScimPatch, applyScimGroupPatch, scimList, parseScimFilter) is exported + unit-tested.

Notes

  • The bearer token is the trust boundary — keep it secret + rotate it via your IdP.
  • scim_users is the SCIM-side mirror; map it to your real users table in onCreate/sync logic if they differ.

Permissions

store:write (the SCIM tables).