SCIM provisioning
Automatic user lifecycle from your identity provider - joiners get accounts, leavers lose access, automatically.
SCIM keeps orboto's user list in lockstep with your identity provider (IdP): joiners get orboto accounts automatically when IT adds them in the IdP, leavers are deactivated the moment IT disables them there, and profile updates (name, department, manager) flow through without anyone touching orboto directly. It's the natural next step after single sign-on - SSO handles logging in, SCIM handles who exists to log in as.
SCIM is an Enterprise capability, configured entirely under Admin → SCIM provisioning.
What SCIM does, concretely
orboto implements the standard SCIM 2.0 user-provisioning protocol (RFC 7644), which means:
- Your IdP can create a new orboto user the moment someone is assigned the app in the IdP.
- Your IdP can update a user's profile fields (name, email,
department, manager, employee number) whenever they change in the IdP
- orboto stays a mirror, not a second source of truth.
- Your IdP can deactivate or delete a user the moment they're unassigned or offboarded - see Deprovisioning for the exact difference between those two actions.
- orboto also answers the IdP's discovery calls (what resource types and
schemas it supports) and supports the enterprise-user schema
extension, so fields like
employeeNumber,department, andmanagermap correctly instead of being dropped.
Group provisioning isn't available yet - user provisioning covers the common IdP setups used today; if your IdP workflow depends on group-based assignment specifically, confirm your rollout plan accounts for that gap.
Setup
- Under Admin → SCIM provisioning, enable provisioning. orboto
shows the SCIM endpoint URL you'll need
(
https://<your-host>/api/scim/v2). - Select Mint a provisioning token. The bearer token is displayed once - copy it immediately into your IdP's configuration; if you navigate away before pasting it, you'll need to mint a new one (the plaintext is never shown again, only a masked reference).
- In your IdP's provisioning app, set the SCIM base URL and the bearer token from steps 1-2. Every major IdP has a Test connection button at this stage - use it before turning anything on for real users.
- Test with a single user first. Assign one test account in the IdP, confirm it appears correctly in orboto (right name, right email, right department if you're using the enterprise extension), then deactivate that same test user in the IdP and confirm it deactivates in orboto too. Only after both directions check out, assign the full group of users.

Per-IdP setup
The general shape (base URL + bearer token) is the same everywhere; here is exactly where each major IdP asks for it:
| Identity provider | Where to configure it | What goes in the auth field |
|---|---|---|
| Azure AD / Microsoft Entra ID | Enterprise App → Provisioning → Automatic | Tenant URL = the SCIM endpoint URL, Secret Token = the minted token |
| Okta | App → Provisioning → Integration → Enable API integration | Base URL = the SCIM endpoint URL, API Token = the minted token |
| Google Workspace | Apps → Web and mobile apps → Auto-provisioning | SCIM endpoint URL + the minted bearer token |
| JumpCloud | SSO app → Identity Management → Configure | Base URL + the minted bearer token |
orboto is verified against the exact payload quirks of all four -
including Azure AD sending booleans as strings ("true" instead of
true) and Okta's PATCH requests that sometimes omit the path
attribute the spec technically expects. You don't need to work around
either; orboto's endpoint already handles them.
If your IdP isn't one of these four, any standards-compliant SCIM 2.0 client should still work - the endpoint follows RFC 7644 rather than special-casing a fixed vendor list.
Token rotation
Mint, rotate, and revoke tokens from Admin → SCIM provisioning.
- Rotate issues a brand-new token and keeps the old one valid for a 24-hour overlap window. This is the safe way to change tokens: update the IdP with the new token at your own pace within that window, rather than the provisioning breaking the instant you rotate.
- Revoke kills a token immediately, no overlap. Use this when a token has leaked or you're decommissioning an IdP integration for good.
Deprovisioning: deactivate vs. delete
SCIM's standard offboarding action, and orboto's own delete route, behave differently - know which one your IdP sends before you rely on either:
PATCHwithactive=false(what a SCIM-compliant IdP sends on offboarding by default) deactivates the orboto user. They can no longer sign in, but every ticket, comment, and history item they ever touched stays intact and correctly attributed to them - nothing is deleted or reassigned.DELETEon a user is a soft-deactivate by default - same effect as the PATCH case above, and the safe choice for most workspaces, since it never destroys history. An operator can flip this to a genuine hard row deletion instead (irreversible, removes the row outright) via a system-level setting - only do this if your compliance posture actually requires purging the row rather than deactivating it.
In practice: unless you've deliberately switched to hard deletion, both paths are safe and reversible in effect (you can always reactivate a deactivated user manually in orboto) - what's NOT reversible is losing track of when something changed, which is why every SCIM action is logged (see Security below).
Security
- Tokens are workspace-scoped and stored hashed (SHA-256) - the plaintext only ever exists at the moment you mint or rotate it.
- Each token has per-second and per-day rate budgets. Exceeding
either returns HTTP
429with aRetry-Afterheader your IdP's provisioning engine should already respect (all four IdPs in the table above back off correctly on this). - Every SCIM operation - create, update, deactivate, delete, and any rejected/failed attempt - is recorded in the sync history under Admin → SCIM provisioning, with timestamp, operation, outcome, and the error detail on failures. This is the trail an auditor asks for when checking identity-management controls (the kind of evidence frameworks like SOC 2 or ISO 27001 expect for user lifecycle management), and it also feeds the workspace's general audit log and compliance export.

Filtering, sorting, and concurrency
For IdP engineers or anyone debugging a sync directly against the API:
- The endpoint supports RFC 7644 filtering (
eq,ne,co,sw,ew,gt,ge,lt,le,pr, combined withand/or/notand grouping), sorting, and attribute projection (attributes/excludedAttributesto shrink a response to just the fields you need). - Updates use ETag optimistic concurrency: a
PUTorPATCHsendsIf-Matchwith the resource's current ETag, and the request is rejected if the resource changed since you last read it - this stops two concurrent updates from silently clobbering each other, which matters if you're scripting bulk changes outside the IdP's normal provisioning loop.
Outbound lifecycle webhook (optional)
Beyond inbound provisioning, you can set an outbound webhook URL
(same Admin → SCIM provisioning page) so orboto POSTs every
lifecycle event (user.created, user.updated, user.deactivated,
user.deleted) to an endpoint you control - useful for feeding a
downstream audit or SIEM pipeline that wants to know about identity
changes without polling orboto's API. Set a secret alongside the URL and
every delivery carries an X-Orboto-Signature HMAC header you can
verify, the same signing scheme orboto's other webhooks use (see the
API cookbook
for a worked verification example).
Interplay with SSO
SCIM and SSO solve two different problems and are meant to run together, not as alternatives:
- SCIM manages the account lifecycle - who has an orboto account at all, and what their profile fields say.
- SSO manages authentication - how a user proves who they are when signing in.
A user provisioned by SCIM has no orboto password; they sign in only through your IdP via SSO. If you run both, pair them with the "require 2FA for password accounts" policy scoped to just the accounts that genuinely remain on local passwords (service accounts, break-glass admins) - SCIM+SSO users don't need it since they never have a password to protect.
Troubleshooting
| Symptom | Likely cause |
|---|---|
| A newly assigned IdP user never appears in orboto | Check the IdP's provisioning job/log first - most "nothing happened" cases are the IdP-side sync not having run yet (some IdPs provision on a schedule, not instantly) or a failed Test connection that was never actually fixed. Then check orboto's sync history for a rejected request with an error detail. |
| Provisioning worked once, then stopped | Check whether the token expired, was rotated without updating the IdP, or was accidentally revoked. The sync history will show 401s once the token stops being valid. |
| Deactivating a user in the IdP doesn't lock them out of orboto | Confirm the IdP is actually configured to send the deprovisioning action on offboarding (some IdPs need this enabled explicitly, it isn't always the default), and check the sync history to see whether the PATCH active=false (or DELETE) request even arrived. |
| Department / manager fields aren't syncing | Those come from the SCIM enterprise-user schema extension - confirm your IdP's provisioning app is actually configured to send that extension's attributes, not just the base user schema. |
Getting 429s during a bulk provisioning run | You're exceeding the token's per-second or per-day rate budget. Most IdPs already throttle and retry on 429 automatically; if yours doesn't, space out the bulk assignment instead of assigning hundreds of users at once. |
| A user was hard-deleted and you need their history back | If your workspace uses the default soft-deactivate behavior, nothing was actually destroyed - reactivate the user manually in orboto. If hard deletion was explicitly enabled, the row is genuinely gone; restoring it means restoring from a backup (see Backups). |