Retiring Keys: Offboarding People and Systems
Here is a test worth running in your head right now. An administrator hands in their notice today. By the end of their last day, could you say with confidence that every SSH key they hold has stopped working — on every server, every appliance, every partner system? If the honest answer involves the phrase "we'd disable their account," this article has news for you: on most SSH servers, the obvious way of disabling an account does not stop key logins at all. And if the honest answer is "we'd have to go looking," you have just described the forgotten-key problem — the quiet failure mode of every organization that adopted keys without adopting key retirement.
Keys make this hard for structural reasons: they never expire on their own, the grants live scattered across authorized_keys files on many machines, and nothing in daily operations ever forces a cleanup. People leave, servers get decommissioned, partnerships end — and the lines that trusted them stay, functional, indefinitely. This closing article of our SSH Key Management series turns retirement into a procedure: what revoking a key really means, the offboarding sweep for a departing person, the mirror-image sweeps for retired systems and ended partnerships, and the audit habit that catches whatever slipped through.
Why Keys Outlive Their Owners
Three facts conspire, and knowing them is half the defense. First, a key has no natural end of life — unlike a password subject to policy or a certificate with an expiry date, an authorized key works until a human deletes its line. Second, the grants are decentralized: there is no single switch to throw, because each server account keeps its own list, and some of the lists live on machines you rarely think about — the old utility box, the appliance, the partner's server holding your side's public keys. Third, and most treacherous: the standard account-disabling reflex misses keys. On Linux systems, locking an account with passwd -l only disables its password. Public-key authentication ignores the password field entirely, so a "locked" account still accepts key logins as if nothing happened. To actually close an OpenSSH account to all comers you must expire the account itself (usermod --expiredate 1 alex) — or remove the keys, which is the subject at hand.
Gotcha that fails audits: passwd -l blocks password logins only. A departed user with an authorized key can log in past a locked password indefinitely. Offboarding that ends at "lock the password" has not ended anything — expire the account and sweep the keys.
What "Revoking" a Key Actually Means
There is no central revocation service in plain SSH — no authority to notify, no certificate to invalidate. A key is "revoked" when its public half no longer appears in any list that grants access. That definition has edges worth seeing clearly:
- You cannot destroy the private key remotely. It sits on the leaver's laptop or the retired server's disk, and it will exist as long as that storage does. What you control is the server side: once the public half is gone from every trust list, the private key opens nothing. Revocation is subtraction on your machines, not recall of theirs.
- Removal stops new sessions, not current ones. A session opened before you deleted the line survives until it disconnects. Complete offboarding therefore ends with a check for live sessions under the affected accounts (
who, or terminate the user's processes) — an open shell from yesterday is still an open shell. - Belt-and-braces exists for high-stakes departures. OpenSSH's
RevokedKeysdirective pointssshdat a list of banned public keys; a key on that list is refused even if a strayauthorized_keysline somewhere on that server still contains it — or gets quietly re-added. For ordinary offboarding the sweep suffices, but for a contentious departure, adding the key to a revocation list on your transfer servers closes the re-add loophole.
Everything, notice, depends on being able to answer "which lines, on which machines?" That answer is the key inventory from key rotation and the key inventory — offboarding is the day the inventory either pays for itself or gets built under pressure.
The Offboarding Sweep, Step by Step
Here is the full sequence for a departing person. It assumes the worst helpful case — the inventory is imperfect — so it gathers identifiers first and trusts fingerprints over memory. Run it on (or before) the last day, not during the following sprint.
- Gather the leaver's key identifiers. From the inventory: every fingerprint owned by the person. From their machines, while you still have them: fingerprint any keys in their profile. From your servers' logs: fingerprints their logins actually used. Comments like
alex@workstationhelp you search, but treat them as hints — fingerprints are the ground truth, because anyone can write any comment. - Close the account doors properly. Expire their interactive accounts (not just
passwd -l— see above), and disable their accounts on managed transfer servers. On a Windows SFTP server such as Sysax Multi Server, disabling the account in the server configuration stops its key and password logins together — the one-switch behavior OpenSSH does not give you. - Sweep every SSH endpoint for their keys. On each server, list fingerprints, remove matching lines, and verify by listing again:
# 1. find candidate lines by comment across all accounts (fast triage) grep -n "alex@" /root/.ssh/authorized_keys /home/*/.ssh/authorized_keys 2>/dev/null # 2. confirm by fingerprint - comments can lie, hashes cannot for f in /root/.ssh/authorized_keys /home/*/.ssh/authorized_keys; do [ -f "$f" ] && echo "== $f" && ssh-keygen -lf "$f" done # compare output against the leaver's fingerprint list # 3. remove each matching line, keeping a dated backup of the file cp /home/svc-batch/.ssh/authorized_keys /home/svc-batch/.ssh/authorized_keys.pre-offboard grep -v "alex@workstation" /home/svc-batch/.ssh/authorized_keys.pre-offboard \ > /home/svc-batch/.ssh/authorized_keys chmod 600 /home/svc-batch/.ssh/authorized_keys # 4. verify: the fingerprint must be gone ssh-keygen -lf /home/svc-batch/.ssh/authorized_keys # 5. end any sessions the leaver still has open who | grep alex # then terminate those sessions/processes
- Cover the endpoints the loop cannot see. Relocated
AuthorizedKeysFilepaths (checksshd_config), system and service accounts outside/home, appliances and network gear with SSH access, Windows OpenSSH machines (including the sharedadministrators_authorized_keysfile), managed platforms with their own key stores — and partner-hosted servers, where you cannot run commands and must instead ask: send the partner the fingerprint and request confirmation of its removal. - Watch for the ghost. You cannot test that the leaver's login fails (testing requires their private key, which you rightly do not have), so verification is absence plus monitoring: fingerprints gone from every list, and a log alert on any future authentication attempt using the retired fingerprints. Post-departure attempts are worth knowing about, every time. Our transfer logging and audit series covers building exactly that kind of alert.
- Record it. Mark the keys retired in the inventory, with the sweep date and who ran it. The record is what turns "we think it's handled" into an answer you can give an auditor.
Offboarding a System
Machines leave too — the batch server replaced, the old DMZ host decommissioned — and a retiring machine has key relationships pointing in both directions. The sweep has to look outward as well as inward:
- Outward: the machine was a client. Its private keys granted it access to other systems. Every server where the retired machine's public keys are authorized — your own systems and partners' — needs those lines removed, exactly as for a departed person. This is the direction teams forget, because the machine being switched off feels like the end of the story; the trust lines it leaves behind are the actual story. The inventory's "authorized on" column, kept current, makes this a checklist rather than a hunt.
- Inward: the machine was a server. Its own
authorized_keysfiles die with it, so no sweep needed there — but its host keys are identity, and its clients'known_hostsentries and pinned files should be cleaned up (or migrated deliberately, if a replacement is inheriting the name — the etiquette in host keys and known_hosts). - The corpse: storage holds secrets. The machine's disks contain its private keys in recoverable form. Decommissioning therefore includes wiping or destroying storage per your disposal process — and until that happens, the retired machine's keys should already be dead on every server, which is why the outward sweep comes first, not after the hardware leaves the building.
- The successor gets new keys. The replacement machine generates fresh pairs and earns fresh grants. Copying the old keys onto new hardware carries the old, unaccountable trust forward and quietly doubles the places the private keys have lived — the exact drift the storage rules earlier in this series exist to prevent. Retire the scheduled jobs too: delete or re-point the connection profiles in your automation tool — in Sysax FTP Automation, that means updating or removing the profiles that referenced the retired machine's key — so no scheduler keeps trying a door you sealed.
Offboarding a Partner
When a business relationship ends, the technical unwinding has a natural order — access first, artifacts second, evidence kept:
- Agree the end date in writing, with named technical contacts on both sides, and stop feeding new files into the exchange ahead of it.
- Disable before deleting. On the end date, disable the partner's account on your transfer server — the single switch that stops all authentication at once — then remove their key lines from the account. Because you gave each partner a dedicated account (the pattern from distributing and controlling authorized_keys), this touches nobody else's access.
- Recall your side. Ask the partner to remove your public keys from their systems and confirm, by fingerprint, in writing. You cannot enforce this — which is precisely why the automation keys you gave them were restricted, dedicated pairs rather than anything shared. Retire those pairs in your inventory regardless of their answer.
- Clean the leftovers deliberately: the partner's entries in your pinned
known_hostsfiles, the scheduled jobs and connection profiles that served the exchange, and any allowlist rules (from=patterns, firewall entries) that named their addresses. - Keep the evidence, watch the door. Retain transfer logs and the offboarding record per your retention rules, and alert on any post-termination connection attempts from the partner's addresses or key fingerprints. Ended partnerships are a known source of surprise reconnections — usually a forgotten scheduler on their side, occasionally something that deserves a sharper conversation. The account lifecycle habits that make this step routine live in our transfer authentication series.
Auditing for Orphaned Keys
Even good processes leak, so retirement has a safety net: the orphan audit — a periodic sweep that re-derives "who can log in" from the machines themselves and challenges every line to justify its existence. The mechanics reuse the inventory sweep from the inventory article (fingerprint every authorized_keys, gather last-used fingerprints from the logs); the audit is the comparison:
- Every authorized fingerprint must match an inventory row with a live owner. A key whose owner has left, whose job was retired, or whose purpose nobody can state is an orphan — access with no accountable human behind it.
- Quarantine before deletion, except when it isn't safe to wait. For a dormant mystery key, comment its line out (a leading
#disables a line inauthorized_keys), note the date, and wait one full business cycle — month-end jobs have a way of announcing themselves. Nothing breaks: delete it. For an active mystery key — one the logs show logging in now — do not politely quarantine: treat it as a possible incident, identify the source address, and involve whoever handles security response before deciding anything. - Watch the files between audits. A new line appearing in any
authorized_keysoutside your change process is the most interesting event on a transfer server — it is either process drift or persistence-building, and both deserve immediate attention. File integrity monitoring, a configuration-management diff, or even a scheduled checksum comparison will surface it; the broader monitoring stance belongs to our hardening transfer servers series.
Making Retirement Routine
None of the sweeps above are hard; what fails is remembering to run them. The fix is attachment: bolt key retirement onto events that already have process. The HR offboarding checklist gets a line — "SSH key sweep completed, fingerprints retired, date and operator recorded" — so a departure cannot close without it. The server decommissioning template gets the outward sweep. The contract-termination runbook gets the partner sequence. And the calendar gets the orphan audit at whatever cadence your environment can sustain honestly — a modest interval actually kept beats an ambitious one abandoned.
Done this way, the forgotten-key problem stops being a discovery you make during incidents and becomes a boring, auditable routine — which is the highest compliment operational security can earn. It also closes the loop this series opened: keys beat passwords because they can be granted, restricted, inventoried, and retired one at a time. Retirement is where that promise is kept.
Where This Series Ends
The compressed takeaway: revoking a key means removing its public half from every list that grants access — nothing less counts, and locked passwords do not count at all. Offboard people with the fingerprint-driven sweep; offboard systems by looking outward at the trust they leave behind, not just the hardware; offboard partners access-first with evidence kept; and let a periodic orphan audit catch the leaks. The inventory makes all of it lookup-speed, which is why it is the habit to start this week if you start only one.
If you landed here first, the foundations are back at the start of the series: SSH keys explained for the mental model, and distributing and controlling authorized_keys for the file every sweep in this article edits.
Frequently Asked Questions
Does disabling a user's account stop their SSH key from working?
Can I revoke a key in one place instead of editing every server?
What about our public keys sitting on servers we don't control?
How do I find keys a user added for themselves that were never in our records?
Should I delete a suspicious key immediately or quarantine it first?
From the Sysax team: we build secure file transfer software for Windows — Sysax Multi Server, an FTP, FTPS, SFTP, and HTTPS server, and Sysax FTP Automation for scheduled, scripted transfers. Free trials are on the download page.
