Skip to content
Agent Identity

IETF · 6 August 2026

AAuth Protocol

draft-hardt-oauth-aauth-protocol-10

D. Hardt (Hellō)

Individual draftDraft — expect changeIdentity + Authn + AuthzAgent-specificField guide

This is the draft people mean by 'AAuth'. It is the most complete attempt at agent-native identity plus authorization that still reuses OIDC claim vocabulary and HTTP. If you are evaluating whether agents can skip OAuth client registration, start here — and stay honest that it is an individual draft.

At a glance

Problem
OAuth 2.0 and OpenID Connect assume pre-registered clients, browser redirects, bearer tokens, and static scopes. Agents discover resources at runtime, need their own cryptographic identity (not just a client_id minted by each AS), must prove possession of a key on every call, and often need mid-task human governance that cannot be reduced to a scope string.
Identity / authn / authz
All three. Agent tokens are identity (who the agent is). HTTP Message Signatures are authentication (proof of the key). Auth tokens, resource tokens, missions, and R3 grants are authorization (what it may do, for whom). AAuth complements OAuth/OIDC rather than claiming to obsolete them.

Actors

  • Agent (any HTTP client with a key and agent token)
  • Agent provider (issues the agent token, hosts JWKS)
  • Resource
  • Person server (PS) — optional user representative
  • Access server (AS) — optional resource-side policy engine
  • User / person

In one board · AAuth access modes

Restage the hop

Draft-10·Draft-10 §4.1.1 — the AAuth meaning of p2p

Agent and resource only. The resource decides from who the agent is. No person server, no access server, no grant of operations.

AgentUserResourcePerson serverAccess server
  • Agent

    Signed HTTP · local policy

    Resource

Which passes exist

aa-agent+jwtsessionaa-person+jwtaa-resource+jwtaa-auth+jwt

Dimmed tickets are not in this mode. Sealed tickets ride with a wax seal (RFC 9421). The session is a photocopy-proof opaque pass: the agent cannot open it.

The resource learns which agent called — not which human it serves. That is p2p in the AAuth sense, not A2A and not did:peer.

Draft-10 (6 August 2026) has four modes. Person-identity and aa-person+jwt are the editor's fifth. Individual Internet-Draft — not an RFC, not an OAuth WG document. AAuth vs OAuth.

01

The gap for agents

OAuth 2.0 and OpenID Connect were designed for applications that a human installs or a developer pre-registers: a client_id minted by each authorization server, a browser redirect for consent, a bearer access token, and a static scope string. An AI agent that discovers a new HTTP resource at runtime has none of those luxuries. It is not a user. It is not a workload identity inside one mesh. It is an HTTP client that must prove who it is to a stranger, then obtain a grant that may involve a human mid-task.

The gap AAuth names is therefore four principals, not one: the user (person), the agent instance (cryptographic identity), the resource (the tool or API), and optionally a resource-side access server. Vanilla OAuth collapses the agent into 'the client' and gives it no portable identity. SPIFFE/WIMSE name the binary inside a trust domain but do not, by themselves, get the agent accepted at an arbitrary internet resource or carry user consent. MCP authorization reuses OAuth 2.1 for host-to-tool access and still assumes an AS that will issue a client identifier.

AAuth's premise, quoted from draft-10's introduction, is that every agent has its own cryptographic identity: an identifier of the form aauth:local@domain bound to a signing key, published at a well-known URL, verifiable by any party — no pre-registration, no shared secrets, no dependency on a particular server. At its simplest the agent signs a request and the resource decides from who the agent is. That identity-based access is the foundation; authorization, governance, and federation are additive.

02

Actors and trust boundaries

The agent is any HTTP client with a key and an agent token. It trusts its agent provider (who issued the agent token and hosts JWKS) and, if it has one, its person server. It does not have to trust the resource's access server until a four-party hop; it never treats a resource-issued opaque session token as something it can inspect.

The agent provider is an identity issuer, not an OAuth authorization server. It attests 'this key speaks for this agent identifier'. Compromise of the provider's signing key is compromise of every agent it vouches for. The resource fetches the provider's JWKS via the token's iss and dwk; that fetch is a trust-boundary crossing (SSRF, mix-up of iss, stale JWKS).

The resource is the verifier of signatures and the enforcer of its own policy. In identity-based and resource-managed modes it never talks to a person server. In three-party mode it issues a resource token whose audience is the person server and later verifies an auth token whose issuer is that PS. In four-party mode the resource token's audience is the resource's own access server; the PS federates to that AS. The resource must not confuse a person token (identity of the user) with an auth token (a grant).

The person server represents the user: consent, missions, permission/audit/interaction relay. It is the only party that calls an access-server token endpoint in four-party mode. The user/person authenticates to the PS or to the resource's own login, never by handing a password to the agent. Draft-10 treats the PS as optional; an agent without a ps claim cannot complete auth-token flows.

The access server (AS in AAuth's vocabulary) is a resource-side policy engine, not the user's IdP. Do not mash it together with an OIDC OP. Four-party federation is PS → resource AS, which is also not OpenID Federation 1.1.

03

Mechanics

Wire authentication is HTTP Message Signatures (RFC 9421) plus HTTP Signature Keys (draft-hardt-httpbis-signature-key). Every signed request carries Signature-Key, Signature-Input, and Signature. AAuth presents the agent token (or, in the editor's copy, a person token or auth token) in Signature-Key with scheme=jwt. The cnf.jwk in that JWT is the signing key; a stolen JWT without the private key cannot produce a valid signature.

Challenges replace browser redirects. A 401 carries AAuth-Requirement (for example requirement=agent-token, interaction, or auth-token). AAuth-Capabilities advertises what the resource can do. Subsequent resource-managed calls may present an opaque session via Authorization: AAuth <token> and/or AAuth-Access. AAuth-Mission can bind a content-addressed mission. These header names are from the draft; do not invent parallel names.

Well-known documents are discovered with the dwk ('dot well-known') parameter from Signature-Key: aauth-agent.json, aauth-resource.json, aauth-person.json, aauth-access.json at {iss}/.well-known/{dwk}. Resource metadata may declare access_mode (advisory): in draft-10 the values are agent-token, aauth-access-token, and auth-token. The editor's copy adds person-token and renames the opaque credential a session token (session-token).

JWT types in draft-10: aa-agent+jwt (identity of the agent; sub is the agent identifier; cnf.jwk binds the key; optional ps names the person server), aa-resource+jwt (issued by the resource to describe the access that needs authorizing; aud is the PS or AS that may redeem it; recommended lifetime five minutes or less), aa-auth+jwt (the grant; iss is PS or AS; aud is the resource; user claims such as sub, optional email/tenant/groups/roles; consented scope or R3 grants; cnf bound to the agent's key; MUST NOT exceed one hour). The editor's copy adds aa-person+jwt: a directed identifier of the person at one resource. It identifies; it does not authorize. A recipient MUST reject aa-person+jwt wherever an auth token is required.

Person-server endpoints in draft-10 include a token_endpoint that accepts a resource token and returns an auth token (or 202 + interaction if the user must approve). The editor's copy splits this: person_token_endpoint (REQUIRED) and auth_token_endpoint (renamed from token_endpoint). Four-party: the PS discovers {aud}/.well-known/aauth-access.json and calls the AS token endpoint. Auth tokens reuse RFC 8693 act for delegation chains. Call chaining uses upstream_token / subagent_token so a sub-agent signs with its own key while nested act records the parent.

Governance is orthogonal to access mode. Missions are natural-language (Markdown) intent, immutable via s256. Permission, audit, and interaction relay through the PS even when the resource is in identity-based mode. R3 (companion draft) replaces coarse scopes with vocabulary operations, including per-call approval.

typ: aa-agent+jwtfrom spec
Quoted from draft-10: agent identity JWT. sub is the agent identifier (aauth:local@domain). cnf.jwk is the signing key. Optional ps names the person server. Lifetime SHOULD NOT exceed 24 hours in the editor's copy.
typ: aa-auth+jwtfrom spec
Quoted from draft-10: the grant. Required payload claims include iss, dwk, aud (the resource), jti, agent, cnf.jwk, iat, exp. Lifetime MUST NOT exceed 1 hour. Optional act, user claims, scope / R3 fields, mission_s256.
typ: aa-resource+jwtfrom spec
Quoted from draft-10: issued by the resource; aud is the PS (three-party) or AS (four-party). Short-lived (five minutes recommended). Carries what needs authorizing so the PS/AS can show consent UX.
typ: aa-person+jwtfrom spec
Quoted from the editor's copy (absent from draft-10's four-mode table): directed person identifier at one resource. Identifies, does not authorize. MUST NOT be accepted where an auth token is required.
AAuth-Requirement / AAuth-Access / AAuth-Capabilitiesfrom spec
Quoted header names from draft-10. Challenges, opaque session/auth presentation, and capability discovery. Not WWW-Authenticate: Bearer.
Signature-Key: scheme=jwtfrom spec
Quoted usage: the JWT (agent, and in the editor's copy person or auth token) rides in Signature-Key. Cover the signature-key component in the RFC 9421 signature base so the header cannot be swapped.
access_mode=agent-token | aauth-access-token | auth-tokenfrom spec
Quoted from draft-10 resource metadata. Advisory. Editor's copy registry: agent-token, person-token, session-token, auth-token (R3 adds per-call).
Authorization: AAuth <session>illustrative
Illustrative of resource-managed presentation in draft-10 examples. The session is opaque to the agent; the signature still binds the request. Do not copy example token values from blogs as test vectors.

04

Step-by-step flows

Flow 1 of 5

Identity-based (peer) — no PS, no AS

Draft-10 §4.1.1 / editor 'agent identity'. The resource decides from cryptographic agent identity alone. This is the AAuth meaning of p2p.

  1. 1

    Agent provider issues aa-agent+jwt bound to the agent's signing key and publishes JWKS at the well-known document named by dwk.

  2. 2

    Agent sends a signed HTTP request: Signature-Key (scheme=jwt, the agent token) + Signature-Input + Signature covering method, authority, path, and the key-identifying header.

  3. 3

    Resource verifies RFC 9421, checks typ, exp, cnf.jwk against the signature, and fetches/caches issuer JWKS if needed.

  4. 4

    Resource applies local policy to the agent identifier (allow, deny, or rate-limit). No token exchange, no redirect, no person server.

  5. 5

    If the request lacked an AAuth agent token, the resource MAY 401 with requirement=agent-token.

The resource learns who the agent is, not which human it serves. For user claims, step up to resource-managed, person-identity (editor), or PS-asserted mode.

Flow 2 of 5

Resource-managed (two-party)

Draft-10 §4.1.2. Still no external AS. The resource runs consent, account linking, or payment itself.

  1. 1

    Agent makes a signed call with its agent token.

  2. 2

    Resource returns 401 or 202 with AAuth-Requirement describing interaction (URL, wait, etc.). First call can be registration.

  3. 3

    User completes the resource's own page — which MAY wrap ordinary OAuth/OIDC behind the resource.

  4. 4

    Resource issues an opaque session (draft-10: via AAuth-Access; editor: session token) bound to the agent's signature.

  5. 5

    Subsequent calls: HTTP signature plus the opaque credential. Stolen session without the key should not replay.

Two-party is p2p in the sense of agent↔resource, not DIDComm. The resource may stuff an OAuth access token inside the opaque session; the agent must not fish it out and replay it as Bearer elsewhere.

Flow 3 of 5

Person-identity (editor's copy only)

Editor's fifth mode. Not in draft-10's four-mode table. Resource accepts who the person is from the PS, without a grant of operations.

  1. 1

    Agent token carries ps. Resource challenges with requirement=person-token (editor).

  2. 2

    Agent calls the PS person_token_endpoint with resource, mission_s256, optional subagent/upstream tokens.

  3. 3

    PS authenticates the person (if needed) and issues aa-person+jwt directed at that resource. Consent here is 'may this agent act at this resource as this person', not a scope list.

  4. 4

    Agent retries with the person token in Signature-Key. Resource verifies typ aa-person+jwt and serves whatever it serves to signed-in people.

  5. 5

    If a later operation needs a grant, the resource must demand an auth token; it MUST NOT treat the person token as one.

Pin the editor's copy if you implement this. Interop against draft-10 implementations that never heard of person tokens will fail closed — or worse, fail open if typ is not checked.

Flow 4 of 5

PS-asserted (three-party)

Draft-10 §4.1.3 / editor 'PS authorization'. Resource has no AS. User claims and consent come from the agent's person server.

  1. 1

    Agent signs a request. Resource sees ps on the agent token (or already has a relationship).

  2. 2

    Resource 401s with requirement=auth-token and a resource token (aa-resource+jwt, aud = PS, ~five minutes).

  3. 3

    Agent POSTs the resource token to the PS token_endpoint (editor: auth_token_endpoint), signed with the agent key.

  4. 4

    If the user must approve a mission or scope, PS returns 202 + interaction. User approves at the PS, not at the resource.

  5. 5

    PS issues aa-auth+jwt with user claims (sub, optional email/tenant/groups/roles) and consented scope or R3 grants, cnf-bound to the agent key, aud = resource, exp ≤ 1 hour.

  6. 6

    Agent retries; resource verifies the auth token (iss = PS, aud = itself, cnf matches the signature) and applies its own policy to (iss, sub).

sub is directed per issuer. The same email from two person servers is two subjects. The resource still decides what that subject may do.

Flow 5 of 5

Federated (four-party)

Draft-10 §4.1.4 / editor 'federated authorization'. Resource has its own access server. The agent still talks only to the resource and its PS.

  1. 1

    Same first call as three-party, but the resource token's aud is the resource's access server URL.

  2. 2

    Agent still POSTs the resource token to its PS. The agent does not call the AS.

  3. 3

    PS discovers {aud}/.well-known/aauth-access.json and federates to the AS token endpoint with the resource token and the agent token.

  4. 4

    AS evaluates resource policy and returns an auth token (iss = AS, dwk = aauth-access.json). PS may pass clarifications back via 202.

  5. 5

    Agent presents the auth token to the resource. Resource verifies against the AS JWKS.

This is not OpenID Federation and not identity chaining (RFC 8693 + 7523 across OAuth domains), though it rhymes. The PS is the only party that calls AS token endpoints.

05

Identity vs authentication vs authorization

Identity: the agent token says which agent; the person token (editor) and auth-token user claims say which person; (iss, sub) at the PS is the user identifier. The agent identifier is not a client_id and not a SPIFFE ID.

Authentication: RFC 9421 signatures proving possession of cnf.jwk on every request. Not bearer possession of a JWT. Signature-Key is how the verifier gets the key; it is not itself a grant.

Authorization: auth tokens, opaque sessions, missions, R3 grants, and the resource's local policy. Identity-based mode is authorization-by-identity-list at the resource. Do not call a person token an authorization.

06

How it composes

  • OAuth 2.1

    AAuth says it complements OAuth rather than replacing it. Where the API is already an OAuth 2.1 resource server (MCP included), keep PKCE, PAR, audience-restricted tokens. Use AAuth when the agent must identify itself to a resource that will not mint a client_id, or when you want signatures instead of bearer tokens.

  • OpenID Connect Core

    Auth-token user claims reuse OIDC names (sub, email, groups, roles) so identity-aware resources can keep their user model. AAuth does not issue an ID Token and does not make the resource an OpenID relying party. The person server may itself be backed by OIDC for how the human signs in.

  • HTTP Signature Keys

    Normative dependency. Without Signature-Key schemes (jwt, jwks_uri, …) and dwk well-known discovery, the resource cannot bootstrap a stranger's key on the first request.

  • HTTP Message Signatures

    The cryptographic primitive. AAuth profiles RFC 9421 rather than inventing HMAC headers. Cover @method, @authority, @path, and signature-key.

  • Token Exchange

    AAuth auth tokens may carry RFC 8693 act for parent/sub-agent chains. That is not the OAuth token-exchange grant; there is no AS token endpoint in identity-based or two-party modes. Cross-domain OAuth hops still use RFC 8693 + 7523 / identity chaining.

  • DPoP

    Different PoP. DPoP is an application-layer proof JWT on OAuth resource requests (Authorization: DPoP). AAuth uses HTTP Message Signatures. Do not stack proofs naively or skip covering the key header.

  • WIMSE architecture

    Overlapping problem, different deployment scope. WIMSE/SPIFFE name the workload inside and across systems that share trust anchors. AAuth targets open-world HTTP resources that will fetch a well-known JWKS. An agent can have both: WIT/WPT inside the mesh, AAuth at the internet resource.

  • MCP authorization

    MCP HTTP authorization is OAuth 2.1 + RFC 9728. It does not give the model a cryptographic agent identity. If an MCP server also verified AAuth signatures, that would be a profile on top — not what the 2026-07-28 MCP spec requires.

  • AAuth R3

    Optional structured authorization. Scopes remain in the core protocol; R3 is how operations in OpenAPI/MCP/GraphQL vocabularies become the grant, including per-call.

  • AIMS (agent auth BCP)

    AIMS says compose existing IETF tools (WIMSE + OAuth). AAuth says those tools are insufficient for open-world HTTP clients. Read both; they disagree on whether you need a new protocol.

07

What bites agent implementers

  • Draft-10 vs editor's five modes

    Datatracker HTML of draft-hardt-oauth-aauth-protocol-10 (6 August 2026) defines four resource access modes. The editor's copy (fetched September 2026, expires 18 March 2027) defines five, adding person-identity, aa-person+jwt, person_token_endpoint, and renaming token_endpoint → auth_token_endpoint. Implement against a pinned snapshot. Interop will fail if one side expects person tokens.

  • typ confusion (fail open)

    The editor's copy is explicit: check typ before acting on any AAuth JWT; reject aa-person+jwt where an auth token is required; deployments SHOULD test this because it fails open. Mixing agent, person, resource, and auth tokens in the same slot is the local analogue of using an ID Token as an access token.

  • Sender constraint is the signature

    If you accept the JWT from Signature-Key without verifying RFC 9421 over the request and the key header, you have reinvented bearer tokens. Cover signature-key in the signature base.

  • Audience and confused deputy

    Auth tokens are audience-restricted to the resource. Resource tokens are audience-restricted to the PS or AS. Presenting an auth token minted for resource A at resource B is a confused-deputy bug. Missions bind intent via s256; do not let the agent swap mission text after approval.

  • Overbroad act / call chaining

    Nested act records parent agents. Attenuate what a sub-agent may do. Draft-10 call chaining was still incomplete in some JS packages at research time. Never expand grants at a hop. Four-party AS policy must see the real agent keys, not a spoofable name.

  • Token replay and lifetime

    Resource tokens ~five minutes; auth/person tokens ≤ 1 hour; agent tokens up to ~24 hours in the editor's copy. Revocation is best-effort via endpoints; verifiers check signatures locally and may not hear a revoke. The editor recommends refreshing when fewer than five minutes remain. Clock skew: exp is judged by the verifier with no tolerance in the editor's copy.

  • Mix-up of iss / dwk / well-known fetch

    The resource fetches JWKS from a URL derived from iss + dwk. Validate TLS, bind iss, and do not let an attacker point dwk at an unexpected host (SSRF). This is the AAuth-shaped cousin of OAuth mix-up.

  • Individual draft, not a WG item

    Not endorsed by the IETF, no RFC number, intended standards track only as a personal statement. Do not tell compliance it is 'the IETF agent standard'. Pin revisions. Complements OAuth; does not obsolete RFC 9700.

08

Stability — what you can ship

Published snapshot: draft-hardt-oauth-aauth-protocol-10, 6 August 2026, expires 7 February 2027, individual Internet-Draft, replaces draft-hardt-aauth-protocol. Author: D. Hardt (Hellō). Datatracker: https://datatracker.ietf.org/doc/draft-hardt-oauth-aauth-protocol/. HTML: draft-hardt-oauth-aauth-protocol-10.

Editor's copy at https://dickhardt.github.io/AAuth/draft-hardt-oauth-aauth-protocol.html (fetched 15 September 2026) is ahead: five modes, person tokens, endpoint renames. aauth.dev and explorer.aauth.dev track the moving copy. Implementations (TypeScript @aauth/*, .NET AAuth NuGet samples) exist at exploratory maturity.

What you can ship today: experiment behind a pin; do not bet a compliance program on wire stability. For production user-delegated APIs, ship OAuth 2.1 + RFC 9700 now and keep AAuth in the evaluation track. Re-read datatracker before every release.

Catalog claims (short form)

aa-agent+jwt
Agent identity. sub is the agent identifier (aauth:local@domain). cnf.jwk binds the signing key. Optional ps claim names the person server.
aa-person+jwt
Directed identifier of the person at one resource. Identifies, does not authorize. Editor's copy discusses this more than draft-10's four-mode table.
aa-resource+jwt
Issued by the resource to describe the access that needs authorizing; aud is the PS or AS that may redeem it.
aa-auth+jwt
The grant. Carries user claims (sub, optional email/tenant/groups/roles) and consented scope or R3 grants. Bound to the agent's key.
AAuth-Requirement / AAuth-Access / AAuth-Capabilities
HTTP headers for challenges, session/auth presentation, and capability discovery.

Implementer notes

Individual Internet-Draft: not a WG document, not endorsed by the IETF, no RFC number. Draft-10 (6 August 2026) describes four resource access modes. The editor's copy and aauth.dev describe five (adding person-identity) — treat the datatracker HTML as the published snapshot and the editor's copy as moving. Replaces earlier draft-hardt-aauth-protocol. Complements OAuth: where pre-registered clients and bearer tokens work, keep them. Implementations exist (TypeScript @aauth/*, .NET samples) but several features (call chaining, four-party federation) were still incomplete in the JS packages at research time. Do not implement from blog posts; read the draft.

Relationship to others

Primary sources

  • Datatrackerhttps://datatracker.ietf.org/doc/draft-hardt-oauth-aauth-protocol/
  • HTML of draft-10https://datatracker.ietf.org/doc/html/draft-hardt-oauth-aauth-protocol-10
  • Editor's copyhttps://dickhardt.github.io/AAuth/draft-hardt-oauth-aauth-protocol.html
  • aauth.devhttps://www.aauth.dev/
  • Protocol explorerhttps://explorer.aauth.dev/
  • Sourcehttps://github.com/dickhardt/AAuth