An agent needs an identity of its own, separate from the user it works for. Without one, every call it makes looks like the user made it, and you cannot revoke, rate-limit or audit the agent without doing the same to the person. This part covers how an agent gets that identity, as an OAuth client and as a workload, and how it proves it on every request.
Why the user’s token is not an agent identity
The most common shortcut is to let the agent run on the user’s access token. The token’s sub names the user, and nothing in it says which software is calling. If the agent misbehaves, the only lever left is the user’s session.
OAuth already has a slot for the software: the client_id. The IETF WIMSE working group’s draft on AI agents, draft-ietf-wimse-aims, builds on exactly that: access tokens identify the agent in client_id and the delegating user or system in sub. The rest of this part is about making that client_id mean something: a stable name for the software, a workload identity for where it runs, and a credential each running copy can prove it holds.
That draft is worth reading in full. It is an Informational working-group document (-01, November 2026) that defines no new protocol. Instead it maps existing OAuth and WIMSE standards onto agents and lists the gaps, which makes it the closest thing to an official reference architecture for agent identity today.
What an agent identity has to say
“The agent’s identity” is really four answers, and each comes from a different place. The software is named once, by whoever publishes it. The workload is named by the platform it runs on. Each running copy proves itself with a key it holds. Each token ties that copy to the person or system it works for.
Read it top to bottom: every layer’s credential names the identifier of the layer above, so a token at the bottom can be traced back to the software that holds it. Most deployments today stop at the first layer, or skip all four and use the user’s token.
Registering the agent as an OAuth client
Before an agent can get a token, the authorization server has to know it as a client. The MCP authorization spec (revision 2026-07-28) defines three ways, and a client that supports all of them should try them in this order: pre-registered credentials, then Client ID Metadata Documents if the server advertises client_id_metadata_document_supported, then Dynamic Client Registration, and finally asking the user.
| Method | How the agent gets a client_id | Fits when | Status in MCP 2026-07-28 | Watch for |
|---|---|---|---|---|
| Pre-registration | An admin registers the client with the authorization server ahead of time | Client and server already have a relationship, such as agents inside one company | SHOULD be supported | Credentials must be tied to the issuing server’s issuer and never reused with another server |
| Client ID Metadata Document | The client_id is an HTTPS URL; the server fetches a JSON metadata document from it | No prior relationship (the common MCP case) | SHOULD be supported | SSRF on the fetch, phishing via look-alike names, metadata that changes after consent |
| Dynamic Client Registration (RFC 7591) | The client POSTs its metadata to a registration endpoint | Older authorization servers without CIMD support | MAY; deprecated | Must send the right application_type (native or web) or OIDC servers may reject the redirect URIs |
For agents, the Client ID Metadata Document is the interesting one. The URL becomes a stable, self-hosted name for the software, portable across authorization servers with no re-registration. The OAuth working-group draft, now at -03 (November 2026), adds rules that matter for agents. Shared secrets are prohibited: no client_secret, client_secret_basic or client_secret_jwt. A client that authenticates publishes its keys through jwks_uri or jwks and uses private_key_jwt. The server must not follow redirects when fetching, must not fetch special-use IP addresses, and must compare the document’s client_id to the URL exactly.
An agent’s metadata document under the -03 draft might look like this:
{
"client_id": "https://agents.example.com/finance-assistant.json",
"client_name": "Finance Assistant",
"redirect_uris": ["https://agents.example.com/callback"],
"grant_types": ["authorization_code", "refresh_token"],
"token_endpoint_auth_methods_supported": ["private_key_jwt"],
"jwks_uri": "https://agents.example.com/jwks.json"
}
One detail to check in your stack: MCP 2026-07-28 still cites draft -00, and its example uses token_endpoint_auth_method, while -03 asks clients to advertise token_endpoint_auth_methods_supported. If your authorization server tracks the newer draft, use the newer field.
A metadata document names a class of software, not a running copy. Every instance of the finance assistant shares that URL. Telling instances apart, and proving which one is calling, is the job of the next two sections.
Proving it: client authentication
A client_id is a claim. Client authentication is the proof, presented to the token endpoint. For agents, the useful methods are all key-based: no shared secrets that sit in a config file the model might read.
| Method | What the agent presents | Standard | Status |
|---|---|---|---|
private_key_jwt | A JWT signed with its private key, sent as client_assertion with type urn:ietf:params:oauth:client-assertion-type:jwt-bearer; sub must be the client_id | RFC 7523 | RFC (May 2015) |
| Mutual TLS | A client certificate, either PKI-validated (tls_client_auth) or matched against registered keys (self_signed_tls_client_auth) | RFC 8705 | RFC (Feb 2020) |
| SPIFFE credentials | A JWT-SVID as a client assertion (type jwt-spiffe), or an X.509-SVID over mutual TLS | draft-ietf-oauth-spiffe-client-auth | OAuth WG draft -03 (Nov 2026) |
| Client attestation | A Client Attestation JWT issued by the client’s backend, carrying the instance’s public key in cnf, plus a proof of possession on each request | draft-ietf-oauth-attestation-based-client-auth | OAuth WG draft -12, WG consensus (Oct 2026) |
The last two rows are where agent identity is heading. The SPIFFE draft lets a workload that already has a SPIFFE credential use it directly as its OAuth credential, with nothing extra to distribute. It also connects to metadata documents: when the client_id is a CIMD URL, the SPIFFE ID in the credential must match the spiffe_id value in that document. Attestation-based authentication solves the instance problem from the previous section. The backend vouches for each running copy and its key, and each request carries an OAuth-Client-Attestation header and a proof of possession, which can be a DPoP proof.
Binding tokens to the agent
Authenticating at the token endpoint is not enough if the access token that comes back is a bearer token anyone can replay. Two RFCs bind a token to the client’s key:
- DPoP (RFC 9449) ties tokens to a key pair at the application layer, so a stolen token is useless without the private key.
- Certificate-bound tokens (RFC 8705) carry the SHA-256 thumbprint of the client certificate in the token’s
cnfclaim asx5t#S256.
For agents that run for hours and pass through several hops, sender-constraining is the cheapest control with the biggest payoff. A token leaked into a log, a prompt or a tool response stops being a credential.
One rule from draft-ietf-wimse-aims deserves its own line: the language model must not have access to the agent’s credentials. Keys and tokens belong to the runtime around the model, never to the context window.
Workload identity: SPIFFE and WIMSE
OAuth tells the authorization server which software is asking. Workload identity tells every other workload which running process it is talking to. Agents need both, because they are workloads first: draft-ietf-wimse-aims defines an agent as a workload that repeatedly calls a language model and external tools until a stop condition is met.
SPIFFE
SPIFFE gives each workload an identity that works across platforms. Three parts matter here:
- The SPIFFE ID is a URI with the
spiffescheme, a trust domain as its authority and an administrator-defined path, for examplespiffe://prod.example.com/agents/finance-assistant. No query, no fragment, and implementations must support IDs up to 2,048 bytes (SPIFFE-ID spec). - The SVID is the verifiable document that carries the ID: an X.509 certificate, a JWT, or a WIT (WIMSE workload identity token).
- The Workload API delivers SVIDs and trust bundles to the workload, usually over a local Unix domain socket. It has no authentication handshake: the implementation identifies the caller out of band, from properties the operating system provides. That is the property agents need, since no secret is ever handed to the process.
The IETF WIMSE working group
WIMSE (Workload Identity in Multi-System Environments) is standardizing workload identity for HTTP-based systems. Its documents as of November 2026:
| Document | What it covers | State |
|---|---|---|
| draft-ietf-wimse-arch | Architecture | WG draft -08 |
| draft-ietf-wimse-identifier | Workload identifiers | WG draft -04 |
| draft-ietf-wimse-workload-creds | Workload Identity Token (JWT) and Workload Identity Certificate (X.509), both bound to a key | WG draft -03 |
| draft-ietf-wimse-wpt | Workload proof token: proof of key possession at the application layer | WG draft -02 |
| draft-ietf-wimse-mutual-tls | Workload authentication with mutual TLS | WG draft -03 |
| draft-ietf-wimse-http-signature | Workload authentication with HTTP Message Signatures | Submitted to IESG, AD evaluation |
| draft-ietf-wimse-workload-identity-practices | Current practices | Submitted to IESG, IETF last call |
| draft-ietf-wimse-aims | AI Identity Management System: applying WIMSE and OAuth to agents | WG draft -01, Informational |
None of these is an RFC yet. The two closest are the HTTP signature profile and the practices document, both already with the IESG.
A recommended baseline
The finished standards already support a solid baseline. The drafts then improve it rather than replace it.
- Give every agent its own
client_id. Pre-register agents inside your own organization; use a Client ID Metadata Document where there is no prior relationship. - Use no shared secrets. Authenticate with
private_key_jwt(RFC 7523) or mutual TLS (RFC 8705) today; move to SPIFFE credentials or client attestation as those drafts settle. - Keep credentials out of the model. The runtime holds keys and tokens; nothing that reaches the context window can be used to authenticate.
- Sender-constrain every token with DPoP or certificate binding, so a leaked token is not a usable one.
- Issue credentials at runtime and keep them short-lived. draft-ietf-wimse-aims recommends issuing, renewing and revoking agent credentials at runtime, with a posture check at issuance, and discourages static API keys.
- Make every token name both parties:
subfor the user or system the agent acts for,client_idfor the agent. Part 3 extends this to chains of agents.
Standards status (November 2026)
| Standard | Status |
|---|---|
| RFC 7523, JWT client authentication | RFC |
| RFC 7591, Dynamic Client Registration | RFC; deprecated for MCP |
| RFC 8705, mutual-TLS client authentication and certificate-bound tokens | RFC |
| RFC 9449, DPoP | RFC |
| OAuth Client ID Metadata Document | OAuth WG draft -03 |
| OAuth SPIFFE Client Authentication | OAuth WG draft -03 |
| OAuth Attestation-Based Client Authentication | OAuth WG draft -12, WG consensus |
| SPIFFE and SPIFFE ID | Specifications marked Stable |
| WIMSE documents | WG drafts; two submitted to the IESG |
| MCP Authorization, client registration | Revision 2026-07-28 |
Sources
- MCP Authorization, Client Registration (revision 2026-07-28)
- OAuth Client ID Metadata Document, draft-ietf-oauth-client-id-metadata-document
- RFC 7523: JWT Profile for OAuth 2.0 Client Authentication and Authorization Grants
- RFC 8705: OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens
- RFC 9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP)
- OAuth SPIFFE Client Authentication, draft-ietf-oauth-spiffe-client-auth
- OAuth 2.0 Attestation-Based Client Authentication, draft-ietf-oauth-attestation-based-client-auth
- SPIFFE specification and SPIFFE ID specification
- IETF WIMSE working group documents
- AI Identity Management System, draft-ietf-wimse-aims
- WIMSE Workload Credentials, draft-ietf-wimse-workload-creds