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
26 changes: 14 additions & 12 deletions quest/m1/auth/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ This questline adds an AUTH exchange to both wires: one stream per token, a
grant per token, the union of every accepted token as the session's scope,
and a loud failure when a publish can never be honored. It ends with the
credential able to travel in band, while the URL keeps working for every peer
that predates the stream. Direct peer sessions need a second credential: a
relay-signed, hop-bound grant that a browser can verify without a signing
key, which HMAC relay keys cannot provide.
that predates the stream. Hop-bound peer grants for direct sessions belong to
[P2P](/quest/m2/p2p/peer-grant.md), their only consumer.

## Plan

Expand All @@ -44,11 +43,13 @@ Decisions settled while planning, recorded so review does not relitigate them:
- **A public grant contains publish patterns, subscribe patterns, and an
expiry**, in the presenter's own root; the presenter never sees the relay-side
root, and every token in a union shares the connection's root. Unscoped
permission is `**`; an empty union grants nothing. AUTH_OK carries those
patterns, wildcards and literals alike, from the first release. There is no prefix-only AUTH_OK and no
covering-prefix workaround. Announce stays a prefix: ANNOUNCE_REQUEST and
SUBSCRIBE_NAMESPACE do not gain patterns in that change. The public grant
type stays pattern-valued.
permission is `**`; an empty union grants nothing. Lite AUTH_OK carries
those patterns, wildcards and literals alike, from the first release, with
no covering-prefix workaround. IETF AUTH_OK carries Track Namespace
prefixes, so an acceptor whose grant is not a union of subtrees answers
AUTH_ERROR NOT_SUPPORTED rather than widening it. Announce stays a prefix:
ANNOUNCE_REQUEST and SUBSCRIBE_NAMESPACE do not gain patterns. The public
grant type stays pattern-valued.
- **Fail loud by aborting the session.** A publisher whose origin announces a
broadcast outside the union aborts the session with `Unauthorized`, naming
the path. The check runs against the grants in hand once the tokens the
Expand All @@ -72,7 +73,9 @@ Decisions settled while planning, recorded so review does not relitigate them:
must explicitly grant `**` for unrestricted access; AUTH does not widen a
scoped grant because the caller is another relay.
- **Client API.** Tokens live on `moq_tokio::connect::Config`, the
dial-side config, and `Connection` exposes the live session's auth handle.
dial-side config. `Connection::auth()` is a handle the connection owns: it
keeps every added token, presents them on each session as it reconnects,
and reports the live session's grant.
- **Spec home.** The AUTH stream is lite-06 core in
`drafts/draft-lcurley-moq-lite.md`, the way routing is. moq-transport gets
`drafts/draft-lcurley-moq-auth.md`, a setup-option-negotiated extension with
Expand Down Expand Up @@ -103,11 +106,10 @@ existing lite-06 ALPN.
- [Token in band](/quest/m1/auth/token-in-band.md) - the credential can leave
the URL: a session starts on what the URL carried and its AUTH streams add
the rest, with the URL kept for peers below lite-06
- [Peer grants](/quest/m1/auth/peer-grant.md) - the relay issues a hop-bound,
asymmetrically signed grant a browser can verify; HS256 keys issue none

## Related

- [Expiring media grants](/quest/m2/processor/grant-lease.md) - a worker's
lease renewal is a new in-band token
- [P2P](/quest/m2/p2p/README.md) - the first consumer of hop-bound peer grants
- [Peer grants](/quest/m2/p2p/peer-grant.md) - P2P's hop-bound credential,
built on this line's relay tokens
2 changes: 1 addition & 1 deletion quest/m2/p2p/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ WASM build, so the browser side stays TypeScript.
## Required

- [Data channel transport](/quest/m2/p2p/transport.md) - `@moq/p2p` speaks qmux over one ordered RTCDataChannel behind the WebTransport shape `@moq/net` consumes
- [Peer grants](/quest/m2/p2p/peer-grant.md) - the relay issues a hop-bound, asymmetrically signed grant a browser can verify; HS256 keys issue none
- [Signaling and policy](/quest/m2/p2p/signal.md) - opted-in peers find each other under the prefix, the application picks who to dial, and the roster-size gate decides whether STUN is used
- [Native data channel transport](/quest/m2/p2p/webrtc.md) - `moq-tokio` holds a moq-net session with a browser over str0m with a full ICE agent
- [moq-cli joins](/quest/m2/p2p/cli.md) - `--p2p` publishes a roster entry with its iroh endpoint, dials iroh between native peers, and serves browsers as a transit hop
Expand All @@ -140,5 +141,4 @@ WASM build, so the browser side stays TypeScript.

## Related

- [Peer grants](/quest/m1/auth/peer-grant.md) - the hop-bound credential a direct session presents; HMAC keys issue none
- [E2EE](/quest/m1/e2ee/README.md) - what a peer would need if the token scope stopped being the trust boundary
10 changes: 3 additions & 7 deletions quest/m1/auth/peer-grant.md → quest/m2/p2p/peer-grant.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ against the roster, and verifies AUTH_POP with `cnf`. The origin then
serves only the granted paths. A missing, expired, HMAC-signed, or
unproven grant is not a grant.

P2P is the first consumer:
[Signaling and policy](/quest/m2/p2p/signal.md) presents the grant in band
on each direct session. This quest does not depend on that line.
on each direct session. P2P is its only consumer, so it lives on this line
rather than the auth line (decided in the 2026-09-30 audit).

Docs: `doc/bin/relay/auth.md` states that peer grants need an asymmetric
key, that HS256 operators get none, and that the public JWKS is not a
Expand All @@ -61,8 +61,4 @@ Additive.

## Required

- [Relay tokens](/quest/m1/auth/relay-refresh.md) - the relay owns AUTH and knows the session's paths

## Related

- [Signaling and policy](/quest/m2/p2p/signal.md) - the first consumer
- [In-band auth](/quest/m1/auth/README.md) - relay tokens reach `main` with this line, so the relay owns AUTH and knows the session's paths
6 changes: 3 additions & 3 deletions quest/m2/p2p/signal.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Rust, so the id in the roster is the id in every chain the tab forwards.
Roster: each peer publishes `<prefix><id>` with an `info.json` snapshot track:
the moq ALPNs it accepts, `webrtc: true`, whether it can run qmux unordered,
the presenter public key that
[peer grants](/quest/m1/auth/peer-grant.md) bind, the application's `meta`,
[peer grants](/quest/m2/p2p/peer-grant.md) bind, the application's `meta`,
and for native peers an optional `webtransport: { url, fingerprint }` and
`iroh` endpoint id. The schema is shared with
[moq-cli](/quest/m2/p2p/cli.md). Unordered is advertised here so the dialer
Expand Down Expand Up @@ -74,12 +74,12 @@ and short-lived, which the peer presents in band with a proof of possession;
the other side verifies the relay's signature, the hop id and key against
the roster, and AUTH_POP, then serves only the granted paths. Issuance,
asymmetric keys, JWKS, PoP, and refresh live in
[Peer grants](/quest/m1/auth/peer-grant.md): HMAC keys cannot be given to
[Peer grants](/quest/m2/p2p/peer-grant.md): HMAC keys cannot be given to
browsers without also letting them forge grants, so an HS256-only relay
issues nothing. A peer session with no verifiable grant serves nothing;
there is no equal-scope shortcut.

## Required

- [Data channel transport](/quest/m2/p2p/transport.md)
- [Peer grants](/quest/m1/auth/peer-grant.md) - the hop-bound, asymmetrically signed credential a direct session presents; HS256 keys issue none
- [Peer grants](/quest/m2/p2p/peer-grant.md) - the hop-bound, asymmetrically signed credential a direct session presents; HS256 keys issue none