Someone leaves. You disable their account in the identity provider and consider access removed. For most of your tools, it is.
For the rest, nothing happened. They still have a personal access token on the source host, an API key they generated for a script, a local account on the two tools that were never wired to SSO, and a session that will stay valid until it expires on its own. Disabling an identity stops future logins. It does not revoke what was issued before.
This post is the gap between those two things, and what to do about it. For whoever runs offboarding, which is usually a checklist owned by someone who does not have access to half the systems on it.
What SSO actually does
SSO centralises authentication. When a user logs in, they are redirected to the identity provider, which asserts who they are. Disable the account and that assertion stops.
What it does not do:
It does not end existing sessions. An application that issued a session token on Monday will keep honouring it until expiry. If your session lifetime is thirty days, that is your real deprovisioning window, not the moment you clicked disable.
It does not revoke tokens issued through other paths. Personal access tokens, API keys, OAuth refresh tokens, SSH keys, deploy keys, service account credentials. All of these bypass the login flow by design, which is what makes them useful and what makes them survive.
It does not touch applications that are not federated. The tool somebody signed up for with a work email and a password. It has no idea your identity provider exists.
It does not remove data access granted directly. A database user, a cloud IAM principal, a shared credential in a password manager.
So "disabled in the IdP" is a statement about one path. Deprovisioning is about all of them.
Where the leftovers live
Enumerate these rather than assuming, because each one is a separate revocation:
- Personal access tokens on your source host. These typically survive account deactivation and often have broad repository scope. This is the most commonly missed item on the whole list.
- SSH keys and deploy keys, including ones added to individual repositories rather than to the account.
- OAuth refresh tokens, which mint new access tokens without re-authenticating.
- API keys the person generated in any product, especially internal tools built without a lifecycle for them.
- Local accounts in anything not federated, including the vendor consoles used by one team.
- Cloud credentials: access keys, kubeconfig entries, certificates.
- Shared credentials they knew, which cannot be revoked, only rotated.
- Their laptop, holding cached tokens, SSH agents, and browser sessions for everything above.
Why SCIM helps and does not finish the job
SCIM automates provisioning and deprovisioning between your identity provider and applications that support it. When it works, disabling an account in one place removes it everywhere connected, and it is worth setting up for every application that offers it.
Two limits are worth stating plainly.
Support is uneven, and it is usually gated behind an enterprise tier. Your long tail of smaller tools will not have it.
And SCIM removes the account, which does not always revoke credentials that account created. Behaviour differs per application, and the ones where a token outlives the account are exactly the ones you want to know about. Test it rather than trusting the integration: on your next real offboarding, try the departed user's token afterwards.
Cut the session window
The simplest structural improvement is to make sessions shorter, so that "until it expires" is a short sentence.
For anything with production access, a session measured in hours rather than weeks, with SSO re-authentication to renew. The cost is a redirect users mostly do not notice, since they are already signed in to the identity provider. The benefit is that your worst-case deprovisioning delay shrinks from a month to a working day, without any additional process.
Where the application supports it, enable back-channel logout so the identity provider can actively terminate sessions rather than waiting for expiry. Support is patchy, and where it exists it closes the gap almost entirely.
Test the offboarding you already do
Take someone who left three months ago and try their access. Not theoretically: actually attempt it.
# Is a token still valid?
curl -s -o /dev/null -w "%{http_code}\n" \
-H "Authorization: token $FORMER_EMPLOYEE_PAT" https://api.githost.com/user
# Does the SSH key still authenticate?
ssh -i /path/to/their/key -o IdentitiesOnly=yes git@githost.com
# Does the account still exist anywhere?
# enumerate users per system and diff against your current directory
Do this deliberately, with the person's knowledge if they are reachable, and treat every success as a finding. In most organisations the first run of this test finds something, and the finding is usually a personal access token.
Then automate the diff: a scheduled job comparing user lists across your major systems against the identity provider, alerting on anyone present in one and absent from the other. That job catches the next gap without anyone remembering to look.
The checklist item that matters most
Revoke tokens before disabling the account.
The ordering sounds pedantic and it is not. In several products, once an account is disabled or deleted, the administrative interface for listing that user's tokens becomes unavailable, and you are left with credentials you cannot see and cannot revoke without vendor support. Revoke first, disable second.
The concession
Complete deprovisioning is genuinely hard, and the reason is not process discipline: it is that credentials are issued by dozens of systems with no central registry, and no product gives you a single view of everything one human holds. Anyone claiming otherwise has not looked at the long tail.
The realistic target is not perfection. It is that the high-privilege paths are closed on the day, the rest is closed within the week, and a scheduled diff catches what the checklist missed. That is achievable, and it is a great deal better than the common state, which is that nobody has ever verified an offboarding after the fact.
The implication
Disabling an identity is a login control. Deprovisioning is a credential problem, and credentials outlive identities by design.
The question to ask of your own process is not whether you followed the checklist. It is whether anyone has ever tested a former colleague's access and watched it fail.