The access you forgot to revoke: an offboarding runbook for small engineering teams
Somebody leaves. Their manager disables the account in the identity provider, the laptop comes back, and everyone moves on. Six weeks later a CI job fails with a token nobody recognises, or a customer security questionna
Somebody leaves. Their manager disables the account in the identity provider, the laptop comes back, and everyone moves on. Six weeks later a CI job fails with a token nobody recognises, or a customer security questionnaire asks how long it takes you to revoke access and nobody can answer with a number.
Offboarding is one of the few security controls where a small team can genuinely match a large one, because the whole thing is a list and a habit. The reason it goes wrong is not sophistication. It is that access was granted in eleven places over two years and revoked in one.
Here is the version I would actually run on a team of ten to fifty engineers.
1. Build the list while nobody is leaving
The worst time to discover where access lives is the afternoon somebody resigns. Write the list first, when it is a boring exercise instead of an urgent one.
Walk your own stack and write down every system that can grant a human access to code, data, infrastructure or money:
- Identity provider or directory: Entra ID, Okta, Google Workspace, JumpCloud.
- Cloud: AWS, Azure, GCP, including any account with its own local users rather than federated ones.
- Source control and package registries: GitHub, GitLab, npm, PyPI, container registries.
- CI and deployment: the pipeline itself, plus anywhere a secret is stored for it.
- Data: production databases, warehouses, BI tools, object storage with its own signed URLs.
- Vendors with their own logins: monitoring, error tracking, feature flags, payment processors, support desks.
- Collaboration: chat, docs, project tracking, design tools, shared drives.
- Access to the perimeter: VPN, bastion hosts, jump boxes, remote support tools.
- The password manager, which is the system that quietly grants access to all of the above.
Two columns are enough: who administers it, and whether it federates through the identity provider or holds its own local accounts. That second column is the one that matters, and it is the one most teams have never filled in.
2. The identity provider is the first move, not the whole move
Suspending the directory account is the highest value action available in the first minute, so do it first. Then treat it as incomplete, because federation is almost never total. The systems that were signed up for before single sign on existed, the ones on a plan that does not include SAML, and the one somebody integrated in a hurry are all still holding local credentials.
There is also a difference between a credential and a session. Disabling an account stops new sign ins. It does not always end the sessions already issued. Where the system offers it, revoke active sessions and refresh tokens explicitly rather than assuming the account change propagated.
3. Tokens outlive people
This is where the real residual access sits, and it is invisible from the identity provider.
Long lived credentials that a person created, but which are not tied to that person's login lifecycle:
- Personal access tokens in source control, often used in scripts that other people now depend on.
- SSH keys registered against the account, and any key pasted into an authorized_keys file on a host.
- Cloud access key pairs on a local IAM user.
- API keys issued from vendor dashboards, which usually keep working after the creator is deactivated.
- OAuth application grants and installed integrations approved with their account.
- Webhook secrets and signing keys they generated.
Enumerate these per departure, not once a year. And when you find a token that something in production depends on, do not simply delete it and hope. Reissue it against a service identity that belongs to the system rather than to a person, then delete the old one. Doing that at offboarding time is how the problem stops recurring.
4. Shared credentials are the reason offboarding fails
If two people know a password, offboarding one of them does not revoke it. The account still works, the login looks legitimate, and no audit trail will tell you who used it.
Shared logins collect in predictable places: the domain registrar, the DNS provider, the payment processor, the app store accounts, the ISP or hosting portal, the social media accounts, and anything with a per seat price that somebody decided to avoid. When a departure exposes one, rotate it and record who holds it now.
Rotate every shared secret the leaver could read. That includes vault entries their group had access to, even where you have no evidence they opened them. Access is the thing being revoked, not usage.
5. Handle the second factor deliberately
MFA is part of the credential set. Remove the registered authenticator, hardware key and recovery codes for the person who left, and check whether their phone number is still the recovery route on any account. A password reset flow that texts a former employee is a live path back in, and it survives every other step in this list.
While you are there, look at whether any break glass or emergency account has their contact details attached.
6. Devices, and the data already on them
Returning a laptop is not the same as clearing it. Confirm the device is unenrolled or wiped through your management tooling, not by inspection. Then think about copies: personal cloud storage syncing a work folder, a local database dump in a downloads directory, an exported spreadsheet, a repository cloned to a personal machine.
You cannot revoke a copy that already left. You can notice that it happened and decide what it means, which is a different and more honest position than assuming it did not.
7. Write it down the same way every time
Use one checklist per departure, with a timestamp against each item and the name of the person who did it. Store it somewhere that is not the leaver's own drive.
This is the part that feels like bureaucracy and is actually the part that pays. It gives you a real answer to how long revocation takes, it makes the gap visible when one system is always skipped, and it means that when a customer or an auditor asks for evidence you are retrieving a record rather than reconstructing a memory. A control you perform but cannot show is treated, by anyone assessing you from outside, as a control you do not have.
Keep the same checklist for contractors, and for anyone who changes role internally. Internal moves are worse than departures, because nothing prompts anybody to take the old access away.
8. Test it on yourself
Pick a quiet week and offboard a volunteer who is not leaving. Run the checklist against a real account and then try, honestly, to get back in: old token, saved session, shared login, recovery flow, VPN profile. You will find two or three things the list missed. Add them and run it again next quarter.
That drill takes an afternoon and it is the only way to know whether the runbook describes your environment or the environment you meant to build. Baseline control sets, if you want a reference for what to cover, treat access provisioning and revocation as one control with two halves: https://irmcon.com/products/cybersecurity-baseline-assessment/
The bit where I say who I am
I work at IRM Consulting & Advisory, where I do virtual and fractional CISO work with small businesses, startups and SaaS companies in Canada and the United States, so offboarding gaps are something I get paid to go looking for. If you want the version of this that comes with someone accountable for it, that is IRM's virtual CISO practice. Flagging the affiliation so you can weigh the advice accordingly.
One question, because I am curious how other teams handle it: when a departure exposes a token that production depends on, do you reissue it to a service identity there and then, or do you note it and move on? The second answer is more common than anyone admits.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.