On this page
What Is a Stale Non-Human Identity?
A stale NHI is a credential nobody uses but that still authenticates. It is a standing backdoor with no owner and no expiry.
Quick answer
- A stale non-human identity is one that no current workload or owner legitimately uses, but that remains valid and reachable.
- It is dangerous because it does not need to be stolen from a running service: the credential can sit in an old repository, a log, or a former employee’s notes and still work.
- Staleness is defined by use and ownership, not by age; a ten-year-old key that is used daily is not stale, and a week-old key created during an incident and forgotten is.
- The controls are last-used tracking, ownership records, expiry by default, and a review that disables before it deletes.
- AI-generated projects create stale identities quickly because setup steps create keys that the finished app no longer needs.
What makes a non-human identity stale?
Two conditions: no legitimate use and no accountable owner. A credential that is still used by a production job is not stale even if it is old, and one that nobody can name an owner for is suspect even if it was created recently. The dangerous combination is a valid credential with neither activity nor ownership.
Staleness also applies to permissions. An identity that is used but has accumulated access it no longer needs is partly stale: its legitimate use hides the excess scope. Reviews therefore check both whether the identity is used and whether what it can reach still matches its job.
Why are stale identities so dangerous?
Because they bypass the assumption that a compromised service is required for a credential to be abused. A stale key may exist in a public repository, a CI log, a screenshot, or a former contractor’s laptop. If it still authenticates and still has permissions, the attacker does not need to breach anything current.
They also survive cleanup. Removing an app from a repository does not delete its cloud key; deleting a Kubernetes secret does not revoke the IAM role it referenced; deleting a user does not always disable the service account that user created. The identity lives in the provider, not in your codebase.
How do you find stale identities?
Start with last-used data from the provider. Cloud IAM, databases, SaaS admin consoles, and secret managers usually record when a credential was last used, and a threshold such as ninety days surfaces most of the tail. Sort by permission breadth as well as inactivity, so the first review covers the identities that could do the most damage.
Then correlate with ownership. An identity with no owner in your inventory is stale until proven otherwise, even if it shows recent use, because the use may be an undocumented job or an attacker. For CI and repository secrets, scan for credentials that are not referenced by any current workflow.
Triage order for an NHI review
1. No recorded use in 90 days + write/admin permissions -> disable now
2. No recorded use in 90 days + read-only -> disable after owner check
3. Recent use + no owner -> find the caller, then assign
4. Recent use + owner + excess scope -> reduce, then monitor
5. Recent use + owner + correct scope -> leave alone, review next cycleWhat should you do about one?
Disable before deleting. Disabling is reversible and proves the impact: if a legitimate job breaks, you have found undocumented use and can restore access while documenting it. Deleting first turns a review into an incident and destroys the evidence of what the credential could reach.
Then revoke the underlying secret, not just the permission. A disabled key that is re-enabled by a forgotten automation returns to service. After the credential is revoked, remove it from repositories, CI variables, and secret stores, and record the decision so the next review does not rediscover the same identity.
Where this bites vibecoders
An AI assistant setting up a project will create a key for a service it is trying, wire it into .env, and move on. When the integration is replaced, the key stays in the dashboard and often in the repository history. A quarterly check of credentials with no recent use finds these faster than reading code.
Where AI coding assistants get this wrong
- Creating a key for every experiment and never revoking the ones the final app does not use.
- Treating an unused credential as harmless because nothing references it in code.
- Deleting the repository secret without disabling the credential at the provider.
- Assuming deleting a user disables the service accounts they created.
- Reviewing by age instead of by last use and permission breadth.
- Re-enabling a disabled credential without finding out why it was disabled.
Checklist
- Pull last-used data for every credential store you control.
- Flag credentials unused for 90 days.
- Sort the list by permission breadth.
- Disable before deleting, and watch for breakage.
- Revoke the secret at the provider after disabling.
- Assign an owner or complete the removal.
FAQ
How old does a credential have to be to be stale?
Age is not the criterion. An unused credential is stale the moment its purpose ends, whether that was a week or five years ago. Use last-used timestamps and ownership instead of creation dates, because a long-lived credential in active use is a rotation problem, not a staleness problem.
Is an unused API key a real risk if it never leaked?
You cannot know it never leaked. Keys end up in logs, screenshots, repository history, support tickets, and backups. The point of revocation is that the exposure question stops mattering. Treat the absence of a known leak as unknown rather than as safety.
What is the difference between stale and orphaned?
Orphaned usually means the owner is gone, while stale means the use is gone. The two overlap: an identity left behind by a departed employee is both. Reviews should catch both, because an identity can have a named owner who has forgotten it exists.
How often should stale identities be reviewed?
Quarterly is a reasonable default for a small team, with a review triggered by any departure or service decommission. The review is only useful if it ends in disables and revocations; a report that lists stale credentials and changes nothing trains everyone to ignore the next one.
Related topics
- What Is a Non-Human Identity (NHI)?
- How to Inventory Non-Human Identities
- What Are the Types of Non-Human Identities?
- How to Automate API Key Rotation
- What Is the OWASP Non-Human Identity Top 10?
- The Non-Human Identity Lifecycle