Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/lib/components/JointSequence.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@
return cursorY;
});
const H = Math.max(cursorY + STEP_GAP, minHeight);
// Lifelines stop just past the last message rather than running to the bottom of the
// box. Diagrams share one height (minHeight) so switching tabs doesn't shift the page;
// without this a short diagram trails dashed lines through the reserved space.
const lifelineEnd = Math.min(H - 10, cursorY + STEP_GAP - 10);

const graph = new joint.dia.Graph({}, { cellNamespace: joint.shapes });
const paper = new joint.dia.Paper({
Expand All @@ -124,7 +128,7 @@
xs.forEach((x) => {
const line = new joint.shapes.standard.Link({
source: { x, y: TOP_PAD + ACTOR_H },
target: { x, y: H - 10 },
target: { x, y: lifelineEnd },
attrs: {
line: {
stroke: theme.lifeline,
Expand Down
93 changes: 76 additions & 17 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -131,27 +131,53 @@
{
name: 'Resource Managed',
parties: 'Agent + Resource',
desc: 'Bridge to OAuth 2.0 — the resource handles authorization via its existing OAuth AS,<br>and returns an opaque AAuth Access Token the agent presents on repeat calls with DPoP.',
desc: 'Bridge to OAuth 2.0 — the resource runs its own authorization flow and returns a <b>session token</b>,<br>the one credential a resource issues for its own consumption, bound to the agent&rsquo;s signature.',
steps: [
{ from: 'Agent', to: 'Resource', lines: ['HTTPSig w/ agent_token'] },
{ from: 'Resource', to: 'Agent', lines: ['202 (interaction required)'], dashed: true },
{ note: 'user completes interaction' },
{ from: 'Agent', to: 'Resource', lines: ['GET pending URL'] },
{ from: 'Resource', to: 'Agent', lines: ['200 OK', 'AAuth-Access: opaque-token'], dashed: true },
{ from: 'Agent', to: 'Resource', lines: ['HTTPSig w/ agent_token', 'Authorization: AAuth opaque-token'] },
{ from: 'Resource', to: 'Agent', lines: ['200 OK', 'AAuth-Access: session-token'], dashed: true },
{
from: 'Agent',
to: 'Resource',
lines: [
'HTTPSig w/ agent_token',
'Authorization: AAuth session-token',
'signature covers authorization'
]
},
{ from: 'Resource', to: 'Agent', lines: ['200 OK'], dashed: true }
]
},
{
name: 'Person Identity',
parties: 'Agent + Resource + Person Server',
desc: "Federated login for agents — the Person Server issues a person token for one resource,<br>and the resource serves on the person's identity alone. No resource token, no auth token.",
steps: [
{ from: 'Agent', to: 'Person Server', lines: ['HTTPSig w/ agent_token', 'POST /person w/ {resource}'] },
{ from: 'Person Server', to: 'Agent', lines: ['person_token'], dashed: true },
{ from: 'Agent', to: 'Resource', lines: ['HTTPSig w/ person_token', 'GET /api/documents'] },
{ from: 'Resource', to: 'Agent', lines: ['200 OK'], dashed: true }
]
},
{
name: 'Person Server Managed',
parties: 'Agent + Resource + Person Server',
desc: "Native AAuth — the resource requires the user's identity or consent (or both).<br>The user's Person Server issues an auth token after the user approves.",
desc: "Native AAuth — the resource needs an authorization decision, not just the person's identity.<br>It issues a resource token bound to that person token; the Person Server returns an auth token.",
steps: [
{ from: 'Agent', to: 'Resource', lines: ['HTTPSig w/ agent_token', 'POST /authorize'] },
{ from: 'Resource', to: 'Agent', lines: ['resource_token', '(aud = Person Server URL)'], dashed: true },
{ from: 'Agent', to: 'Person Server', lines: ['HTTPSig w/ agent_token', 'POST /token w/ resource_token'] },
{ from: 'Agent', to: 'Person Server', lines: ['HTTPSig w/ agent_token', 'POST /person w/ {resource}'] },
{ from: 'Person Server', to: 'Agent', lines: ['person_token'], dashed: true },
{ from: 'Agent', to: 'Resource', lines: ['HTTPSig w/ person_token', 'POST /authorize'] },
{
from: 'Resource',
to: 'Agent',
lines: ['resource_token', '(aud = Person Server URL)', 'ps / sub / person_token_jti'],
dashed: true
},
{ from: 'Agent', to: 'Person Server', lines: ['HTTPSig w/ agent_token', 'POST /auth_token w/ resource_token'] },
{ from: 'Person Server', to: 'Agent', lines: ['auth_token'], dashed: true },
{ from: 'Agent', to: 'Resource', lines: ['HTTPSig w/ auth token', 'GET /api/documents'] },
{ from: 'Agent', to: 'Resource', lines: ['HTTPSig w/ auth_token', 'GET /api/documents'] },
{ from: 'Resource', to: 'Agent', lines: ['200 OK'], dashed: true }
]
},
Expand All @@ -160,15 +186,45 @@
parties: 'Agent + Resource + Person Server + Access Server',
desc: "Cross-domain AAuth — the resource has its own Access Server that federates with the agent's Person Server.<br>Authorization works across org and cloud boundaries without pre-registration.",
steps: [
{ from: 'Agent', to: 'Resource', lines: ['HTTPSig w/ agent_token', 'POST /authorize'] },
{ from: 'Resource', to: 'Agent', lines: ['resource_token', '(aud = Access Server URL)'], dashed: true },
{ from: 'Agent', to: 'Person Server', lines: ['HTTPSig w/ agent_token', 'POST /token w/ resource_token'] },
{ from: 'Person Server', to: 'Access Server', lines: ['HTTPSig w/ jwks_uri', 'POST /token w/ resource_token'] },
{ from: 'Agent', to: 'Person Server', lines: ['HTTPSig w/ agent_token', 'POST /person w/ {resource}'] },
{ from: 'Person Server', to: 'Agent', lines: ['person_token'], dashed: true },
{ from: 'Agent', to: 'Resource', lines: ['HTTPSig w/ person_token', 'POST /authorize'] },
{
from: 'Resource',
to: 'Agent',
lines: ['resource_token', '(aud = Access Server URL)', 'ps / sub / person_token_jti'],
dashed: true
},
{ from: 'Agent', to: 'Person Server', lines: ['HTTPSig w/ agent_token', 'POST /auth_token w/ resource_token'] },
{ from: 'Person Server', to: 'Access Server', lines: ['HTTPSig w/ jwks_uri', 'POST /auth_token w/ resource_token'] },
{ from: 'Access Server', to: 'Person Server', lines: ['auth_token'], dashed: true },
{ from: 'Person Server', to: 'Agent', lines: ['auth_token'], dashed: true },
{ from: 'Agent', to: 'Resource', lines: ['HTTPSig w/ auth token', 'GET /api/documents'] },
{ from: 'Agent', to: 'Resource', lines: ['HTTPSig w/ auth_token', 'GET /api/documents'] },
{ from: 'Resource', to: 'Agent', lines: ['200 OK'], dashed: true }
]
},
{
name: 'Per-Call',
parties: 'Agent + Resource + Person Server + Access Server',
desc: "R3 per-call authorization — the resource challenges one invocation with a proposal carrying that call's<br>concrete parameters. The person approves them, and the retry is verified against what was approved.",
steps: [
{ from: 'Agent', to: 'Resource', lines: ['HTTPSig w/ person_token', 'POST /send_email (r3_per_call)'] },
{
from: 'Resource',
to: 'Agent',
lines: ['401 + resource_token', 'r3_uri/r3_s256 → per-call proposal'],
dashed: true
},
{ from: 'Agent', to: 'Person Server', lines: ['HTTPSig w/ agent_token', 'POST /auth_token w/ resource_token'] },
{ from: 'Person Server', to: 'Access Server', lines: ['HTTPSig w/ jwks_uri', 'POST /auth_token w/ resource_token'] },
{ from: 'Access Server', to: 'Resource', lines: ['GET r3_uri (signed)'] },
{ from: 'Resource', to: 'Access Server', lines: ['proposal: operation + parameters'], dashed: true },
{ note: 'person approves these exact parameters' },
{ from: 'Access Server', to: 'Person Server', lines: ['auth_token (r3_granted: this call)'], dashed: true },
{ from: 'Person Server', to: 'Agent', lines: ['auth_token'], dashed: true },
{ from: 'Agent', to: 'Resource', lines: ['HTTPSig w/ auth_token', 'POST /send_email (same parameters)'] },
{ from: 'Resource', to: 'Agent', lines: ['200 OK', 'parameters verified vs proposal'], dashed: true }
]
}
];

Expand All @@ -181,7 +237,7 @@
status: 'Internet-Draft',
href: 'https://datatracker.ietf.org/doc/draft-hardt-oauth-aauth-protocol',
editorsCopy: 'https://dickhardt.github.io/AAuth/draft-hardt-oauth-aauth-protocol.html',
desc: 'The authorization protocol for agent-to-resource access. Four access modes, three token types, agent governance, missions, clarification chat, and call chaining.',
desc: 'The authorization protocol for agent-to-resource access. Five access modes, four token types, agent governance, missions, clarification chat, and call chaining.',
primary: true,
indent: false
},
Expand All @@ -199,7 +255,7 @@
status: 'Exploratory',
href: 'https://dickhardt.github.io/AAuth/draft-hardt-aauth-r3.html',
editorsCopy: null,
desc: 'Vocabulary-based authorization using formats agents already understand (MCP, OpenAPI, gRPC, GraphQL).',
desc: 'Vocabulary-based authorization using formats agents already understand (MCP, OpenAPI, gRPC, GraphQL), plus per-call proposals for operations authorized one call at a time.',
primary: false,
indent: true
}
Expand Down Expand Up @@ -562,8 +618,9 @@
<InView>
<h2 class="text-3xl md:text-4xl font-bold mb-4 uppercase">How AAuth Works</h2>
<p class="text-[var(--color-text-muted)] mb-4 text-lg">
AAuth has four access modes. All replace API keys with cryptographic identity.<br class="hidden sm:inline" />
Capability grows from simplest to most capable — adopt incrementally as your needs expand.
AAuth has five access modes. All replace API keys with cryptographic identity.<br class="hidden sm:inline" />
They differ in what the resource ends up knowing and which party established it — adopt incrementally as your needs expand.<br class="hidden sm:inline" />
Per-call authorization, from R3, governs a single action rather than a class of access.
</p>
</InView>

Expand Down Expand Up @@ -638,8 +695,10 @@
<div class="mt-4 flex justify-start">
<ul class="text-xs text-left text-[var(--color-text-dim)] space-y-1 font-mono list-none">
<li><span class="text-[var(--color-text-muted)]">agent_token</span> establishes the agent's identity</li>
<li><span class="text-[var(--color-text-muted)]">person_token</span> names the person the agent acts for, at one resource</li>
<li><span class="text-[var(--color-text-muted)]">resource_token</span> describes the access needed</li>
<li><span class="text-[var(--color-text-muted)]">auth_token</span> grants an agent access to a resource</li>
<li><span class="text-[var(--color-text-muted)]">session-token</span> issued by a resource for its own consumption, opaque to the agent</li>
<li><span class="text-[var(--color-text-muted)]">jwks_uri</span> Person Server's JWKS endpoint, discovered via well-known metadata</li>
</ul>
</div>
Expand Down
10 changes: 6 additions & 4 deletions static/llms.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# AAuth

> AAuth is an authorization protocol for agent-to-resource authorization and identity claim retrieval, supporting four resource access modes with agent governance as an orthogonal layer.
> AAuth is an authorization protocol for agent-to-resource authorization and identity claim retrieval, supporting five resource access modes with agent governance as an orthogonal layer.

## What is AAuth?

Every agent — any HTTP client — gets its own cryptographic identity: a domain, static metadata, and a JWKS. No pre-registration, no shared secrets, no dependency on a particular server. An agent signs a request and a resource decides what to do based on who the agent is.

AAuth supports four resource access modes (identity-based, resource-managed, PS-managed, federated), each adding parties and capabilities. Adoption does not require coordination between parties.
AAuth supports five resource access modes (agent identity, resource-managed, person identity, PS authorization, federated). They differ in what the resource ends up knowing and which party established it, not in how much of the protocol they use. Adoption does not require coordination between parties.

Four token types travel between parties: the agent token (the agent's identity), the person token (the person the agent acts for, at one resource), the resource token (the access a resource needs authorized), and the auth token (the grant). A resource may additionally issue a session token for its own consumption, opaque to the agent, returned in `AAuth-Access` and presented back in `Authorization: AAuth`.

## Walk an Agent Through AAuth (Start Here)

Expand All @@ -25,9 +27,9 @@ The demos run against the Hello beta Person Server; data is reset regularly.

## Specifications

- [AAuth Protocol (Internet-Draft)](https://datatracker.ietf.org/doc/draft-hardt-oauth-aauth-protocol/) — current version: [draft-hardt-oauth-aauth-protocol-01](https://datatracker.ietf.org/doc/html/draft-hardt-oauth-aauth-protocol-01). The authorization protocol. Four access modes, three token types, agent governance with missions, clarification chat, and call chaining.
- [AAuth Protocol (Internet-Draft)](https://datatracker.ietf.org/doc/draft-hardt-oauth-aauth-protocol/) — the datatracker page always resolves to the latest published version; the [editor's copy](https://dickhardt.github.io/AAuth/draft-hardt-oauth-aauth-protocol.html) tracks the working draft. The authorization protocol. Five access modes, four token types, agent governance with missions, clarification chat, and call chaining.
- [HTTP Signature Keys (Internet-Draft)](https://datatracker.ietf.org/doc/draft-hardt-httpbis-signature-key/): Foundation layer. Well-known key discovery, `Signature-Key` header for conveying public keying material alongside HTTP Message Signatures (RFC 9421).
- [R3 — Rich Resource Requests (Exploratory)](https://dickhardt.github.io/AAuth/draft-hardt-aauth-r3.html): Vocabulary-based authorization using formats agents already understand (MCP, OpenAPI, gRPC, GraphQL).
- [R3 — Rich Resource Requests (Exploratory)](https://dickhardt.github.io/AAuth/draft-hardt-aauth-r3.html): Vocabulary-based authorization using formats agents already understand (MCP, OpenAPI, gRPC, GraphQL), plus per-call proposals for operations authorized one call at a time.

## Implementations

Expand Down