Skip to content

test(interop): assert each AUTH cell's grant and refuse a publish outside it - #4181

Merged
kixelated merged 3 commits into
quest/m1/auth/READMEfrom
quest/m1/auth/interop
Sep 26, 2026
Merged

kixelated merged 3 commits into
quest/m1/auth/READMEfrom
quest/m1/auth/interop

Conversation

@kixelated

Copy link
Copy Markdown
Collaborator

Problem

The interop matrix ran the relay with public = "**" and checked media alone. A relay that sent a malformed AUTH_OK, or none, left the client with no grant and every cell still passed. Nothing checked that a publish outside the grant fails loud.

Approach

  • The relay now verifies tokens through moq auth serve with a key generated per run; nothing is anonymous. Each publisher dials with --publish '<broadcast>/**' and each subscriber with --subscribe '<broadcast>/**', so every client also covers the ?jwt= URL.
  • moq_net::auth logs one auth granted publish=[...] subscribe=[...] debug line per AUTH_OK. The native JS subscriber prints the same line from connection.auth.grant. The harness enables the log for moq-cli (RUST_LOG=...,moq_net::auth=debug) and fails a Rust or native JS cell whose last grant is missing or differs from the token, even if media flowed.
  • After the matrix, each enforcing publisher (Rust, browser) runs once more with a token for interop-allowed-<pid>/** only. It passes only if the publisher log names the broadcast on the "publishing outside our grant" line and says Unauthorized, every subscriber times out, and the publisher's printed grant matches its token. The check reads the session close, not a stream code, so it holds whether or not the dedicated UNAUTHORIZED reset lands.
  • --negative and --media get tokens too (media uses one ** token).
  • Tokens grant subtrees because lite-06 AUTH_OK carries prefixes. The relay withholds a literal grant it cannot encode, so the client sees none (checked by hand: a b1.hang token reads as auth token ended err=unsupported).
  • Deletes the quest and points bindings.md at prints_grant / enforces_grant, which is where the binding clients join.

Sensitivity check: swapping the relay's grant halves in lite/session.rs fails every Rust and native JS cell with grant: got ..., token implies ....

Impact

  • No public API or wire change.
  • moq-net: a new debug log line (moq_net::auth, "auth granted") per AUTH_OK received.
  • test/interop/interop.toml: token auth (auth.url) replaces anonymous access.

Alternatives

  • Adding moq_tokio::Connection::auth() for moq-cli to print the grant. Not done: Relay tokens owns that accessor and plans a different shape.
  • Exposing a grant on the browser's shared @moq/net Connection. Not done: it deliberately keeps its session private, so the browser cells check media and the refusal only.
  • Keeping public = "**" beside the tokens. Rejected: a client that silently dropped its token would still pass.

Follow-ups

  • Local just test interop --all: every Rust, browser, native JS, C, and GStreamer cell passed, plus both refusal rounds. The Python and Go clients are unavailable because main's moq-ffi fails to compile (E0283, waiting on fix(ffi): name the binary config conversion so moq-ffi compiles #4157). js -> js failed once when the canvas intercepted the pause click, then passed on two reruns: a UI flake unrelated to auth.
  • A negative round adds about one --timeout per enforcing publisher (about 60s with --all).
  • Two concurrent nix develop runs can pick the same port: the harness keeps its port reservations under the per-shell TMPDIR. This predates the PR.

(Written by Claude Opus 5.5)

🤖 Generated with Claude Code

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-26T03:36:17.813920Z 6bb0e4b Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

kixelated and others added 3 commits September 25, 2026 20:30
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…side it

Every interop client now dials with a token minted for its cell and verified
by `moq auth serve`. The Rust CLI (a new `moq_net::auth` debug log per
AUTH_OK) and the native JS subscribers print the grant they received, and the
harness fails the cell unless it matches the token. A final round per
enforcing publisher (Rust, browser) mints a token that excludes its broadcast:
the publisher must fail loud with Unauthorized naming the path, and every
subscriber must see nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated force-pushed the quest/m1/auth/interop branch from 435129e to 6bb0e4b Compare September 26, 2026 03:31

Copy link
Copy Markdown
Collaborator Author

Rebased onto quest/m1/auth/README and named the binary config at the two catalog calls (moq_mux::binary::Config::from(config)). Check, Test, and Interop all died on E0283 in moq-ffi, which also left the Python and Go interop clients unbuilt. Same annotation as #4157.

@codex review

(Written by Grok 4.7)

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

Reviewed commit: 6bb0e4b7f2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@kixelated
kixelated merged commit 29463bf into quest/m1/auth/README Sep 26, 2026
18 of 20 checks passed
@kixelated
kixelated deleted the quest/m1/auth/interop branch September 26, 2026 03:41

Copy link
Copy Markdown
Collaborator Author

Squash-merged onto quest/m1/auth/README as 29463bfe. Codex completed on 6bb0e4b with no findings. The quest base does not require Check or Test, so --squash --auto merged while those jobs were still running.

After the merge:

  • Test passed.
  • Check failed: test/interop/README.md is not formatted (just _markdown check).
  • Interop got past the moq-ffi E0283 (the matrix step finished). just test media then failed late join: frame 111, 16 frames behind 127, and the budget is one GOP (15).

(Written by Grok 4.7)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant