Offboard someone who leaves
What you get: when your identity provider deactivates a person, Ambit stops their access within seconds. It deletes their personal API keys, ends their console sessions, blocks tokens that are still valid and revokes their connected apps at the vendor. It keeps a record of what it did.
Before you start
You need:
-
the cluster from the Quick start with the people of Different models for different teams. This guide offboards Dan, who is in
engineering; -
the model rule
engineering-modelsand the tool ruleengineering-time(Give an agent tools and apps), so that Dan has something to lose; -
no budgets that block Dan. If you did Set spending limits, delete its budgets first and wait a minute:
kubectl -n ambit-system delete budgets.ambitproject.dev engineering sales -
two personal API keys for Dan, made in the console as in Connect Claude Code and Cursor: one with the scope LLM, in
DAN_KEY, and one with the scope MCP, inDAN_MCP_KEY. Keep Dan signed in to the console in a browser. Alice also needs a key, inALICE_KEY.
In real use, your identity provider (Okta, Entra ID) sends the SCIM requests. In this guide you send them yourself with curl, so you can see each step.
1. Find the SCIM address and token
In the console, open Settings and then Offboarding. The page shows the base URL of the SCIM endpoint and a bearer token behind Show token. In your identity provider, add a SCIM app with this URL and token, and turn on Deactivate users.
For this guide, read the token from the cluster. The command puts it in a variable without printing it:
SCIM=http://console.localtest.me:8080/scim/v2
SCIM_TOKEN=$(kubectl -n ambit-system get secret ambit-console-keys -o jsonpath='{.data.scim-token}' | base64 -d)
The endpoint refuses requests without the token:
curl -s -o /dev/null -w 'HTTP %{http_code}\n' $SCIM/Users
HTTP 401
2. Provision Dan
Your identity provider creates a user in Ambit before it can deactivate one. Create Dan the way the provider does:
curl -s -X POST $SCIM/Users -H "Authorization: Bearer $SCIM_TOKEN" -H 'Content-Type: application/scim+json' \
-d '{"schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"userName":"dan@acme.test","active":true,"emails":[{"value":"dan@acme.test","primary":true}]}' | tee dan-scim.json
ID=$(sed -E 's/.*"id":"([^"]+)".*/\1/' dan-scim.json)
The answer has "active":true and an id. The address in userName and emails must be the address Dan signs in with.
Check that Dan has access
Before you offboard Dan, check that his keys and his session work. The function mcp is the one from Give an agent tools and apps.
curl -s -o /dev/null -w 'Dan LLM key: HTTP %{http_code}\n' http://llm.localtest.me:8080/v1/chat/completions \
-H "Authorization: Bearer $DAN_KEY" -H 'Content-Type: application/json' \
-d '{"model":"nvidia/nemotron-3-super-120b-a12b:free","messages":[{"role":"user","content":"hi"}]}'
mcp "$DAN_MCP_KEY" '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
The first command prints Dan LLM key: HTTP 200. The second lists the tool time_get_current_time. In the console, Settings and Keys list Dan's keys as Active, and Dan's browser is signed in.
3. Deactivate Dan
curl -s -w '\nHTTP %{http_code}\n' -X PATCH $SCIM/Users/$ID -H "Authorization: Bearer $SCIM_TOKEN" -H 'Content-Type: application/scim+json' \
-d '{"schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"],"Operations":[{"op":"Replace","path":"active","value":"False"}]}'
The answer has "active":false and ends with HTTP 200. Deleting the user in the identity provider (DELETE $SCIM/Users/$ID) has the same effect.
Check it works
Run the same checks as before. The gateway needs a few seconds to learn about the block, so repeat a command if it still shows 200.
curl -s -o /dev/null -w 'Dan LLM key: HTTP %{http_code}\n' http://llm.localtest.me:8080/v1/chat/completions \
-H "Authorization: Bearer $DAN_KEY" -H 'Content-Type: application/json' \
-d '{"model":"nvidia/nemotron-3-super-120b-a12b:free","messages":[{"role":"user","content":"hi"}]}'
mcp "$DAN_MCP_KEY" '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
Dan LLM key: HTTP 403
authorization failed
HTTP 403
Dan's console session ended. Reload the console in his browser, and it shows the sign-in page. The console API answers 401 for his session cookie. His keys are deleted, not only blocked: as an admin, open Settings and Keys and see that Dan has none. Alice is not affected:
curl -s -o /dev/null -w 'Alice LLM key: HTTP %{http_code}\n' http://llm.localtest.me:8080/v1/chat/completions \
-H "Authorization: Bearer $ALICE_KEY" -H 'Content-Type: application/json' \
-d '{"model":"nvidia/nemotron-3-super-120b-a12b:free","messages":[{"role":"user","content":"hi"}]}'
Alice LLM key: HTTP 200
The record
Ambit keeps a record of each offboarding. As an admin, open Settings and Offboarding, or read the same data from the console API. The record for Dan looks like this. Your times and counts are different:
{
"email": "dan@acme.test",
"at": "2026-10-13T08:20:07.193204178Z",
"trigger": "scim PATCH active=false",
"grants": [],
"sessionsEnded": 2,
"gatewayBlocked": true,
"keysDeleted": 3,
"completeSuccess": true
}
sessionsEnded: the console sessions that were ended.gatewayBlocked: the gateways now refuse the person's email, even for a token that has not expired.keysDeleted: the personal API keys that were deleted.grants: one line for each connected app, withrevokedAtProviderset totruewhen the vendor confirmed the revocation. The list is empty here because Dan connected no app. A revocation that a vendor does not confirm shows its error and marks the recordcompleteSuccess: false. Which vendors truly revoke is in Offboarding.
If the person comes back
Reactivating the user in the identity provider lifts the block. The old keys and app grants stay deleted. The person signs in and creates new keys.
While a user is deactivated, the console refuses to make keys for that person with this person is offboarded.
Related
- Offboarding: which vendors truly revoke a person's grants.
- Personal API keys: how keys follow the identity, and what offboarding does to them.
- Give an agent tools and apps: connected apps.