SCIM Provisioning
Gatewyse implements the SCIM 2.0 protocol so your identity provider (IdP) can automatically create, update, deactivate, and role-map users without any manual admin work. SCIM complements SSO: SSO authenticates users at login, while SCIM provisions and lifecycle-manages their accounts and roles out-of-band — an IdP administrator can add a user to a group and have them provisioned into the gateway before they ever sign in.
The SCIM API is mounted at /scim/v2. Every operation is bounded by the bearer token presented on the request: an organization’s token confines it to that organization, and a deployment-level token spans the whole deployment.
What SCIM Is For
- Automated onboarding — new users in your IdP are pushed to the gateway on a schedule or in real time, no per-user setup in the admin dashboard.
- Automated offboarding — when a user is removed from the IdP, they are deprovisioned (soft-disabled) in the gateway.
- Role synchronization — IdP group membership maps to gateway roles (see Groups → Roles).
Enabling SCIM
SCIM is authenticated with a per-organization bearer token, issued from that organization’s page (POST /api/admin/organizations/:id/scim-token). A deployment-wide token can be issued instead from Settings (POST /api/admin/settings/scim-token) when one IdP should provision across every organization.
The token is SHA-256 hashed with the same scheme as API keys and only the hash is stored (Organization.scim.tokenHash); the plaintext is shown once at issuance and never persisted. Issuing either token requires the scim licence feature.
Configure your IdP’s SCIM integration with:
- Base URL —
https://gateway.example.com/scim/v2 - Authentication — OAuth Bearer Token
- Token — the token issued for that organization (or the deployment-wide one)
Every request must carry the token:
curl https://gateway.example.com/scim/v2/Users \ -H "Authorization: Bearer <scim-token>"A request with a missing, malformed, or unrecognized token is rejected with a SCIM 401 error body. Because an organization’s token resolves to exactly that organization, it can never create, read or modify a user outside it.
Endpoints
Responses use the application/scim+json media type. The ServiceProviderConfig advertises support for PATCH and filtering, and no support for bulk operations, sort, etag, or changePassword.
| Method | Path | Purpose |
|---|---|---|
GET | /ServiceProviderConfig | Advertised capabilities and auth scheme |
GET | /ResourceTypes | The User and Group resource types |
GET | /Schemas | Supported attribute schemas |
GET | /Users | List users (supports filter, startIndex, count) |
POST | /Users | Provision a new user |
GET | /Users/:id | Fetch a single user |
PUT | /Users/:id | Full replace of the user’s mutable attributes |
PATCH | /Users/:id | Partial update (most commonly toggling active) |
DELETE | /Users/:id | Deprovision (soft-disable) the user |
GET | /Groups | List groups (roles) |
GET | /Groups/:id | Fetch a single group and its members |
PATCH | /Groups/:id | Add or remove group members (assign/unassign a role) |
User Lifecycle
Provisioning
POST /Users creates a user in the organization the token belongs to. The email is taken from userName (or the primary emails entry), name.givenName/name.familyName populate the user’s name, and externalId is stored for future matching. Newly provisioned users receive the base user role — role elevation is never driven from the User resource, only through Group membership.
Provisioning is idempotent-safe: if a user with the same email or externalId already exists, the request returns SCIM 409 uniqueness rather than creating a duplicate.
curl -X POST https://gateway.example.com/scim/v2/Users \ -H "Authorization: Bearer <scim-token>" \ -H "Content-Type: application/scim+json" \ -d '{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"], "userName": "jane@example.com", "externalId": "idp-user-123", "name": { "givenName": "Jane", "familyName": "Doe" }, "active": true }'Updates
PUT /Users/:idreplaces the mutable attributes (userName,externalId,name,active) in full.PATCH /Users/:idapplies partial changes. It accepts both the{ "path": "active", "value": false }and the{ "value": { "active": false } }operation shapes, forreplaceandaddoperations. Recognized attributes areactive,userName,name.givenName,name.familyName, andexternalId; unknown attributes are ignored rather than failing the whole request.
Deprovisioning
Deprovisioning is a soft disable, never a hard delete. Setting active: false (via PATCH or PUT) or calling DELETE /Users/:id moves the user to the DEACTIVATED status. The user record — and with it all audit history and request-log attribution — is preserved. Re-activating the user (active: true) restores access.
# Deprovision via PATCHcurl -X PATCH https://gateway.example.com/scim/v2/Users/<id> \ -H "Authorization: Bearer <scim-token>" \ -H "Content-Type: application/scim+json" \ -d '{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:PatchOp"], "Operations": [{ "op": "replace", "path": "active", "value": false }] }'Groups → Roles
A SCIM Group maps one-to-one to a gateway role; the group’s members are the users holding that role. Listing groups (GET /Groups) returns the roles available to that scope — the seeded system roles plus any custom roles — with displayName set to the role name.
Membership is synchronized with PATCH /Groups/:id:
- An
addoperation with member values assigns the role to those users. - A
removeoperation unassigns it.
curl -X PATCH https://gateway.example.com/scim/v2/Groups/<roleId> \ -H "Authorization: Bearer <scim-token>" \ -H "Content-Type: application/scim+json" \ -d '{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:PatchOp"], "Operations": [ { "op": "add", "value": [{ "value": "<userId>" }] } ] }'Escalation Guard
The super-admin role is never exposed or assignable through SCIM. It is excluded from the GET /Groups listing, and any attempt to PATCH a group that resolves to super-admin is rejected with SCIM 403 mutability. This means an organization’s IdP — whether misconfigured or compromised — can grant scoped roles (org-admin, dept-admin, and so on) through group membership, but can never escalate a user to super-admin.
A token issued to an organization is bounded to that organization: accounts it provisions are members of it and nowhere else, and it cannot reach another organization’s people. Group-to-role mappings are held per organization for the same reason — a deployment-wide map would mean one organization’s group named engineers and another’s group of the same name granting the same role.
Relationship to SSO
SCIM and SSO are independent and complementary:
- SSO handles authentication — verifying a user’s identity at login and (optionally) re-syncing their roles from IdP group claims on each sign-in.
- SCIM handles provisioning — creating, updating, deprovisioning, and role-mapping accounts out-of-band, independent of whether the user has ever logged in.
Both enforce the same escalation guard: neither path can assign super-admin. Most enterprise deployments run both — SSO for login, SCIM for lifecycle management.