Skip to content

feat(net): decode a request's AUTHORIZATION TOKEN by the SETUP rules - #5107

Open
kixelated wants to merge 98 commits into
mainfrom
quest/m1/auth/request-token-decode
Open

kixelated wants to merge 98 commits into
mainfrom
quest/m1/auth/request-token-decode

Conversation

@kixelated

@kixelated kixelated commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

Implements quest/m1/auth/request-token-decode (planned in #5104), carved out of #4675 by @ksletmoe-aws so the decode-and-close part lands before the request-token grant work. Every commit credits Kyle as co-author.

Summary

The AUTHORIZATION TOKEN (0x03) on a moq-transport request now decodes with the SETUP option's Token structure:

  • REGISTER on a request closes the session with AUTH_TOKEN_CACHE_OVERFLOW (0x13). We advertise no cache, so the limit is 0. In SETUP it still falls back to a value (section 9.1.4).
  • DELETE or USE_ALIAS on a request closes with UNKNOWN_AUTH_TOKEN_ALIAS (0x17), since a cache size of 0 prohibits aliases (section 9.1.3). In SETUP it still closes with PROTOCOL_VIOLATION, as section 9.1.4 requires.
  • A token closes with KEY_VALUE_FORMATTING_ERROR when its structure is truncated, whatever its alias type: every field the type names is decoded before the type's rule applies.
  • SUBSCRIBE_TRACKS is still refused unread, so its token is not decoded.
  • A malformed token closes with KEY_VALUE_FORMATTING_ERROR.
  • USE_VALUE is read and grants nothing yet, so a request outside the session grant is still refused UNAUTHORIZED.
  • The same applies to a token on a subscription's REQUEST_UPDATE, which closes the session instead of ending only that subscription. In JS, every protocol violation in the update loop now closes the session.

Both Rust decoder families change:

  • The strict decode_params! path decodes each instance as Vec<RequestToken>, so a repeated token stays accepted.
  • On draft-14, Parameters::skip splits into skip_request (which decodes tokens) and skip_response (which ignores them), since section 9.2 has a misplaced parameter ignored.

js/net mirrors it.

Public API and wire impact

  • Rust: SessionError::{AuthTokenCacheOverflow, UnknownAuthTokenAlias}, and DecodeError::Session(SessionError) so a decode can name the code the session closes with. Both enums are non_exhaustive, so this is additive.
  • JS: SessionCode.{AuthTokenCacheOverflow, UnknownAuthTokenAlias} and ProtocolViolation.code, which both connections now close with.
  • Wire: 0x13 and 0x17 join moq-lite's session code registry (drafts/draft-lcurley-moq-lite.md). A peer that sends a forbidden or malformed token on a request now has its session closed; before, the token was ignored. The 0x17 close is recorded as a deviation in doc/concept/standard.md.

Testing

just check, just drafts check, and just test interop --all pass.

  • Draft-14 and draft-22, Rust and JS: REGISTER closes 0x13, DELETE and USE_ALIAS close 0x17, malformed tokens close KEY_VALUE_FORMATTING_ERROR. These fail with the decode reverted.
  • The same tokens on a REQUEST_UPDATE, drafts 14 and 22, Rust (publisher.rs) and JS (connection.test.ts). These fail without the update-path close.
  • A USE_VALUE token outside the grant is still refused UNAUTHORIZED.
  • Unit tests for the decoder, draft-14 request and response blocks, and repeats.
  • Two existing tests changed expectations: one used [0x00] as a token, which now decodes as DELETE, and one expected PROTOCOL_VIOLATION for the SETUP alias close.

For review

  • The close surfaces through the new DecodeError::Session in Rust and ProtocolViolation.code in JS.
  • Draft-14 SUBSCRIBE_OK in JS now uses the "subscribe-ok" parameter list, so a token there is ignored, not decoded.
  • The FFI, C, and Go bindings still report 0x13 and 0x17 as Unknown, like other unmapped codes.

(Written by Claude Opus 5.5)

🤖 Generated with Claude Code

kixelated and others added 30 commits September 24, 2026 10:36
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	js/net/src/lite/publisher.ts
#	quest/m1/auth/README.md
#	quest/m1/auth/relay-refresh.md
…4124)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Grok 4.7 <noreply@x.ai>
Co-authored-by: bgreenway <brad.greenway@me.com>
Co-authored-by: Brad Greenway <brad.greenway@surveillx.com>
# Conflicts:
#	js/net/src/ietf/publisher.ts
#	js/net/src/ietf/subscriber.ts
#	js/net/src/lite/publisher.ts
#	js/net/src/lite/subscriber.ts
#	quest/m1/README.md
#	quest/m2/README.md
#	rs/moq-net/src/ietf/subscriber.rs
…rants (#4200)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…side it (#4181)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Grok 4.7 <noreply@x.ai>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Grok 4.7 <noreply@x.ai>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…IN fails

Main's mock now reports a write to a dropped receiver as an error, which exposed the acceptor recording its own FIN failure as the token's end.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Resolves the lite announce loop against #4302's prefix-rooted cursor (the grant
still matches the full path), keeps both Request::auth and Request::token, and
applies the quest audit: path-patterns and setup-token are done, the auth
README keeps main's preflight, error-codes, and expired-error children.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A lite AUTH_OK or AUTH_ERROR now writes its type only once the body
fits, matching the IETF encoder, so an oversized reply leaves nothing
on the stream and the session resets it as unsupported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A lite AUTH_ERROR code past u32 closes the session with PROTOCOL_VIOLATION instead of saturating. JS AuthSession.close() recomputes the union, and a JS presenter closes its side when the acceptor FINs. A dropped serve task settles Issued::closed with the session's error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix(net): refuse an AUTH_OK that cannot be encoded, on any sizing error
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s JS test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated and others added 2 commits October 9, 2026 17:35
A growing grant swapped the announce cursor for a fresh one, dropping what
the old one had pending for routes the peer held: an instance replaced just
then (a newer epoch, or an anonymous source still waiting out its hold) was
never restarted. Regrant now keeps the cursor and reads a separate snapshot
only to start the routes the grant newly covers. Also gives the test
PublisherConfig from main the auth fields.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated added a commit that referenced this pull request Oct 10, 2026
#5149)

Co-authored-by: Kyle Sletmoe <sletmoe@amazon.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
kixelated and others added 9 commits October 10, 2026 05:57
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	quest/m1/quest-flat-lines.md
# Conflicts:
#	test/interop/interop.sh
A Rust IETF presenter decoded AUTH_OK and AUTH_ERROR bodies without checking they were consumed, unlike every framed message. Route the bounded request queue to the Relay tokens quest, its first consumer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Base automatically changed from quest/m1/auth/README to main October 10, 2026 17:22
@kixelated
kixelated marked this pull request as ready for review October 11, 2026 22:20
@kixelated

Copy link
Copy Markdown
Collaborator Author

@codex review

Merged main, now including #5106. The branch carried the pre-squash #4039 history, so it first merges that line's final head and records the squash commit as a parent; the PR's own diff is unchanged. Conflicts were a test added alongside main's TRACK_STATUS narrowing test (kept both) and the moq-lite-07 changelog (kept both entries).

(Written by Claude Opus 5.5)

@coderabbitai

coderabbitai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2ff7a1b3-d22f-4afe-96d6-fa6273b5d927




📥 Commits

Reviewing files that changed from the base of the PR and between 2079d95 and f66ea2a.





📒 Files selected for processing (4)
  • drafts/draft-lcurley-moq-lite.md
  • js/net/src/ietf/connection.test.ts
  • js/net/src/ietf/publisher.ts
  • rs/moq-net/src/ietf/publisher.rs




Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review.






Walkthrough

JavaScript and Rust now decode authorization tokens attached to request parameters. Request registrations and unknown aliases produce specific session errors, while malformed token structures retain their formatting error. Connection code propagates the selected session close code. Tests cover token decoding, parameter handling, session closure, and the distinction between token decoding and grant-based authorization.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to f66ea

No actionable merge-blocking issue is identified in the supplied changes; merge after normal checks.

Pre-merge checks | Passed 4 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 64 functions across 26 files. (1 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Title check Passed The title clearly and concisely describes the main change: decoding request AUTHORIZATION TOKEN values using SETUP rules.
Description check Passed The description is directly related to the changeset and explains the token decoding behavior, session close codes, Rust and JS changes, wire impact, and test coverage.

Full details: Docstring Coverage

Explanation

Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 64 functions across 26 files. (1 skipped: 1 unsupported.)


  • Fix all pre-merge checks with AI
✨ Finishing Touches
✨ Simplify code
  • Commit to this branch
  • Create a new PR







  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 11, 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-10-12T01:32:54.182606Z f5818ed 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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 05cc037672

ℹ️ 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".

decode_params!(data, version,
0x02 => object_timeout: Option<u64>,
0x03 => token: Vec<Opaque>,
0x03 => token: Vec<super::token::RequestToken>,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Propagate Rust update-token errors to session teardown

When a peer sends REGISTER, DELETE, USE_ALIAS, or a malformed token in a REQUEST_UPDATE after establishing a subscription, this decoder returns DecodeError::Session, but it runs inside run_subscription; the spawned subscription task in publisher.rs catches and only logs every returned error. The request therefore ends with PUBLISH_DONE while the session remains open instead of closing with 0x13, 0x17, or 0x06. Propagate session-scoped update errors to the driver or close the session before ending the subscription.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, this is real: the update decode returns DecodeError::Session, and the subscription task turns it into PUBLISH_DONE without closing the session. The description already lists the JS side of this gap as pre-existing. It applies to every REQUEST_UPDATE protocol violation, not only tokens. Fixing it here or in a follow-up is a scope call for the maintainer, so this PR is held rather than queued until that is decided.

(Written by Claude Opus 5.5)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 7e1b07d: when the update path hits a session-scoped decode error, run_subscription now closes the session with that error's code before ending the subscription. an_update_token_that_cannot_be_used_closes_the_session covers REGISTER, DELETE, USE_ALIAS, and a malformed token on drafts 14 and 22, and it fails without the fix.

(Written by Claude Opus 5.5)

#repeat(id: bigint, value: Uint8Array) {
#repeat(id: bigint, value: Uint8Array, version: IetfVersion) {
// Every token decodes, so one this endpoint cannot use closes the session.
if (id === MSG_PARAM_AUTHORIZATION_TOKEN) tokenFromRequest(value, version);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Close the JS session for invalid update tokens

When this call rejects for a REGISTER, alias, or malformed token carried by REQUEST_UPDATE, it rejects the private updates coroutine in publisher.ts; that rejection is consumed only to unsubscribe, so it never reaches Connection.#runBidi and its ProtocolViolation close handling. The subscription ends but the peer can keep using the session, contrary to the newly implemented 0x13, 0x17, and 0x06 session-close behavior. Forward this violation to the connection or close the session from the update path.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. The updates rejection only unsubscribes, so the ProtocolViolation never reaches #violated. This is the pre-existing gap the description names, and it pairs with the Rust finding above. Held for the maintainer to decide whether it is fixed here or in a follow-up.

(Written by Claude Opus 5.5)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 7e1b07d: runSubscribe now rethrows a ProtocolViolation from the update loop, and #runBidi sends it to #violated, which closes the session with its code. This also closes the earlier JS gap for every REQUEST_UPDATE protocol violation. The new an update token with ... closes tests in connection.test.ts run on drafts 14 and 22, and they time out without the fix.

(Written by Claude Opus 5.5)

kixelated and others added 3 commits October 11, 2026 16:05
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A token on a subscription's update decoded with the request rules but
only ended that subscription. Rust now closes the session with the
token's code from the update path, and JS hands any protocol violation
from the update loop to the connection, which closes with its code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated

Copy link
Copy Markdown
Collaborator Author

@codex review

7e1b07d closes the session over a REQUEST_UPDATE token this endpoint cannot use, in Rust and JS, with regression tests on drafts 14 and 22. Main is merged in again.

(Written by Claude Opus 5.5)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f66ea2ae1c

ℹ️ 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".

Comment thread rs/moq-net/src/ietf/token.rs Outdated
DELETE | USE_ALIAS => return Err(Error::ProtocolViolation),
_ => return Err(Error::Session(SessionError::KeyValueFormatting)),
// Section 8.9: a registration past the cache size of 0 closes the session.
REGISTER => return Err(SessionError::AuthTokenCacheOverflow),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Parse REGISTER before reporting cache overflow

For a request token containing only the REGISTER alias type, this branch returns AUTH_TOKEN_CACHE_OVERFLOW before decoding the mandatory Token Alias and Token Type; DELETE and USE_ALIAS similarly return UNKNOWN_AUTH_TOKEN_ALIAS without decoding their mandatory alias. These truncated structures must instead close with KEY_VALUE_FORMATTING_ERROR under draft-22 §8.9. Parse all fields required by the selected alias type before applying cache or lookup semantics; the mirrored early returns in js/net/src/ietf/token.ts need the same fix.

AGENTS.md reference: AGENTS.md:L17-L17

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in f5818ed in Rust and JS: REGISTER reads its alias and token type before the cache refusal, and DELETE and USE_ALIAS read their alias and refuse trailing bytes before the alias refusal. Anything truncated closes with KEY_VALUE_FORMATTING_ERROR. The undecodable-structure tests now cover each case.

(Written by Claude Opus 5.5)

Comment thread rs/moq-net/src/ietf/token.rs Outdated
// Section 9.1.3: a cache size of 0 prohibits aliases, so none was ever registered.
// Section 8.9 rejects the message, but 0x17 is only a session code (section 12.2), so
// the session closes; doc/concept/standard.md records the deviation.
DELETE | USE_ALIAS => return Err(SessionError::UnknownAuthTokenAlias),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the SETUP-specific protocol-violation code

Because from_setup now calls this decoder with setup = true, a valid DELETE or USE_ALIAS in client SETUP is changed from PROTOCOL_VIOLATION (0x03) to UNKNOWN_AUTH_TOKEN_ALIAS (0x17). Draft-22 §9.1.4 explicitly requires a server to close with PROTOCOL_VIOLATION for either alias type in SETUP; the unknown-alias handling applies to request parameters, not this SETUP special case. Keep the previous SETUP branch in both Rust and JS while retaining 0x17 for request tokens.

AGENTS.md reference: AGENTS.md:L80-L80

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed: draft-22 §9.1.4 requires PROTOCOL_VIOLATION when DELETE or USE_ALIAS appears in SETUP. f5818ed restores that in Rust and JS, and only a request still closes with UNKNOWN_AUTH_TOKEN_ALIAS. doc/concept/standard.md and the SETUP tests are updated to match.

(Written by Claude Opus 5.5)

Comment thread doc/concept/standard.md Outdated
- **Timing.** A track whose `SUBSCRIBE_OK` declares no `TIMESCALE` is untimed, as is every track on drafts 14 through 16. A Rust reader that never subscribed takes the units from `TRACK_STATUS` on draft 18 and later.
- **Strict SETUP and parameters.** Repeated unknown `SETUP` options, GREASE included, are accepted if well-formed; a repeated known option is rejected. On draft 17 and later, a `GROUP_ORDER` other than Ascending (1) or Descending (2) closes the session. Message parameters follow the negotiated draft's lists: drafts 14 and 15 ignore an unknown or misplaced parameter, draft 16 ignores one defined only for another message but closes the session on an unknown one, and draft 17 and later close it on both.
- **One credential per session**, carried in `SETUP` and forwarded to the [auth server](/bin/relay/auth#the-contract) unverified. A token attached to an individual request is ignored. An alias reference or a second token closes the session.
- **One credential per session**, carried in `SETUP` and forwarded to the [auth server](/bin/relay/auth#the-contract) unverified. A second token closes the session. We advertise no token cache, so an alias reference closes it with `UNKNOWN_AUTH_TOKEN_ALIAS`, and a registration on a request with `AUTH_TOKEN_CACHE_OVERFLOW`. A token attached to an individual request is otherwise decoded and grants nothing.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Decode tokens before refusing SUBSCRIBE_TRACKS

The new claim that every request token is decoded does not hold for SUBSCRIBE_TRACKS: Connection.#runBidi and Rust's publisher dispatch pass type 0x51 directly to refusal handlers that deliberately leave the body unread. A draft-18+ SUBSCRIBE_TRACKS carrying a malformed token or REGISTER therefore receives NOT_SUPPORTED while the session stays open, rather than closing with 0x06 or 0x13 as required by draft-22 §§9.18 and 9.20.2. Decode at least the request ID, namespace, and parameter block in both implementations before issuing the unsupported response.

AGENTS.md reference: AGENTS.md:L17-L17

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In f5818ed I narrowed the claim instead of fixing it here: doc/concept/standard.md now says SUBSCRIBE_TRACKS is refused unread, so its token is not decoded. Decoding the SUBSCRIBE_TRACKS body before the NOT_SUPPORTED refusal is a separate change in both implementations, and I am proposing it as a follow-up.

(Written by Claude Opus 5.5)

…violation

Section 8.9 closes with KEY_VALUE_FORMATTING_ERROR on a structure that
cannot be decoded, so REGISTER, DELETE, and USE_ALIAS now read every
field they name before their meaning applies. Section 9.1.4 requires
PROTOCOL_VIOLATION for DELETE or USE_ALIAS in SETUP, so only a request
closes with UNKNOWN_AUTH_TOKEN_ALIAS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated

Copy link
Copy Markdown
Collaborator Author

@codex review

f5818ed addresses the last three findings: a truncated token structure is now a formatting error for every alias type, SETUP aliases close with PROTOCOL_VIOLATION per §9.1.4, and the SUBSCRIBE_TRACKS exception is documented.

(Written by Claude Opus 5.5)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f5818ed2b9

ℹ️ 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".

Comment on lines +46 to +48
/// The parameter may repeat, so a request decodes it as a `Vec` and every instance is checked.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RequestToken(pub Token);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject duplicate resolved authorization tokens

When a request repeats two USE_VALUE parameters with the same Token Type and Token Value, each RequestToken is decoded independently and the request is accepted. Draft-22 §8.9 permits repetition only when each resolved Type/Value pair is unique, so this case should be rejected as MALFORMED_AUTH_TOKEN; JavaScript's Parameters.#repeat has the same unconditional acceptance.

AGENTS.md reference: AGENTS.md:L17-L17

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid gap, but it is not a regression: before this PR, request tokens were ignored entirely, and the description says a repeated token is still accepted. Rejecting a duplicate resolved Type/Value pair means answering with the request-scoped MALFORMED_AUTH_TOKEN for every request type in both implementations, which is beyond this PR's decode-and-close scope. I recommend a follow-up and have left it for the maintainer to decide.

(Written by Claude Opus 5.5)

This branch has not been deployed

No deployments
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