OAuth·for·Agents

Delegated access in the agentic era

Agents need to log in to things.

Not with your API key. Not with a copy of your password. With an identity of their own, permission you actually granted, and a trail you can read afterwards.

Almost all of that machinery already exists — already shipped, already deployed at scale. It's OAuth. What has been missing is a picture of how the pieces fit together for software that decides at runtime what it's going to touch. This is that picture: seven scenarios, each adding a single piece to the one before it.

The honest version

Software changed. Five assumptions broke.

OAuth was designed around a world where integrations were decided by people, in advance, and written down. Agents don't work that way — and the friction everyone is feeling right now is real.

The old shape

A developer decides their app will integrate with a service. They read the docs, register the app, get a client_id, pick their scopes, and ship. A user clicks "Connect," sees a consent screen in a browser, and approves. The app holds a token and uses it for months.

The new shape

An agent is handed a task and works out which services it needs while it is running. It may meet a server nobody has ever registered with. It acts at 3am while its user is asleep. It calls another agent, which calls an API at a different company. Nothing about that was written down in advance.

01

Nobody registered the client

OAuth's registration step assumes a human filled out a form on a developer portal and got an identifier back. An agent that discovers a server mid-task has no such identifier, and neither side wants a manual step in the middle of a conversation.

Closed by Client ID Metadata Documents — the client publishes its own metadata at a URL, and that URL is the client ID.

02

There's no browser, and no one is watching

Consent was designed as a redirect: a person, in front of a screen, reading a page. Agents run in terminals, in CI, on a server, at night. The moment a decision is needed, the human may be hours away — and "pending" was never treated as a legitimate state to sit in.

Closed by the device grant, CIBA, and the transaction authorization challenge — asynchronous approval, with polling, as a first-class flow.

03

"Read your email" is not a permission

Scopes name categories of capability. Agents take specific actions: move this $4,000, delete that repository, email these forty people. A scope can't tell a user which of those is about to happen, so the consent they give is much broader than the act they'd approve.

Closed by Rich Authorization Requests — structured authorization details describing the actual operation, not the category.

04

A bearer token is a bearer token

The whole security model of a bearer token is "don't let it leak." Agents copy credentials into prompts, logs, sandboxes and third-party runtimes. The blast radius of a leak is the entire lifetime of the token, on any machine on earth.

Closed by DPoP and mTLS — the token is bound to a key the agent holds, so a stolen copy is inert.

05

By hop four, nobody knows who asked

A request starts with a person, passes through an agent, an MCP server, a partner's API and three internal services. Somewhere in there the original identity turns into "trust me, I'm the backend." When something goes wrong, the log says a service did it.

Closed by Token Exchange, Identity Chaining and Transaction Tokens — the actor chain travels with the request across every hop.

Notice what isn't on this list

Not one of these is a flaw in OAuth's core idea: that a resource owner can grant a piece of software narrow, revocable, auditable access without handing over a credential. That idea is exactly what agents need. What broke are the assumptions layered on top of it, and every one of them has a spec-shaped answer that's in progress or already exists.

The ladder

Seven scenarios, each one piece bigger than the last.

Start with an agent that has no user at all and just needs to call an API. Add a person. Add a service nobody registered with. Add precision, then absence, then a company boundary, then your own internals. Every rung reuses everything below it and adds exactly one new idea.

The agent acts as itself

A nightly job summarizes yesterday's support tickets. There's no user in the loop — the agent is the one being authorized. Today this is a long-lived API key pasted into an environment variable, copied into three deployment configs, and rotated never.

Adds: an identity for the agent that isn't a shared secret — a key it holds, a short-lived token it earns, and a token that's useless if it leaks.

Replace the API key

The agent acts for a person

Now the agent reads your calendar. The API has to know two things at once: which software is asking, and whose data it's allowed to touch. These are different questions, and conflating them is how you end up with an agent that can read everyone's calendar.

Adds: delegation — a token that names the user and the agent acting for them, so the audit log has both.

Add the human

The agent meets a service nobody registered with

Mid-conversation, the agent is pointed at an MCP server it has never seen, run by a company that has never heard of it. There is no developer portal step available, and there is no human to go do one. The two sides have to bootstrap trust from a URL.

Adds: runtime discovery and registration-free clients — protected resource metadata, and a client ID that is a URL you can fetch.

Bootstrap from a URL

The agent says exactly what it's about to do

"This agent may send email on your behalf" is a promise with no edges. What the user wants to approve is "send this draft to these recipients." The gap between those two sentences is where most of the fear about agents actually lives.

Adds: structured intent — authorization details that describe the operation, so consent and the audit record are about the act, not the category.

Get specific

Nobody's watching and it needs permission

The agent has been running for forty minutes and hits the one step that needs a person: a refund above the limit, a production deploy, a payment. Its user is asleep. Failing is wrong, and guessing is much worse.

Adds: asynchronous authorization — the resource issues a challenge, a human approves it out-of-band, and the agent waits without holding anything sensitive.

Wait for the human

The work crosses a company boundary

An agent inside your SaaS vendor's product needs to read a document in your company's storage. Your IdP knows the user. The storage API does not trust your vendor's tokens, and shouldn't have to learn a new issuer for every vendor you buy.

Adds: identity chaining — a short-lived, audience-bound grant that lets each domain keep issuing its own tokens while the user's identity survives the crossing.

Cross the boundary

The request fans out inside your own walls

One agent call becomes eleven internal service calls. The outermost token was audience-bound to the edge and shouldn't go further, but every service downstream still needs to know it's acting for a specific person, under a specific authorization, in a specific request.

Adds: transaction tokens — a per-request, internally-scoped credential carrying immutable call context through the whole fan-out.

Follow it inward

The parts bin

None of this is speculative.

Everything in the seven scenarios is a published RFC or an active IETF draft. Here are the load-bearing ones. The full reference has the rest, with what each is for and where it stands as of August 2026.

DPoP RFC 9449

Binds an access token to a key the client holds. A copied token is worthless without the private key — which is what makes a token safe to hand to a runtime you don't fully control.

Protected Resource Metadata RFC 9728

Lets an API say, in a machine-readable document, which authorization server protects it. This is the discovery step that makes "meet a server you've never seen" possible at all.

Client ID Metadata Document WG draft

A client's ID is an HTTPS URL that serves its own metadata. No registration call, no portal, no shared secret — and the identifier means the same thing at every server that fetches it.

Rich Authorization Requests RFC 9396

Replaces a scope string with a structured description of the operation being requested. The difference between "can send mail" and "send this message to these people."

Token Exchange RFC 8693

Trades one token for another, and carries an act claim naming the actor operating on the subject's behalf. This is where "the agent, for the user" becomes a thing a token can say.

Transaction Tokens WG draft

A short-lived token scoped to one call chain inside a trust domain, carrying immutable context so every internal hop can make its own decision without re-deriving who asked.

Not a sales pitch

What's actually missing.

A page that claims everything is solved is a page you shouldn't trust. Some things genuinely aren't standardized yet. They're worth naming precisely, because the size of the remaining gap is the whole question of whether this needs a new ecosystem or a few more drafts.

  • Naming the individual agent instance

    You can identify the software, and you can bind a token to a per-instance key. What you can't yet do in a standard way is put "this is instance abc-123, spawned at 14:02, by this parent" into a token so a resource can reason about it, revoke just that one, and show it in a list to a user.

    Closest thing today: DPoP's key thumbprint as a de-facto instance handle, plus a private claim. Interoperable, no. Workable, yes.

  • How deep delegation is allowed to go

    Token Exchange's may_act says who may act for whom. It doesn't express "this agent may sub-delegate to one more agent and no further," or "this delegation dies when the parent task ends." Agents calling agents makes that a live question rather than a theoretical one.

    Closest thing today: nested act chains plus local policy at each authorization server.

  • Showing a person what they're approving

    Rich Authorization Requests can express an operation exactly. Nothing standardizes how an authorization server should render an unfamiliar authorization details type to a human, or what to do when it receives one it doesn't understand. Precision the user can't read isn't consent.

    Closest thing today: the RAR metadata and error remediation draft, which is exactly this problem being worked on.

  • Revocation that actually propagates

    "Kill this agent's access everywhere, now" spans an IdP, three authorization servers and a partner. The machinery exists in the Shared Signals Framework and CAEP; deployment does not. Until it's common, an agent's access dies at the speed of the longest token lifetime in the chain.

    Closest thing today: short token lifetimes and the refresh token expiration draft — blunt, but it works.

  • Vouching for what an agent is

    A client ID metadata document tells you what a client claims to be. Attestation-based client authentication and SPIFFE client auth cover the workload case. There's no widely-deployed way for a model provider or platform to vouch for an agent's provenance in a form a random API can check.

    Closest thing today: attestation-based client authentication, plus reputation on the client ID URL itself.

The shape of the gap

A claim here. A metadata field there. A rendering convention. These are draft-sized problems, being worked on in the open by the people who will have to implement them — and each one lands in an ecosystem that already has authorization servers, libraries, audit pipelines and security review behind it.

That's the case for building on what's here: not that OAuth is perfect for agents, but that the distance from where it is to where agents need it is genuinely short, and the distance from zero is not.

Start at the bottom.

The first rung is the one almost everybody is standing on right now — an agent with an API key in an environment variable. It's also the easiest one to fix.