Skip to content
LearnOrphaned credentials

What are orphaned credentials?

Also known aszombie credentialsstale tokens
Example. Kiteline is a fictional company.
On this page

Orphaned credentials are credentials that still work but no longer have an owner or a purpose: a token created by someone who has left, a key for a service that was retired, an invitation never accepted, a share link nobody remembers, an enrollment code for a machine that was never set up.

How they come about

Credentials are created by people for tasks. People move on and tasks finish, but nothing ties the credential's life to either. OWASP puts this first in its Non-Human Identities Top 10 as "Improper Offboarding": the "inadequate deactivation or removal of non-human identities (NHIs) such as service accounts and access keys" once they are no longer needed (OWASP NHI Top 10).

Typical sources:

  • Departures. Tokens a person created for their scripts, CI variables they set, SSH keys they added to servers.
  • Experiments. A key made for a proof of concept that went nowhere.
  • Replaced systems. The old deploy pipeline's credentials, still valid after the move to a new one.
  • Unfinished flows. Invitations and machine enrollment codes issued and never used.

Why they matter

An orphaned credential has the worst profile a credential can have: it is valid, nobody watches it, and nobody would notice if it were used. No one reviews its permissions, no one gets alerted on odd usage, and no one thinks to replace it when something else leaks. Often it was also created with broad permissions because it was meant to be temporary.

Finding them

Start from your systems, not from the people. A list of what a departing person "had" misses what they created on the side.

  • Ask each provider for credentials and their last use: cloud consoles, Git hosts and payment providers usually show it.
  • Treat "never used" and "not used for months" as candidates for removal.
  • Tie each remaining credential to an owner that is a team or a service, not a person.
  • Prefer credentials that expire. A forgotten credential with a short lifetime fixes itself.

Common mistakes

  • Revoking only the person's account. The tokens they created may belong to other accounts or to no account at all.
  • Keeping things "just in case". If nobody can say what a credential is for, deactivate it first and delete it after a quiet period.
  • No owner field. A note saying who created a key and why costs seconds and saves an afternoon later.

How Crunu handles its own

Crunu's member removal wizard looks for exactly this inside Crunu. Its first step 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, together with the rotation of environment keys.

Example. Kiteline is a fictional company.

Crunu's own credentials also tend to age out: invitations last up to 7 days, enrollment codes 15 minutes by default, and share links, service tokens and machines can have expiry, usage limits or leases. Credentials at your providers are a different matter. Crunu can't list or revoke tokens at GitHub, AWS or Stripe; the reissue checklist names values to replace, and the rest of the inventory is yours. What to rotate when a developer leaves has a table of the credentials people most often forget.

Sources

From the blog

  • AI agents

    API keys in MCP server configs: where they end up

    MCP clients keep server settings as plain JSON, and the API key usually sits in it. Where those files live, who can read them and how to keep keys out.

    AI coding agents guide

  • Security

    Audit logs you can verify: how hash chains work

    An audit log is only evidence if nobody can quietly edit it. How hash chains make tampering visible, what they miss, and how to check an export yourself.

    Offboarding guide

  • Migration

    Moving team secrets out of Ansible Vault

    Why teams move secrets out of Ansible Vault, how to export them with ansible-vault, bring them into per-environment storage, and keep playbooks working.

    Offboarding guide