Skip to content

Add AAuth R3 (Rich Resource Requests) support: SDK + GuidedTour 10th scenario #35

Description

@nedruk

Summary

Implement AAuth Rich Resource Requests (R3) end-to-end and showcase it as a new 10th scenario in the GuidedTour interactive tutorial. R3 replaces opaque scope strings with vocabulary-based, content-addressed authorization: resources publish R3 documents, agents request operations in a vocabulary they already understand (MCP), the Person Server renders human-readable `display` for consent, the Access Server evaluates `operations` and mints `r3_granted`/`r3_conditional` grants, and the resource enforces directly from the auth token.

The work runs against live mock servers (closest-to-reality), on the Calendar resource, using the MCP vocabulary, and includes the conditional / per-call proposal arc with digest-matched enforcement.

⚠️ Experimental. R3 is an AAuth Exploratory Draft (`aauth-spec/v02/draft-hardt-aauth-r3.md`) with no known implementations. The scenario and docs are flagged experimental and may change as the draft evolves.

Motivation

Scopes like `calendar:write` are limited in three ways the spec calls out: (1) not human-comprehensible for consent, (2) don't name the exact operations authorized, (3) don't pin which authorization definition was approved (audit). R3 addresses all three via vocabularies, content-addressed R3 documents, and vocabulary-based grants the resource enforces without introspection.

Scope decisions (agreed)

Decision Choice
Reality tier Live mock servers (real HTTP, real tokens)
Vocabulary MCP only (`urn:aauth:vocabulary:mcp`)
SDK Real R3 types/claims added to `src/AAuth`
Resource Calendar (`:5001`)
Access Server MockAccessServer (`:5500`)
Person Server MockPersonServer (`:5100`)
Conditional arc Included (per-call proposal + digest match)
Mission interplay Orthogonal (standalone flow)

Note (v02): `r3_s256` hashes the verbatim bytes served — no canonicalization. RFC 8785 / JCS is not required (dropped in the v02 spec migration).

Part 1 — SDK update (`src/AAuth`)

  • 1.1 Hash primitive — `R3Hash` = `base64url(SHA-256(bytes))`, no padding, over verbatim serialized bytes; vector-tested against spec examples.
  • 1.2 Models — `R3Document`, `McpOperation`, `R3Operations`, `R3Display`, `R3Grant`, MCP vocabulary constant; JSON round-trip + `display.summary` validation.
  • 1.3 Token claims — `ResourceTokenBuilder` emits `r3_uri`+`r3_s256` (both or neither); `AuthTokenBuilder` emits `r3_uri`/`r3_s256`/`r3_granted`/`r3_conditional`; `TokenVerifier` surfaces them.
  • 1.4 Resource metadata + R3 endpoint + enforcement — `r3_vocabularies` in well-known metadata; AS-signature-gated R3-document endpoint (rejects non-AS = agent opacity); `r3_granted`/`r3_conditional` enforcement; per-call proposal store (persist bytes by `r3_s256`).
  • 1.5 Agent-side request — carry `r3_operations` in the authorize/exchange body; surface grants; drive the conditional per-call round-trip.

Exit: `src/AAuth` builds 0/0; unit + conformance tests green; no GuidedTour/live-server dependency in the SDK.

Part 2 — Demo (live servers + GuidedTour)

  • 2.1 Calendar speaks R3 — advertise MCP vocabulary; map `r3_operations` → R3 doc; emit `r3_uri`/`r3_s256`; serve AS-gated `/r3/{hash}`; per-call proposal on `create_calendar_event`; enforce grants.
  • 2.2 AS + PS processing — AS does signed R3 fetch + hash-verify + grant population + per-call eval + audit; PS renders R3 `display` at consent.
  • 2.3 GuidedTour 10th scenario — `TourMode.RichRequest` (~9 steps, server-backed): discover → request `r3_operations` → resource token (`r3_uri`/`s256`) → PS `display` consent → AS grants → granted `200` → conditional challenge → per-call approval → enforced retry `200`. Picker option docs: Add comprehensive SDK documentation and README improvements #10 + experimental blurb + per-step SDK code snippets.
  • 2.4 Wiring, E2E, docs — `make demo-tour-r3`; `rich-request.spec.ts`; bump picker count 9→10; `docs/workflows/rich-resource-requests.md`; GuidedTour README update.

Exit: full build 0/0; unit + conformance + R3 E2E green; subagent review adjudicated against v02 spec.

Security invariants to demonstrate / test

  • AS-only R3 fetch — Calendar's R3 endpoint requires a valid AS HTTP Message Signature and rejects everyone else (agent included). Enforced — not by-convention — basis of agent opacity.
  • Hash-verify before use — AS verifies `r3_s256` against fetched bytes.
  • Per-call digest binding — on the conditional retry, the resource verifies presented params' digest matches the approved proposal; mismatch rejected (no replay against different content).

Demonstrative narrative

Aria requests `list_calendar_events` + `modify_calendar_event` (granted) and `create_calendar_event` (conditional — creating an event emails attendees). The user sees the R3 `display` consequences, approves; granted calls return `200` straight from the token; creating an event triggers a per-call proposal with concrete event details, which the user approves exactly, and the resource digest-matches on retry.

Out of scope

  • Vocabularies other than MCP; vocabulary discovery parsing (MCP tool-list / OpenAPI `$metadata`).
  • Mission + R3 combined flow (orthogonal by decision; open spec gap).
  • Production AS/PS SDK roles (remain mock); RFC 8785 / JCS (removed by v02).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions