Skip to content
Offboarding14 min read

What to rotate when a developer leaves

When a developer leaves, access ends but the secrets they saw keep working. The order to work in, what to rotate first, and how to reissue without downtime.

Short answer

Cut their access first, then find out exactly which secrets they could read, then reissue those values at each provider, production first, using overlap windows to avoid downtime. Removing an account or rotating a vault's keys protects only future values: what they already saw keeps working until you replace it.

On this page

Rotate every secret the developer could read, and do it in a fixed order: cut their access first, then find out exactly what they could read, then reissue those values at each provider, production and money-moving keys first. Removing the account stops new access. It does nothing to the API keys, database passwords and tokens they already saw, which keep working until someone replaces them at the provider. This guide gives the order, a priority list for what to reissue, how to do it without downtime, and how to handle the keys of the vault itself.

Access ends, knowledge doesn't

Two different things happen when someone leaves, and they are easy to blur.

Access is what systems let a person do from now on: sign in to GitHub, read the vault, assume a cloud role. You end it by removing accounts and revoking tokens, and it ends at once.

Knowledge is what the person already has: the values of STRIPE_SECRET_KEY and DATABASE_URL that were on their laptop, in their terminal history, in a chat message they can still scroll to. No system can revoke that. The only fix is to make those values useless, by issuing new ones at the provider and retiring the old ones.

The words matter here too. Rotating a key means changing an encryption key, such as the key a vault uses for an environment. Reissuing a value means getting a new credential from the service that issued it: a new Stripe key, a new AWS access key, a new database password. Rotation protects the vault's future versions. Reissue protects your systems. An offboarding needs both, and only the second one stops a value they saw from working.

The order to work in

Order matters because each step depends on the one before. Reissue before you have cut access, and the person could read the new values too. Reissue before you know what they saw, and you either miss something or replace everything.

Example. Kiteline is a fictional company.
  1. Cut access everywhere at once: identity provider, Git host, cloud consoles, CI, the vault, chat.
  2. Revoke what they could carry away: tokens they created, share links, invitations, machine enrollment codes, SSH and deploy keys.
  3. Work out which secrets they could read, and which versions of them.
  4. Reissue those values at their providers, highest impact first, using overlap windows where the provider has one.
  5. Make sure the vault's own keys can't open new versions for them.
  6. Record what you did, for your security team and for the next audit.

The rest of the guide goes through each step. If the departure is planned, you can prepare steps 2 to 4 before the last day and run the whole sequence in one sitting.

Step 1: cut access everywhere

Do this in one sitting, in the hour the person leaves or is told. A list kept in advance makes it fast:

  • Identity provider or SSO, if you have one. Suspending the account there ends sign-in to every app behind it.
  • Git host. Removing a member from a GitHub organization ends their access to its private repositories. GitHub's documentation on removing a member adds two points worth knowing: removed members lose access to private forks of your private repositories, but they may still have local copies, and it is up to you to make sure confidential information on them is deleted.
  • Cloud consoles that aren't behind SSO, including any IAM users with their own access keys.
  • CI systems, including personal tokens they used to trigger pipelines.
  • The vault. End their sessions and remove them from every environment.
  • Chat and email, so they can't read channels where values may still sit.

Ending sessions matters as much as removing accounts. A session cookie on a laptop or a token in a CLI config can outlive the account change for hours if nothing invalidates it.

Step 2: revoke what they carried away

Developers create credentials that don't belong to their account and so don't disappear with it. Look for these explicitly.

WhatWhere it hidesWhat to do
Personal access tokensGit host, package registries, cloud CLIsrevoke; replace any that automation used
SSH keysauthorized_keys on servers, the Git hostremove their keys; check for shared keys they knew
Deploy keysrepository settingsreplace keys they created or could read
CI variables they setrepository and project settingstreat as seen; reissue the values
Service tokens and API keys they createdthe vault, cloud consoles, SaaS dashboardsrevoke or reissue; the creator saw the value once
Share links and invitations they createdthe vaultrevoke
Machine enrollment codesthe vaultrevoke unused ones

The last three rows are where a vault can help. In Crunu, the member removal wizard lists what the person could have carried away: service tokens they created and saw, machines not yet approved whose enrollment code they may have kept, and invitations and share links they created. You tick what to revoke, and it is revoked as part of the removal.

Credentials that are easy to forget

The table above covers what a person creates on purpose. A second group appears on no list because nobody thinks of it as theirs:

  • Shared logins. A team account for a SaaS dashboard, a registrar or a status page, with one password everyone knows. Change the password, and check whether the account's second factor is a code generator on the leaver's phone. If it is, move the second factor before anything else, or you may lock yourself out.
  • Long-lived keys in home directories. ~/.aws/credentials with keys of a personal IAM user, an .npmrc with a publish token, a .netrc with a Git host password. They belong to systems you still run, even though the files are on their laptop.
  • Apps and integrations they authorized. OAuth apps installed in your Git host or chat workspace under their name, and webhooks that deliver events to an address only they control. Some stop working when the account goes, others keep running. Review the list of installed integrations.
  • Automation running as them. A scheduled job on their machine, a CI pipeline triggered with their personal token, a bot account whose credentials they set up. Move each to a service identity before you revoke, or it breaks silently on the first day.
  • Recovery paths. Recovery email addresses and phone numbers on shared accounts, and backup codes printed during setup. An attacker who controls the recovery path controls the account.

None of these is exotic. They are simply invisible to a process that starts from the person's own accounts, which is why the inventory has to start from your systems instead.

Step 3: work out what they could read

This is the step that decides how much work step 4 is. The answer depends entirely on how your team shared secrets.

  • Shared through chat or email: you can't know, so assume they saw every value that ever passed through a channel they were in.
  • One encrypted file in Git: they held the key, so they could read every value in every version of the file, including old commits.
  • A vault with server-side permissions: you can see which paths they were allowed to read. Whether the logs show which values they actually fetched depends on the product and how long logs are kept.
  • A vault with per-environment keys and a delivery record: you can see which environments they had keys for, and which versions were delivered to them.
Example. Kiteline is a fictional company.

In Crunu the second half of that last case is the exposure report. For each environment it shows the person's access, the versions the server delivered to them, when, from which addresses, and whether they had the current key or an earlier one. Next to it, the reissue checklist lists the values they received that are still in use. Your browser compares the versions they received with the current ones, so a value that has already been changed since drops off the list. Only file paths and variable names are shown, never values.

Two limits apply to any such record. It covers only what went through the vault, not what someone copied into a note. And a delivery record proves the value reached their device, not that they read it. Treat delivered as seen.

Step 4: reissue the values, highest impact first

You rarely reissue everything on the same afternoon. Order by what an old value could do in the wrong hands.

PriorityExamplesWhy
1production payment keys, cloud admin credentials, database superuser passwords, release signing keyscan move money, read customer data or ship code
2production database application users, object storage keys, CI deploy credentialsread or change production data
3webhook signing secrets, session and token signing secretslet someone forge requests or sessions
4third-party API keys: email, monitoring, AI providers, analyticscost money, leak data, send mail as you
5staging and development valuesuseful as stepping stones; reissue them too

Two things raise a value's priority whatever its type: it is shared between environments, or it is used by more than one service. A database password that staging and production both use is a production password. That situation is also a reason to stop sharing it once you reissue.

Reissue without downtime: the overlap window

Replacing a key that live systems use risks an outage. Providers such as AWS and Stripe avoid it by letting an old and a new credential work at the same time, so you can deploy the new one before you retire the old one.

AWS, for example, lets an IAM user have two access keys. Its guide to updating access keys gives the sequence:

  1. While the first access key is still active, create a second one.
  2. Update every application and tool to use the new key.
  3. Check the old key's last-used information to confirm nothing still uses it, ideally after waiting a few days.
  4. Deactivate the old key instead of deleting it, and confirm your applications still work.
  5. After a further wait, delete the old key.

Stripe builds the window into its dashboard. When you rotate a key there, the old and new keys both work for up to 7 days, and Stripe suggests checking the old key's request logs and expiring it once its traffic has been at zero for a while, per its API keys guide. The same page lists the case where "a team member with access to the key leaves your organization or changes roles" as a reason to rotate.

Not every credential has an overlap. A token that is revoked the moment a new one is issued, or a signing secret that a framework accepts only one of, needs a short planned switch instead. For signing secrets in particular, check whether your framework accepts a previous key during a transition: without that, everyone who is signed in gets signed out. The rotation guides by service list, for each provider, whether old and new keys can overlap and how fast a revoked key stops working.

Deliver the new values without a redeploy

The overlap window only helps if the new value reaches every running service quickly. If values are baked into images or copied into .env files on servers, each reissue becomes a redeploy.

With a vault agent on the server, saving the new value is the deploy. In Crunu, a service started with crunu run --restart on-change notices the new version, logs the names of the changed variables, and restarts the program with the new values:

Shell
crunu run --env payments-api/production --restart on-change -- /opt/payments/bin/server
Example. Kiteline is a fictional company.

Then the order for one value becomes: issue the new key at the provider, save it in the environment, watch the services restart, check the old key's usage at the provider, revoke the old key. Pipelines that read the environment with a service token get the new value on their next run.

How fast is fast enough

There is no universal deadline, and any number we gave you would be invented. A workable rule is to tie speed to the circumstances of the departure and to the priority table above.

  • A hostile or sudden departure: treat it as an incident. Cut access within the hour, and reissue priority 1 and 2 values the same day, accepting a short planned interruption where a provider has no overlap window.
  • A normal resignation: cut access on the last day, reissue priority 1 and 2 values within days, and the rest as part of the next regular maintenance window.
  • Someone moving to another team: they still work for you, but their new role may not need production. Narrow their access first, then decide which values to reissue based on what they no longer need.

Whatever the pace, put a date next to every value on the reissue list and a name next to every date. A list without owners is how a key from a departure two years ago is still live today.

Step 5: make sure the vault's own keys are closed to them

If your secrets are encrypted, the person may hold, or may once have held, a key that decrypts them. Removing them from a list doesn't change that key. What happens next depends on the tool, and the differences are large.

ToolWhat removal doesWhat you have to do
git-cryptcannot revoke access, per its README; an old key still opens old historycreate a new key, re-encrypt, and reissue every value
SOPSsops updatekeys removes their key but keeps the data keyrun sops rotate --in-place on each file, then reissue the values, per the SOPS key management guide
Ansible Vaultanyone with the password can decryptansible-vault rekey each file with a new password; encrypted variables can't be rekeyed, per the Ansible docs, so re-encrypt them
1Password vaultsnot cryptographically enforced; keys are not changed, per its security designmove items to a new vault for a new key, and reissue the values
Server-side vaults and cloud secret managersusers never held the storage keysrevoke their tokens and roles; reissue the values
Crunurotates the key of every environment they had a key fornothing extra in the vault; reissue the values

Old ciphertext is the trap in the first four rows. A repository's history, a cached copy of a vault, an old backup: all of them still open with the old key. Re-encrypting the current file doesn't re-encrypt its past.

Example. Kiteline is a fictional company.

For step-by-step commands for the file-based tools, see removing someone from git-crypt, SOPS or Ansible Vault.

In Crunu the rotation is part of the removal. Each environment the person had a key for gets a new key, sealed to everyone who stays, and a new signed revocation list tells apps and agents to stop accepting signatures the person makes after the removal. If the admin running the removal doesn't hold the key of some environment, that environment's rotation waits in Pending actions until someone who holds the key opens the app.

Example. Kiteline is a fictional company.

When the person was an admin

An admin leaving widens the scope in both directions.

Inside the vault, an admin usually holds more than environment keys. In Crunu, owners and admins know the organization's signing key and recovery key, so removing one moves the organization to a new key generation: new organization keys, every certificate reissued, and a new key for every shared environment. This happens in the same wizard.

Outside the vault, check the accounts only admins tend to hold:

  • cloud root or organization admin accounts and their recovery settings;
  • domain registrar and DNS, because whoever controls DNS can redirect mail and certificates;
  • billing and support accounts that can change contacts or approve recoveries;
  • the vault's own server, if you host it yourself. If they had access to its hosting or settings file, change its server key. For Crunu, see Rotate the server key.

When an admin leaves goes deeper into the keys that sign everything.

Step 6: record what you did

Write down what was revoked, which values were reissued and when, and anything you decided not to reissue and why. An auditor will ask, and so will the next person who has to answer "are we sure that key is gone".

In Crunu, the removal ends with a report you can download, with the result per environment, such as "access removed, environment key rotated", and the reissue checklist. Keep it: the report and your "reissued" ticks exist only on that page, because the member is already removed. The audit log separately records the removal, the new revocation list and each environment key rotation.

Doing it in Crunu

The vault part of the offboarding runs in one wizard, in the browser of an owner or admin. Only an owner can remove an admin or another owner.

  1. Open Members, choose the person, then Remove from organization….
  2. Review the exposure report and the reissue checklist, and tick the tokens, links, invitations and enrollment codes to revoke.
  3. Check the plan: removal from every environment and access profile, new environment keys, a new revocation list.
  4. Choose Remove and rotate keys, and keep the page open while it runs in your browser.
  5. Download the report, then work through Reissue at providers, using Where to reissue for known services.
  6. Remove the person from your providers' consoles, repositories and CI separately, because Crunu doesn't manage access outside itself.

Offboarding a teammate documents every screen, and the offboarding feature page shows the wizard.

Contractors, agencies and planned departures

A departure you know about is a chance to shrink step 4 before it happens.

  • In the last two weeks, move the person to the narrowest access their remaining work needs. Every environment they don't open from now on is one less to reissue.
  • Before the last day, list the tokens and keys they created, and plan reissue for the values they received. Order new credentials that need a lead time, such as keys that need a vendor's approval.
  • For contractors, prefer expiring share links to accounts for short work, and per-client environments for agencies. When the engagement ends there is less to remove and less to reissue.

The offboarding checklist for engineering teams turns this into a list to keep with your HR process, and the offboarding checklist generator builds one for the services you use.

What no tool can do

  • Make someone forget a value. Reissue is the only fix, and until it is done, the old value works for whoever has it.
  • See copies outside the system. A value pasted into a notes app, kept in shell history or sent to a personal email isn't in any delivery record.
  • Stop a process that is already running. A program that started with the old value keeps it until it restarts. Revoking a server's access in Crunu wipes its environments from the agent's memory within minutes while the machine is online, but a running program holds its variables until restart.
  • Reissue at the provider for you. Crunu changes its own keys. New Stripe, AWS or GitHub credentials still come from Stripe, AWS or GitHub.

The OWASP Secrets Management Cheat Sheet says exposed keys should be revoked immediately, and that restarting an application does not revoke stolen credentials. An offboarding is the moment to apply both, before you have to.

For the terms used here, see exposure report, credential reissue and overlap window. For the reverse problem, how secrets were shared before someone left, see how to share .env files with your team.

Frequently asked questions

Something else? Write to support@crunu.com

Do we really need to rotate secrets when a developer leaves on good terms?

Yes, for the ones they could read. A departure on good terms still leaves copies on a personal laptop, in shell history and in old chat threads, and those copies can leak later through no fault of theirs. Reissue what they received, starting with production.

Which secrets should we rotate first?

Start with what can move money or data, or open other systems: production payment keys, cloud admin credentials, database passwords and signing keys for CI or releases. Then webhook secrets and third-party API keys, then development and test values.

Can we rotate API keys without downtime?

Where the provider allows an overlap, yes. AWS allows two access keys per IAM user, and Stripe keeps the old key working for up to 7 days after a rotation. Issue the new key, deploy it everywhere, check the old key is unused, then revoke it.

How do we know which secrets a former employee saw?

Only from a record of deliveries. If values were shared in chat or through one encrypted file, assume they saw everything. In Crunu, the exposure report lists which versions of which environments the server delivered to them, when and from which address.

Does Crunu rotate our API keys at the providers?

No. When you remove someone, Crunu rotates its own environment keys and gives you a reissue checklist of the values they received, by name, with links to where each known service issues new keys. Reissuing the values at Stripe, AWS or GitHub is done by hand.

What changes when the person who leaves is an admin?

More keys change. An admin could sign access lists and recover shared environments, so Crunu moves the organization to a new key generation. Outside Crunu, check the accounts only admins hold: cloud root, domain registrar, DNS, billing and, if you self-host, the server's own key.

Sources

Every source this guide relies on, with the date we last checked it.

  1. Update access keys, AWS IAM User Guide · checked October 30, 2026
  2. API keys, Stripe Docs · checked October 30, 2026
  3. Removing a member from your organization, GitHub Docs · checked October 30, 2026
  4. SOPS: key management · checked October 30, 2026
  5. Encrypting content with Ansible Vault, Ansible Docs · checked October 30, 2026
  6. git-crypt README · checked October 30, 2026
  7. 1Password Security Design: Leopard · checked October 30, 2026
  8. OWASP Secrets Management Cheat Sheet · checked October 30, 2026

Offboarding

In this topic

All guides

Try it with one project

Free during early access. Sign up with your email; your account keys and Secret Key are created in your browser, and the server never sees them.