Skip to content

fix: scope compatibility mode to 0.x clients - #1444

Merged
dunglas merged 3 commits into
mainfrom
fix/compat-mode-isolation
Oct 19, 2026
Merged

dunglas merged 3 commits into
mainfrom
fix/compat-mode-isolation

Conversation

@dunglas

@dunglas dunglas commented Oct 18, 2026

Copy link
Copy Markdown
Owner

Fixes #1443.

protocol_version_compatibility restored 0.x subscriptions but not history replay, and relaxed checks for 1.x clients as well. This PR restores replay and limits the relaxation to 0.x requests and tokens.

  • Replay: under protocol_version_compatibility 8, the hub accepts the 0.x lastEventID query parameter again. It sends the 0.x Last-Event-ID response field only to requests using lastEventID or topic=. An empty lastEventID is ignored, as in 0.x.
  • Token checks: only tokens carrying a mercure claim and no authorization_details skip the RFC 9068 checks (typ, exp, aud, iss). Before, any token without authorization_details skipped them, so any JWT from a shared issuer, such as an OpenID Connect ID token, got past disabled anonymous access.
  • Carriers and issuer: 1.x tokens are rejected in the authorization query parameter and the mercureAuthorization cookie. They must carry iss, even when the hub only uses the deprecated top-level directives.
  • Mixed parameters: subscribe requests mixing 0.x (topic, lastEventID, Last-Event-ID) and 1.x (match*, last_event_id) query parameters get a 400.
  • v7 exemption: posting public updates to ungranted topics under protocol_version_compatibility 7 now requires a legacy mercure.publish claim. Tokens with only a publish authorization detail no longer qualify.

docs/UPGRADE.md documents the behavior changes in a 1.1.3 section. A 0.x token with no mercure claim at all is now rejected in compatibility mode; adding "mercure": {} keeps it working.

0.x clients reconnect with the lastEventID query parameter and read the
cursor from the Last-Event-ID response field. Accept both under
protocol_version_compatibility 8, sending the 0.x field only to requests
using lastEventID or topic=.

Fixes #1443
Protocol 7 predates authorization details: a 1.x token must hold a grant
for every topic it publishes to, even in compatibility mode.
Compatibility mode relaxed the RFC 9068 checks for any token without
authorization_details, so any JWT from a shared issuer, such as an
OpenID Connect ID token, bypassed disabled anonymous access. Relax them
only for tokens carrying a mercure claim, decided once per token.

- Reject 1.x tokens in the authorization query parameter and the
  mercureAuthorization cookie.
- Require iss in 1.x tokens, also under the implicit issuer.
- Reject subscribe requests mixing 0.x and 1.x query parameters.
@dunglas
dunglas merged commit 889c48f into main Oct 19, 2026
44 of 48 checks passed
@dunglas
dunglas deleted the fix/compat-mode-isolation branch October 19, 2026 09:50
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.

lastEventID is not functional with latest 0.x release

1 participant