Identity for AI Agents: Short-Lived, Scoped, Audience-Bound Tokens
The fastest way to give an AI agent access to your systems is to mint it an API key and paste it into a config file. It's also the most dangerous thing you can do. That key is long-lived, broadly scoped, valid everywhere, and — because it sits in plaintext in an agent's environment — exactly the kind of credential that leaks. Multiply it by the number of agents your team is about to deploy and you've built a credential-sprawl problem before you've shipped a feature.
Agents are a genuinely new identity class. They're not human users (no browser, no password, no MFA prompt) and they're not traditional service accounts (there are far more of them, they're short-lived, and no human provisions each one). Treating them like either is where it goes wrong. The good news: you don't need a new protocol. OAuth already has the primitives for agent identity done right — short-lived, narrowly-scoped, audience-bound tokens that you can revoke and audit. Here's what "done right" means, and which OAuth mechanism delivers each piece.
Why the API key is the wrong primitive
A static API key fails on every axis that matters for an agent:
- It doesn't expire. A leaked key works until someone notices and rotates it — which, for a key buried in an agent's config, is rarely.
- It's over-scoped. Keys are usually all-or-nothing. An agent that needs to read one calendar gets a credential that can do everything the key's owner can.
- It works everywhere. The same key is accepted by every service that trusts it, so one leak is lateral movement waiting to happen.
- It's unattributable. When something goes wrong, "the API key did it" tells you nothing about which agent, which user, or which action.
Every one of those is a property you'd never accept for a human login. Agents deserve the same bar — higher, actually, because there are more of them and no human is watching each one.
What good agent identity looks like
Five properties. Treat them as the spec:
- Short-lived. Access tokens measured in minutes, not forever. A leaked token expires on its own.
- Narrowly scoped. The token carries only the permissions the task needs — not the user's whole account.
- Audience-bound. The token works at exactly one resource server and is rejected everywhere else.
- Revocable. You can kill an agent's access instantly, without rotating a shared secret that breaks everyone else.
- Audited. Every token issuance and every action it authorized is recorded and attributable to a specific agent, user, and consent.
None of this requires inventing anything. It's the OAuth 2.1 authorization-code flow with a few requirements turned on.
The OAuth mechanics that deliver it
Short-lived + revocable → access tokens + refresh-token rotation. Issue short-TTL access tokens and let the agent refresh them. Crucially, rotate the refresh token on every use and revoke the entire chain if an old one is replayed — so a stolen refresh token is a single-use dead end, not standing access. (We cover the mechanism in refresh-token rotation and replay detection.)
Narrowly scoped → scopes + per-resource consent. The user authorizes the agent for specific scopes against a specific resource, and that consent is recorded — so the token reflects what the user actually agreed to, not a blanket grant.
Audience-bound → resource indicators (RFC 8707). The agent names the resource it wants a token for; the authorization server stamps that into the token's aud claim; the resource server rejects anything not bound to it. This is the single property that stops a token for one service from working against another — the foundation of securing an MCP server.
No secret to leak → public clients + PKCE. An agent running on someone's machine can't keep a client secret secret, so it shouldn't have one. It authenticates the flow with PKCE instead — a per-request proof that can't be replayed.
No human onboarding → CIMD. Agents you've never seen present a dereferenceable client_id (a URL) and onboard at first contact, without a registration endpoint. (The trade-offs vs Dynamic Client Registration are in CIMD vs DCR.)
Put together, that's "zero standing privilege" for agents: nothing the agent holds is broadly powerful or long-lived. The token it has right now is small, expiring, and good for one door.
Zero standing privilege, concretely
The phrase sounds abstract; the implementation isn't. It means the agent never sits on a credential that, if stolen this minute, grants broad lasting access:
- The access token is short-lived and audience-bound — steal it and you have minutes against one resource.
- The refresh token rotates and self-revokes on replay — steal it and the chain dies on next use.
- There is no client secret — there's nothing static to exfiltrate.
Compare that to the API key: stolen once, valid everywhere, forever. Zero standing privilege is just refusing to ever hand an agent that shape of credential.
The part teams skip: govern and audit
Identity isn't only authentication — it's accountability. The reason "the API key did it" is such a bad answer is that there's no identity behind it to attribute. With per-agent tokens tied to a user and a recorded consent, every action is attributable: this agent, acting for this user, under this consent, did this — written to an append-only audit log you can actually answer questions from. And when an agent misbehaves, you revoke its chain and nothing else breaks.
That auditability isn't a nice-to-have once agents are acting on real user data — under India's DPDP Act it's the difference between "we can show exactly what was accessed and on whose consent" and a reportable gap.
Agentic AI doesn't need a new identity stack — it needs the OAuth stack you already trust, with audience binding, short-lived tokens, PKCE, and rotation turned on, plus a way to onboard agents no human provisioned. NamoID issues audience-bound tokens, rotates refresh tokens with replay revocation, runs public-client PKCE flows, resolves CIMD client_id URLs, and writes every issuance and action to an append-only audit trail — so the agents your customers deploy get real identity instead of a shared key. The MCP server guide is the place to start.