Article image
Digital Housekeeping: Revoking SSH Keys and Admin Accounts After a Client Project Ends
The project is over. The final invoice is paid, the launch party is a wrap, and your agency team has successfully deployed a beautiful, high-performing web application. High-fives all around. Your team immediately pivots to the next client, archiving the Slack channel and moving on.
But lurking in the background of that completed project is a massive, silent liability: a web of active admin accounts, API tokens, and SSH keys that your agency still holds.
Picture the scenario six months later: the client’s server is breached, and a threat actor installs a cryptominer that drains the client’s AWS budget by tens of thousands of dollars. When the forensic audit concludes, the entry point is discovered — an orphaned, compromised SSH key belonging to one of your former freelance developers. Because your agency failed to revoke developer access and clean up its digital footprint, you are now squarely in the crosshairs for breach of contract, negligence, and potentially catastrophic financial damages.
This scenario isn’t far-fetched. It’s simply what happens when the lifecycle of access isn’t managed with the same rigor as the lifecycle of a domain or a hosting plan. In 2026, agency offboarding security is no longer a “nice-to-have” administrative chore; it is a critical operational mandate. Asset tracking isn’t just about making sure domains and SSL certificates renew on time — it is equally about tracking, and terminating, access. If you do not formally remove your agency from client hosting and sever all digital ties when a contract ends, you are carrying uncompensated risk.
This guide breaks down the core vulnerabilities agencies leave behind and provides an actionable checklist to manage client SSH keys and admin accounts, grounded in current breach data rather than guesswork.
- The Liability of Lingering Access The instinct to treat SSH keys and admin credentials as the primary risk here is reasonable, but the 2026 threat data complicates the picture. In Verizon’s 2026 Data Breach Investigations Report — its 19th annual edition — vulnerability exploitation overtook credential abuse as the leading single initial access vector for the first time in the report’s history, accounting for 31% of breaches versus 13% for credential abuse alone. That’s a meaningful shift from the year before, when credential abuse topped the list at 22%.
That doesn’t mean lingering credentials are suddenly safe to ignore. Counted across the entire attack chain rather than just the initial point of entry, credential abuse still appears in 39% of breaches — more than any other single factor — and stolen or reused credentials remain the top action in basic web application attacks. The more relevant number for agencies specifically is this: third-party involvement in breaches jumped to 48% in the 2026 DBIR, up from 30% the year before, a 60% year-over-year increase. An agency that still holds SSH keys, admin logins, or API tokens to a former client’s infrastructure is that third party.
Most SSH-related security failures trace back to poor key hygiene rather than sophisticated exploits. The standard agency workflow often looks like this: a new client hands over server credentials via Slack, a developer generates an SSH key on the spot, pastes it into the server’s authorized_keys file, and gets to work. When the project concludes, the key is simply forgotten. Multiply that across dozens of client engagements and departed freelancers, and you have an expanding, undocumented attack surface.
The transition out of a client’s environment is intricate, and if your offboarding procedure doesn’t guarantee that departed developers are entirely excluded from the infrastructure, your environment contains a live vulnerability. Former employees or agency partners who retain access can delete files, mismanage servers, alter data, or misappropriate intellectual property — and IBM’s 2025 Cost of a Data Breach Report found that breaches involving a malicious insider are the single costliest category to resolve, averaging $4.92 million and taking roughly 260 days to identify and contain, well above the 241-day global average across all breach types. Insider-driven incidents are expensive precisely because the access looks legitimate; there’s no perimeter to breach when the “attacker” is using a key your own agency issued.
The “Who Owns the Cleanup?” Dilemma
Clients often assume that because they own the server, they are responsible for security. However, clients frequently lack the technical expertise to audit Linux servers or Identity and Access Management (IAM) roles. If an agency provisions access for itself to do the work, the legal and ethical burden falls on the agency to de-provision that access upon exit.
Relying solely on the client to terminate SSO or VPN access is insufficient. To avoid becoming part of that growing 48% third-party-breach statistic, agencies need a methodical approach to revoke their own access across all client systems — not a hope that the client will eventually notice and handle it.
- Core Risk Vectors for Agencies Before the checklist, it helps to understand exactly where an agency leaves digital footprints. The modern web stack is fragmented, meaning access is scattered across multiple layers.
A. The Infrastructure Layer (SSH & Cloud IAM)
SSH keys — the primary method developers use to push code, manage databases, and configure Linux servers.
Cloud provider IAM roles (AWS, GCP, Azure) granted to your agency for provisioning storage, managing DNS, or deploying serverless functions.
Infrastructure-as-Code scripts (Terraform, CloudFormation) that may contain embedded credentials or implicit permissions tied to your agency’s identity.
B. The Application Layer (CMS & Control Panels)
CMS super-admin accounts (WordPress, Shopify, Magento, Drupal) used by your content and development teams.
Hosting panel access — cPanel, Plesk, or collaborator seats on managed hosts like Kinsta or WP Engine.
C. The Integration Layer (APIs & Secrets)
API keys for services like Stripe, SendGrid, Twilio, or Algolia, potentially stored in your agency’s internal password manager or secrets vault.
CI/CD pipelines (GitHub Actions, GitLab runners) holding deployment keys tied to the client’s production environment.
This third layer deserves particular attention. GitGuardian’s 2026 State of Secrets Sprawl report found that 28.65 million new hardcoded secrets were exposed on public GitHub in 2025 alone — a 34% year-over-year increase and the largest single-year jump the company has recorded. More striking for offboarding purposes: 64% of secrets leaked in 2022 were still valid and exploitable four years later. Credentials don’t expire on their own. If your agency’s offboarding process doesn’t explicitly rotate or revoke a client’s API keys, there’s no reason to assume time alone will neutralize the risk.
- The Complete Agency Offboarding Security Checklist Treat client offboarding with the same rigor as terminating an internal employee. Documenting each step matters — in the event of a subsequent incident, it lets your organization demonstrate that reasonable measures were taken, which offers meaningful legal protection.
Conduct a full access audit. Before removing anything, maintain an up-to-date inventory of who at your agency had access to which client resources, keys, credentials, and certificates.
Remove all admin roles. Proactively strip your agency’s admin roles from the client’s systems rather than simply disabling accounts. A disabled account with role assignments still intact is a risk if it’s ever accidentally re-enabled.
Revoke access at the identity provider. If your agency was integrated into the client’s SSO (Entra ID, Okta, Google Workspace), request formal deactivation rather than suspension. In identity platforms like Okta, deactivating a user permanently strips all app and group assignments — the correct action when someone is leaving for good. Suspending a user, by contrast, is designed to be temporary and reversible: it preserves those app and group memberships specifically so they can be restored later, which is appropriate for a leave of absence, not an offboarding.
Rotate all shared admin credentials. Don’t assume a developer never memorized a break-glass password or saved one in a personal vault. Rotate any shared admin credentials, emergency-access accounts, or root passwords your team had access to.
Audit secrets and API keys. For any senior engineers who managed CI/CD, review secrets-management tools (like AWS Secrets Manager) for keys scoped to your agency, and have the client rotate those keys so your local copies become useless.
Review automated jobs. Check for scheduled cron tasks or automation scripts that authenticate as your agency or reference your credentials — these keep running silently after an account is disabled if credentials are hardcoded rather than pulled from a live secrets store.
Formalize the exit in writing. Send the client a written offboarding confirmation detailing which accounts were removed, which keys were rotated, and confirming your agency no longer holds access.
The scale of the problem this checklist addresses isn’t hypothetical. Oomnitza’s State of Offboarding Process Automation research, conducted with YouGov, found that 42% of surveyed organizations had experienced unauthorized access to SaaS applications or cloud resources stemming from incomplete deprovisioning, and 27% reported losing track of more than 10% of their technology assets during offboarding. A separate industry survey by Beyond Identity found that 83% of departing employees said they still had access to a former employer’s digital assets after leaving, and more than half admitted to using that lingering access in ways that harmed their former employer. Agencies aren’t exempt from these dynamics — if anything, the multi-client, multi-freelancer structure of agency work makes the problem worse, not better.
- Deep Dive: How to Properly Manage Client SSH Keys Of all the vulnerabilities discussed here, unmanaged SSH keys are among the most dangerous, because they provide command-line-level access to a server that bypasses standard web firewalls and CMS login screens entirely.
Best Practices for SSH Hygiene During a Project
Never share keys. A private key should never leave the hands of the individual it belongs to. If a key is shared, you have to assume anyone who received it can impersonate that developer. Tie SSH keys to individuals, not a shared agency account.
Use Ed25519, not legacy RSA. Ed25519 has been OpenSSH’s recommended key type for years and is now the default type generated by current versions of ssh-keygen. It produces a much smaller key for equivalent security, signs and verifies faster than RSA, and — because it uses deterministic signing — isn’t vulnerable to the kind of weak-randomness failures that can compromise RSA or ECDSA keys during signing. RSA at 3072 or 4096 bits remains a reasonable fallback only when connecting to legacy systems that don’t yet support Ed25519.
One clarification worth making here: SSH key-based authentication and SSH password-based authentication have different failure modes. A poorly protected private key (no passphrase) is a risk if the key file itself is ever stolen off a laptop — not because it can be “guessed” the way a weak password can. Password-based SSH login, if it’s enabled at all, is the version that’s actually vulnerable to brute-force and credential-stuffing attacks. The practical takeaway is the same either way: disable password authentication on the server, require key-based auth, and always protect private keys with a strong passphrase.
Use per-client key pairs. Freelancers and agencies should generate a separate key pair per client, with local-only private key storage. A compromised developer laptop should expose one client’s server, not your entire roster of accounts.
Harden the basics. Change the default SSH port to cut down on automated discovery, and disable SSH root login entirely so every session is tied to a named, auditable account.
Revoking SSH Keys at Project End
When it’s time to remove your agency from client hosting, there are two standard methods for SSH revocation.
Method 1: The authorized_keys cleanup (standard). Log into the client server, navigate to ~/.ssh/authorized_keys for the relevant users, and delete the public keys belonging to your agency’s developers.
Warning: this requires meticulous record-keeping. If you can’t positively identify which key belongs to which developer, you risk deleting the client’s own key and locking them out of their own server.
Method 2: Using a revoked-keys file (more robust, recommended for larger engagements). OpenSSH’s sshd supports a RevokedKeys directive in sshd_config that explicitly blocklists specific keys across the entire server, independent of whatever is sitting in individual authorized_keys files:
RevokedKeys /etc/ssh/sshd_revoked_keys
You then add the agency’s public keys to that file, one per line (or generate a proper OpenSSH Key Revocation List with ssh-keygen). When a revoked key attempts to authenticate, the server refuses it and logs an entry describing the key as found in the revoked-keys file. On the developer’s side, the private key simply stops working and falls through to whatever other authentication method is configured. One important operational note: if the file referenced by RevokedKeys doesn’t exist or isn’t readable, sshd will refuse all public-key authentication for every user — so the file needs to exist (even as an empty placeholder) before you point the config at it.
- Where InstaRenewal Fits Into This Process Tracking access across dozens of concurrent client projects with spreadsheets alone is a recipe for exactly the kind of orphaned-key scenario described at the top of this article. This is where a centralized renewal and asset-tracking system earns its keep — with a clear-eyed sense of what it should and shouldn’t be relied on for.
InstaRenewal is built for renewal tracking and asset ownership mapping: keeping a running, per-client inventory of domains, SSL certificates, hosting accounts, and plugin licenses, along with who on your team owns each one. Used well during offboarding, that inventory becomes the checklist backbone your team works from — because you can’t revoke access you never wrote down in the first place. When a project is marked “Completed,” that existing asset map is what tells your ops lead which hosting panels, domain registrars, and CMS installs to actually go touch.
What InstaRenewal is not is a credential vault or a security-scanning tool. It won’t store your developers’ SSH public keys, hold live IAM role assignments, or generate a compliance audit trail of exactly when a given credential was rotated — that work still has to happen in your identity provider, your secrets manager, and the client’s own hosting or cloud console, using the tools built for that job (password managers, SSO admin panels, sshd_config, cloud IAM consoles). Treating a renewal tracker as if it were also your credential-revocation system of record is its own kind of risk; the two need to work together, with InstaRenewal supplying the “what exists and who owns it” layer and your security tooling handling the actual revocation and audit trail.
- Conclusion: Leave No Trace In the agency world, your reputation is built on the code you write and the designs you ship. But your legal and financial security is built on how cleanly you can walk away when the job is done.
The data backs this up plainly: third-party involvement in breaches is climbing fast, malicious-insider incidents are the costliest category to resolve, and the majority of leaked credentials studied by researchers are still valid years later. None of that improves on its own — it only improves when someone actually does the work of revoking access. By implementing strict SSH key hygiene, following a real IAM offboarding checklist, and keeping an accurate asset inventory through tools like InstaRenewal, you make sure your agency’s legacy is defined by the work you shipped — not by a breach you accidentally left the door open for.
Sources
Verizon, 2026 Data Breach Investigations Report
IBM, Cost of a Data Breach Report 2025
GitGuardian, The State of Secrets Sprawl 2026
Oomnitza / YouGov, State of Offboarding Process Automation Report
Wing Security, SaaS offboarding and insider-risk research
Beyond Identity, Former Employees Admit to Using Continued Account Access to Harm Previous Employers
Okta, end-user lifecycle state documentation (suspend vs. deactivate)
OpenSSH, sshd_config(5) manual — RevokedKeys directive
OpenSSH project documentation on Ed25519 key support and defaults
답글 남기기