← All articles

Non-Human Identities: Types, Lifecycles, and Risks

Key takeaways

  • Non-human identities are credentials used by software, such as API keys, service accounts, OAuth tokens, certificates, and workload identities, and they outnumber human identities in most organizations.
  • The defining trait of a non-human identity is the absence of a login event, session, or MFA prompt, which breaks security tooling designed around human session boundaries.
  • API keys and service accounts carry the highest risk because they have no default expiry, while short-lived workload identities fail mainly through over-broad scopes.
  • Rotation suits credentials with a known owner and active use; revocation is the right call when ownership or usage is unknown.
  • Vaults solve custody of secret values, but a separate metadata layer is needed to track ownership, expiry, and rotation deadlines.

Non-human identities are the credentials your machines use to authenticate: API keys, service accounts, OAuth tokens, certificates, and workload identities. They outnumber your engineers, outlive the people who created them, and sit outside your vault's visibility once issued. This guide defines the five types, then traces one Stripe API key through every lifecycle stage to show where risk appears.

What are non-human identities and how do they differ from human identities?

A non-human identity is any credential or identity consumed by software rather than a person: the Stripe API key in your payments service, the GitHub token your CI pipeline uses, the IAM role your Lambda assumes. The OWASP Non-Human Identities Top 10 project defines them by the same criterion: no human is involved in their use, which means no login event, no session, and no MFA prompt to audit.

The defining difference: no login, no logout

A human identity has a session boundary. It signs in, works, and signs out, and most security tooling assumes that shape. A non-human identity just runs. A Stripe key embedded in a Postman collection has no session to expire, so the only thing that ages it is an expiry date someone had to set deliberately.

Why NHIs behave differently in an audit

Ownership is fuzzier too. When an auditor asks who owns a key, "Payments platform" is a team, not a person who gets paged. Human identities come with HR records; NHIs come with whoever created them, if that person is still employed. That is why we track metadata only, never secret values, at KeyGuardRail: the audit problem is knowing who owns the key, when it expires, and what breaks if it is revoked.

What are the main types of non-human identities?

Non-human identities fall into five types. Most platform teams run several of each without a single inventory of who owns what or when it expires.

API keys

Static strings issued by a SaaS provider. Your Stripe restricted key that the Payments platform uses for charges, and the GitHub personal access token your CI uses to check out repos, are both API keys. They usually have no default expiry, so a rotation policy of 30/60/90 days has to be enforced by you, not the provider. Tracking those deadlines manually across teams breaks fast; that is the problem KeyGuardRail's rotation tracking alternatives covers.

Service accounts

Cloud-native principals with their own permissions. An AWS IAM user with an access key pair, used by a nightly billing job, is a service account. The risk is scope creep: the account accumulates policies nobody reviews.

OAuth tokens

Delegated access, often long-lived refresh tokens. A GitHub App installation token or a Stripe OAuth token from an integration qualifies.

Certificates

X.509 credentials with hard expiry dates, like the TLS cert on an internal service or a client cert for mTLS between services.

Workload identities

Short-lived, cryptographically attested identities, such as an AWS IAM role assumed via OIDC from GitHub Actions.

TypeExampleTypical expiry
API keyStripe restricted keyNone unless you set it
Service accountIAM user access keyNone
OAuth tokenGitHub App refresh tokenMonths
CertificateInternal TLS certFixed date
Workload identityOIDC-assumed IAM roleMinutes to hours

The shorter the expiry, the less a vault matters and the more lifecycle coordination does.

Why do non-human identities outnumber human identities in most organizations?

Because every integration mints credentials and headcount stays flat. A single team wiring up Stripe, GitHub, Datadog, and a CI pipeline creates one service account or API key per connection. Add a staging copy of each and the count doubles. Sprawl is structural, not a hygiene failure.

Every SaaS integration is a new identity

Each SaaS connection needs its own key, owned by whoever set it up, often a dev who has since moved teams. That is how keys end up in Postman collections with no owner and no expiry date.

Why the vault does not shrink the count

A vault centralizes storage, not creation. Moving keys into AWS Secrets Manager changes where they live, not how many exist or who owns them. AWS's own guidance treats long-lived access keys as a liability to rotate on a schedule (AWS IAM documentation), which means every stored key carries a rotation deadline on top. Secrets distribution tools help with delivery, but the inventory of identities keeps growing either way. Tracking expiry and ownership across that inventory is the gap KeyGuardRail targets.

How does a non-human identity's lifecycle create security risks at each stage?

A single Stripe API key picks up a new risk at every stage of its life. Trace it end to end and the failure modes stop being abstract.

Stage 1: Creation, who requested it and what scope

A developer on the Payments platform team creates a restricted key for webhook signing. Nobody records why it exists, what scope it got, or who owns it. The risk starts here: an unowned credential with more scope than the task needed.

Stage 2: Distribution, the human transport layer problem

The key travels by the worst possible routes: a Slack DM, a Postman collection, a ticket comment. As one practitioner put it, "humans are the transport layer." Every copy is a new place the key lives outside the vault, and none of them show up in an audit trail.

Stage 3: Use, drift between documented and actual consumers

The key was built for one webhook endpoint. Eighteen months later, a data pipeline also reads it from a shared Postman workspace. The documented consumer list says one service; the actual list is three. Drift like this is why "who owns this key" becomes unanswerable, and why a revocation decision turns into guesswork.

Stage 4: Rotation, the 30/60/90 day policy in practice

The policy says 90 days for long-lived keys. In practice, rotation happens when someone remembers, because the vault stores the secret value but nothing tracks the deadline or the owner. A rotated key also leaves the old one valid until someone manually deletes it, so you now run two live credentials with one owner between them. This is the gap a credential lifecycle monitoring layer like KeyGuardRail exists to close: it tracks ownership, expiry, and rotation deadlines as metadata only, without holding secret values, and you can read more at the KeyGuardRail resource library.

Stage 5: Expiry, the silent failure

Stripe keys do not expire on their own, so expiry only happens if you set it. When an expiring credential lapses unnoticed, the failure is silent until a job breaks, or worse, it is not silent and the key keeps working past its intended life.

Stage 6: Revocation, proving nothing still depends on it

Revocation is the moment drift becomes expensive. Delete the key and the undocumented Postman consumer fails in production; keep it and the rotation policy is theater. Without an inventory of actual consumers, you cannot prove nothing still depends on the credential, so stale keys survive "just in case."

How does the OWASP Non-Human Identities Top 10 map to real identity types?

The OWASP Non-Human Identities Top 10 lists risks like credential sprawl, long-lived secrets, and unclear ownership. Those risks land unevenly across the five identity types in your stack, which is why the same list means different things for a Stripe key than for a workload identity.

Which risks hit long-lived credentials hardest?

API keys and service accounts, which have no built-in expiry, absorb the worst of it: unclear ownership, no rotation deadline, and secrets leaked into Postman collections or Slack. Short-lived credentials such as OAuth tokens and workload identities fail differently, usually through over-broad scopes rather than staleness. Certificates sit in between, with expiry dates you can forget but rarely leak.

Mapping the Top 10 to your AWS and SaaS footprint

Run your footprint through the list: AWS Secrets Manager entries are usually owned, but the Stripe restricted keys and GitHub PATs around them are not. Stripe's own guidance on restricted keys and rotation treats rotation as routine, yet most teams have no owner or deadline attached. We break down the operational side in our guide to API key management best practices.

When should a non-human identity be rotated versus revoked?

Rotation is maintenance. Revocation is a verdict. Pick based on two questions: do you know who owns this key, and do you know it is still in use?

Rotate when the identity is alive and owned

If a Stripe key has a named owner, a rotation deadline, and recent traffic, rotate it on your 30/60/90 day policy. Rotation keeps a live identity's blast radius bounded without breaking the services depending on it. Track the deadline, the last rotation date, and the owner in one place so the schedule survives team changes.

Revoke when ownership or use is unknown

A key with no owner and no visible calls is a liability, not an asset to maintain. Over-scoped credentials fall here too: if you cannot say what a key can access, you cannot safely keep it. Revoke, then wait for something to break loudly enough to claim it.

The orphan test

Ask three questions: who owns this, when does it expire, and what last used it? Fail one, and the credential is orphaned. Your Stripe key passes if all three answers exist in writing.

How do you start inventorying non-human identities in your own environment?

Where NHIs hide in an AWS-plus-SaaS shop

Walk four surfaces in order: cloud IAM (IAM users, access keys, Secrets Manager entries), CI/CD (deploy keys, pipeline variables, OIDC trust policies), SaaS dashboards (Stripe restricted keys, GitHub PATs, Slack bot tokens), and code (keys pasted into Postman collections, .env files, scripts). The code sweep finds the ones humans moved by hand, which is where secrets sprawl usually starts.

The minimum metadata per identity

For each key, record: owner (a team name like "Payments platform", not a person), purpose, environment, creation date, expiry date if the provider enforces one, last-used date, and rotation interval per your 30/60/90 day policy. Never record the secret value itself. GitHub's fine-grained PATs, for example, carry a mandatory expiration you set at creation, which makes them easier to inventory than keys with no expiry at all.

Keeping the inventory alive

Point discovery at metadata APIs, not secret stores, so the inventory stays current without anyone holding a key. Reconcile weekly against provider listings, flag anything with no owner, and assign one before its next rotation deadline.

How do vaults and lifecycle monitoring fit together?

Vaults like AWS Secrets Manager, HashiCorp Vault, Infisical, Doppler, and Akeyless solve custody and delivery: storing secret values, injecting them at runtime, and enforcing access control at the moment a workload requests a credential. They are the right layer for that job, and most platform teams should keep them there. What they generally do not give you is a coordination layer above custody: who owns each key, when it expires, whether the 30/60/90 day rotation policy is actually being met, and what the audit trail shows after the person who created a key leaves the company. A vault can hold a Stripe restricted key perfectly for years while the developer who requested it moves to another team, the expiry date passes unnoticed, and nobody can say which pipeline still reads it. Custody answers where the secret lives; coordination answers whose key it is and who is on the hook when it dies.

Custody is not coordination

Custody answers "where is the secret value?" Coordination answers "whose key is this, when does it die, and who is on the hook?" A vault can hold a Stripe key perfectly while the dev who created it leaves and nobody notices the expiry date.

Running KeyGuardRail through the same criteria

KeyGuardRail monitors credential lifecycle metadata: ownership, expiry, rotation deadlines across AWS, Stripe, and GitHub, without holding secret values. That metadata-only stance means it cannot rotate or deliver secrets, so you still need a vault underneath, and coverage depends on the integrations it supports. It fits above your existing vault, not instead of one.

FAQ

What is an example of a non-human identity?

A Stripe restricted API key used by your payments service is a classic example. Other common ones include the GitHub personal access token your CI pipeline uses to check out code, an AWS IAM user access key pair running a nightly billing job, an internal TLS certificate, and an IAM role assumed via OIDC from GitHub Actions.

Are service accounts considered non-human identities?

Yes. A service account is a cloud-native principal, such as an AWS IAM user with an access key pair, that software uses rather than a person. It fits the defining criterion: no login event, no session, no MFA prompt. The main risk is scope creep, since service accounts accumulate permission policies over time that nobody reviews.

How many non-human identities does a typical company have?

More than its headcount, and the gap grows with every integration. Each SaaS connection, CI pipeline, and staging environment mints at least one credential, so a single team wiring up Stripe, GitHub, Datadog, and CI can create several, doubled by staging copies. Sprawl is structural, not a hygiene failure, which is why inventorying matters more than counting.

What happens if a non-human identity expires while a service is running?

It depends on the type. API keys and service accounts usually have no default expiry, so they keep working past their intended life, which is its own risk. Credentials with hard expiry dates, like certificates or fine-grained GitHub PATs, fail silently until a job breaks in production. Either way, the fix is tracking expiry dates and owners in one place.