CodeHerderSearch⌘KRequest access →

Automatic user provisioning (SCIM)

Let your identity provider create, update, and deactivate CodeHerder accounts automatically, on the Enterprise plan.

Automatic user provisioning uses the SCIM standard to let your identity provider manage CodeHerder accounts directly. It creates an account when someone joins, keeps their name in sync, and deactivates the account the moment they leave, all without an admin doing it by hand.

SCIM rides on top of a Single sign-on (SAML) connection, so set that up first. It also needs the Enterprise plan in its own right. A workspace can hold SAML without SCIM, or neither, so check both before you start. See Plans and limits.

Minting a token

There’s no app screen for this yet. You mint a SCIM token with a direct request, using your own CodeHerder API key:

curl -X POST {{api_base}}/v1/sso-connections/<connectionId>/scim-token \
  -H "Authorization: Bearer $CH_TOKEN"

You’ll need your connection’s id for that URL. List it first:

curl -H "Authorization: Bearer $CH_TOKEN" \
  {{api_base}}/v1/workspaces/<workspaceId>/sso-connections

Any workspace id under your account’s top-level workspace works, since SSO connections are account-wide, not per-workspace. The id field on the one connection returned is what the SCIM routes call <connectionId>.

Only an owner or admin of your account’s top-level workspace can mint or revoke a SCIM token, and only a person acting with their own credentials — an agent’s, or any session’s, doesn’t work here. See Credentials and profiles for setting up your own API key.

The response carries token, expiresAt, and createdAt. Copy the token now. CodeHerder shows it once, in that response, and never displays it again. By default a token lasts one year from when you mint it; read expiresAt for the exact deadline.

Minting again immediately retires whatever token was live before. Your identity provider stops authenticating with the old one the moment the new one exists, so update it there right away. Sending a DELETE to the same address revokes the current token outright and answers with the connection either way, including when no token was live to revoke.

To check a live token without re-minting it, read the connection (the same list request above, or a GET on that connection’s own address): the response carries scimTokenMintedAt and scimTokenExpiresAt whenever a token is currently live, so you can confirm when it was issued and when it expires. Both fields are left out entirely when no token is live.

Mint the token as an admin who won’t be the one your identity provider later deactivates — see Offboarding an admin below for why that matters.

Handing it to your identity provider

Give your identity provider two things: the SCIM base URL and the token you minted.

  • Base URL: {{api_base}}/scim/v2 (a self-hosted deployment uses its own address — see Self-hosted deployment).
  • Authentication: bearer token, using the SCIM token from above.

Most identity providers check the connection before saving it by requesting its capabilities. CodeHerder’s SCIM implementation supports filtering and profile updates through both PUT (a full replace) and PATCH (a partial update). It doesn’t support bulk operations, sorting, or ETags.

What your identity provider can do

CodeHerder’s SCIM implementation manages users only — there’s no group provisioning.

Action What happens
Create a user Provisions the account the same way an ordinary invitation does: the member role in your top-level workspace, and the same invitation email.
Read or list users One filter is supported, userName eq "person@example.com". Paging uses a 1-based startIndex and a page size count, which defaults to 200 and tops out at 500.
Update a user Renames userName, displayName, or name.formatted, with a full replace (PUT) or a partial update (PATCH).
Deactivate a user A DELETE, or a profile update that sets active to false.
Reactivate a user A profile update that sets active to true.

Creating a user needs userName, the person’s email address. Everything else is optional: if you don’t send displayName or name.formatted, CodeHerder makes a readable name out of the email address — jane.doe@example.com becomes “Jane Doe”. An email address already registered anywhere in CodeHerder is refused, since addresses are unique across the whole product, not just your workspace. Your plan’s member limit applies to accounts SCIM creates, the same as any invitation you send by hand.

A PATCH supports replace and add operations on active, userName, displayName, and name.formatted (or the whole name object). Any other operation or attribute path is rejected. A PUT replaces the whole user and needs userName; when it leaves out active, the person’s status stays exactly where it was — CodeHerder never reads a missing active as “deactivate” or “reactivate.” Syncing someone’s name never reactivates or deactivates them as a side effect either way.

What deactivating someone does

This is the part your identity provider admin should understand well, because it goes further than switching off sign-in:

  • Every role they hold in the account is revoked.
  • Every API key they hold is revoked, not only ones related to SCIM. That includes agent keys they minted.
  • Every connection they’ve granted to Claude or ChatGPT is revoked too — see What Claude and ChatGPT can do with CodeHerder.
  • Their devices are unlinked and their sessions stop.
  • Their sign-in is disabled, when your account is their home account.

The full list is in Members, teams, and roles.

Reactivating someone re-grants the member role and lets them sign in again — but not necessarily the role they had before. Someone who was an admin or an owner comes back as a plain member; raise their role again if you want the old level back, the same as described in Members, teams, and roles. Reactivating also does not restore a revoked API key or connector grant — set those up again from scratch, the same as anyone doing it for the first time. See Minting API keys.

Deactivating through SCIM never erases the account. A later read still returns the person, with active set to false, because their history stays attached to the work they did.

A SCIM token can never deactivate a workspace owner, or the person who minted it — either attempt is refused with a 403, whether it comes in as a DELETE or as active:false. To remove an owner, have another owner run ch member deprovision, and see Offboarding an admin below for the minter case.

Limits

  • SCIM only sees your account’s top-level workspace roster. Someone whose only membership is in a workspace nested underneath it is invisible to SCIM — listing, reading, updating, or deactivating them through SCIM behaves as if they don’t exist. Manage those people from the Members page instead.
  • There’s no group provisioning and no bulk operations. Team membership inside CodeHerder stays something you manage directly — see Teams.
  • A disabled connection stops SCIM as well as sign-in. A pending one — not yet enabled for sign-in — still serves SCIM, so you can wire up provisioning before you cut sign-in over.
  • SCIM requests are rate-limited per connection. If your identity provider bursts a large sync, a handful of requests may be throttled and worth a retry.

Troubleshooting

Your identity provider reports What’s happening
401 unauthorized No bearer token was sent, or the one that was sent is malformed, unrecognized, revoked, or expired. Mint a fresh token and update your identity provider; if the current one is close to a year old, check expiresAt to see if that’s why.
402 payment required Your account’s plan no longer includes SCIM provisioning — it needs Enterprise.
403 forbidden, on any request The token is valid, but its connection is disabled or gone. Re-enable the connection on the Single sign-on (SAML) page, or set up a new one.
403 forbidden, on creating a user Your plan’s member limit is reached. Free up a seat or upgrade your plan — this applies even if the email address is also already taken; the seat check runs first.
403 forbidden, on deactivating a user The target is a workspace owner, or the same person who minted this SCIM token. Neither can be deactivated through SCIM — see What deactivating someone does above.
404 not found The user id isn’t in your account’s top-level workspace roster, or doesn’t exist at all. SCIM can’t see someone whose only membership is in a workspace nested underneath the top level.
400 bad request The request body is malformed, userName is missing or isn’t an email address, or a PATCH operation names something other than replace/add on active, userName, displayName, or name.formatted.
409 conflict, on creating a user That email address is already registered somewhere in CodeHerder.
429 too many requests Sync traffic hit the per-connection rate limit. Retry the throttled requests; the response’s Retry-After header says how long to wait.
A filter is rejected Only userName eq "..." is supported — no other field or operator.
Group sync fails (501) Group provisioning isn’t implemented. Manage team membership in CodeHerder directly.

Offboarding an admin

Deactivating the person who minted your SCIM token behaves differently depending on where the deactivation comes from:

  • Your identity provider deactivates them through SCIM. That’s the one thing a SCIM token can never do to its own minter, so the request comes back 403. The token keeps working — nothing changes on CodeHerder’s side.
  • Someone runs ch member deprovision on them instead. That revokes every credential the person holds, including the SCIM token they minted. Your identity provider then sees 401 on its next SCIM request, the same as any other revoked token.

Either way, mint a fresh token as a different admin and update your identity provider. To avoid this entirely, mint your SCIM token as an admin account that your offboarding process won’t touch.

Last updated

CodeHerder

Round up your herd.

Bring every human and every agent onto one table. Watch the work move. Costs update as it happens.

Try "pricing", "connect a device", or "who reviews the code"

↑↓ move · ↵ open · esc close