Contractor offboarding AI access: what to do today
Contractor offboarding AI access runs at two speeds. Grant revocation and member removal land on the next call. Role and restriction changes propagate more slowly, about two minutes.
The last day is a calendar event, the access is not
A contractor finishes on a Friday. HR closes the ticket, someone disables the laptop login, and the assumption is that the story ends there. If that contractor pointed Claude, ChatGPT or Cursor at your organization's MCP endpoint, contractor offboarding AI access is a separate question with a separate answer. It is not whether you turned off their SSO account. It is whether the next tool call that client makes gets data back.
That call does not come from a machine you control. It comes from a desktop client signed in with a bearer token (the standard OAuth 2.0 bearer credential defined in RFC 6750), running against one org-wide MCP address. So the thing you need to be exact about is what stops that token, and how fast. Below is how this works in Elaichi's MCP access layer specifically. The mechanics are product-specific, but the underlying pattern (instant credential revocation vs. cached policy propagation) is common across OAuth-based systems and worth understanding even if you're running something else.
What a contractor's AI client is actually holding
Three terms matter here, and they are not interchangeable:
- Grant. The fact that this identity is allowed to call the endpoint at all. Binary: exists or doesn't.
- Role. The bundle of permissions the identity inherits (Member, Guest, Admin, Auditor).
- Restriction. A rule layered on top of a role or a specific user that removes access to a connector or tool.
The client holds a bearer token issued when the contractor signed in to the endpoint through OAuth. Every subsequent call on POST /mcp is authorized against that bearer.
What the client does not hold is a credential for any of your SaaS accounts. There are no embedded tokens in the endpoint URL and no per-user MCP address, because the endpoint is one address for the whole organization and the grant is what varies from person to person. That matters on a last day for a practical reason: there is no per-user URL to go find, no list of minted servers to reconcile, and nothing to rotate. There is one grant, attached to one identity, and it either resolves or it does not. The contrast with an address that is itself the credential is exactly what makes a leaver tractable.
It also means the contractor's Cursor install and their Claude desktop client are not two problems. They are the same grant seen twice. Revoking it once ends both sessions on their next call, not eventually, immediately.
Contractor offboarding AI access runs at two speeds
This is the distinction that decides what you do at 5pm on the last day.
Effective on the next call: grant revocation, member removal, member suspension. removing or suspending a member revokes every live grant in the same transaction as the membership change Mechanically, this is possible because the revocation flag lives in the organization store and is re-read on every single call. There is no cache in front of it, so nothing needs to expire before the change takes effect. The next call from any client, in any office, is refused.
Effective in about two minutes: role changes and restriction changes. Both resolve through a 60-second cache plus edge propagation, on every surface: MCP, console, and REST alike. Moving a contractor from Member to Guest, or adding a block rule that takes a connector away from their role, is correct and it is also not instant.
| Action | Speed | Mechanism | Use when |
|---|---|---|---|
| Suspend or remove member | Next call | No cache; flag read live from org store | Contractor is leaving now |
| Revoke a specific grant | Next call | Same live-read path as removal | You need one integration cut without touching the account |
| Narrow a role | Up to about two minutes (60s cache + edge propagation) | Cached policy, refreshed on TTL expiry | Scope is shrinking but the person is staying |
| Add a restriction rule | Up to about two minutes | Same cached path as role changes | Blocking one connector or tool org-wide or per-role |
The operational rule follows directly. If you need access stopped now, suspend or remove the member. Do not narrow the role and walk away from the screen. Narrowing a role is the right move when a contractor's scope is shrinking and they are staying; it is the wrong move when they are leaving in ten minutes.
One more detail worth knowing before you reach for a restriction: restriction targets are role or user only; the organization default is the absence of a rule, which means allow everything. A user-scoped rule replaces the role rule for that person rather than layering on top of it, blocks beat allows within the winning layer, and the allowlist stage engages on the presence of an allow rule, not its contents, so an allow rule that names nothing denies everything. Get this backwards and you'll conclude a contractor is blocked when they aren't, or blocked entirely when you meant to restrict one tool.
The preflight that will refuse your removal
Removal is not a single click that always succeeds, and that is deliberate. Offboarding runs a preflight check first, and it evaluates three distinct cases:
- Personal connections referenced by a shared toolbox entry. These must be resolved before removal proceeds: transferred to the organization, a team, or another member, or deleted. If you do neither, the removal is refused outright. Personal connections nothing references are cleaned up automatically.
- Private connections. These have no transfer option, ever. A credential scoped to one person's identity does not become someone else's because that person left. The outcome is deletion, full stop. Whatever workflow depended on it needs a different account behind it going forward.
- Delegated toolbox entries. These surface as a non-blocking warning rather than stopping removal. The fix is re-pinning the entry to a live connection, not a decision about a credential.
This preflight is why removal is not instant even though grant revocation is. Plan for it to take longer than a single click. The exact time depends on how many personal and private connections the contractor accumulated, not on a fixed number. This is the step that gets skipped when someone tries to do the removal from a phone between meetings, and skipping it is how orphaned references pile up.
Same day: the order to work in
- Suspend or remove the member. This is the fast path and it should be first. Live grants are revoked in the same transaction, and the next call is refused. Do this before anything else, including the preflight cleanup below.
- Work the preflight. Transfer the referenced personal connections to the organization, a team, or the person picking up the work. Delete the private ones. Re-pin any delegated toolbox entries the warning named.
- Revoke at the source anything the contractor authorized personally. Connector credentials do not live in Elaichi. A separate credential service holds per-account secrets encrypted at rest and owns refresh. Deleting a connection removes your side of it. If the contractor also holds that API key in their own password manager, the vendor's admin console is the only place that fact gets fixed. This is the same limitation every third-party OAuth integration has, not something specific to this endpoint.
- If you are narrowing rather than removing (because the contractor is coming back part-time next quarter), allow about two minutes and then verify against the console rather than assuming the change is live.
The next morning: read the trail, not your memory
The audit trail answers the question you will actually be asked, which is not "did we remove them" but "what did their assistant touch in the last two weeks."
Every call is logged with the calling identity, the tool invoked, and which connector account it resolved against, including which of two same-vendor accounts was hit when more than one is connected. one entry per tool-call attempt, succeeded or failed When two Notion workspaces are connected, that distinction is the whole answer. Argument names and counts are logged. Argument values never are. This is a deliberate redaction boundary, not an omission, and it means the audit log cannot itself become the leak.
actor_kind is a recorded field rather than something inferred later from a user agent, and ai_assistant is one of its values. So filtering the last fortnight to what an assistant did, as opposed to what a person did in a browser, is a filter and not a forensic exercise.
Two practical notes. The trail is eventually consistent, so a row from late the previous evening may take a moment to appear; if the morning review runs at 8am on activity from 11pm, check again rather than concluding nothing happened. And a departed member renders as "Former member" instead of vanishing from the records, which is the behavior you want when the review happens three months after the contract ended.
If the person doing the review is a compliance reviewer rather than an operator, give them an Auditor seat. It is read-only, it is not billable, and it lacks tool:execute, so the MCP endpoint advertises nothing to them at all. They see the log, not the tools.
What revocation does not reach
Be honest with whoever signs off on this, because the gap is real and it is the shadow-AI part of the problem.
Revoking the grant stops future calls. It does not retrieve what already left. If the contractor read a customer list through a governed tool call in week three and pasted it into a personal assistant account, the audit trail records the read and nothing about the paste. This is not a gap specific to this product. No access-control layer, MCP-based or otherwise, can see what happens to data after it crosses the trust boundary into a model's context window. The control you actually have is upstream of that: the record of what was reachable and when, plus restrictions that keep the reachable set small in the first place. A tool blocked for a role is never advertised over MCP to a member of that role, so the model does not know it exists to try. This is a meaningfully different guarantee than "the model was told not to use it."
The endpoint also has no prompt-injection gate and cannot have one, because an MCP server never sees a user prompt. It sees tool calls with structured arguments, not the conversation that produced them. What does hold on every call: RBAC per operation, a forbidden classification that no OAuth scope can override, output redaction, scope limits, and the audit record. That is the actual perimeter. Anything sold as catching prompt injection at the MCP layer is describing a control that architecturally cannot exist there.
When you do not need any of this
If your contractor logged into one SaaS application with their own account and never connected an AI client to anything, offboarding is that vendor's admin console plus your identity provider. Standard SCIM deprovisioning (RFC 7644) already kills the SSO session immediately; nothing here improves on that, and a control plane bought for one contractor is a control plane you will not have configured properly when it matters.
If your contractor used a shared login that three other people also use, removal changes nothing, and adding governance on top of a shared credential just moves the fiction one layer up. The fix is a per-person account at the vendor. Do that first. No MCP-layer control substitutes for identity that doesn't map 1:1 to a person.
The case for a single governed endpoint starts when the contractors are plural, the connected accounts are plural, and nobody can currently say which of the 450+ apps in your stack an assistant reached last Tuesday.
For how roles, restrictions, and seat classes fit together before a leaver ever appears, see the access model in the product overview. The security page covers residency, customer-managed keys, and SCIM deprovisioning in more detail.