github dunglas/mercure v1.1.0

4 hours ago

Community

Mercure 1.1.0 makes hubs easier to operate at scale and closes several security gaps found during an audit of the 1.0 code base. Rolling updates no longer have to wait for write_timeout: the new drain_timeout spreads subscriber reconnections over a short window. The new subscription_limits directive caps concurrent event streams per hub, per token and per client. On the security side, the subscription registry now requires authentication, remote JWKS retrieval refuses redirects, and the cost of compiling subscription URL patterns is bounded. Upgrading is recommended for every 1.x deployment.

⚠️ Upgrade Notes

  • Subscription registry: the /.well-known/mercure/subscriptions routes now return 404 when no subscriber key or issuer is configured, in every protocol mode. Anonymous event streams keep working.
  • protocol_version_compatibility 7: publishing a public update to a topic outside the token's grants again requires a mercure.publish claim, as in 0.13. Tokens without one now get 403 insufficient_scope.
  • Remote JWKS: redirects are no longer followed. Point jwks_uri at the final HTTP(S) endpoint.
  • Compression: the default Caddyfile no longer uses encode at all. The docs explain how to opt in and the bandwidth, memory and BREACH trade-offs.

✨ New Features

  • Graceful shutdown: add drain_timeout to decouple the shutdown drain window from write_timeout. On termination, each subscriber is closed at a random point within the window, so rolling updates finish quickly without a reconnection storm. Config reloads never drain. The Helm chart grace-period guidance now keys on this window. by @pseidemann in #1365
  • Subscription limits: add subscription_limits <total> <per_token> <per_client> to cap concurrent event streams on each hub instance. All limits default to 0 (off). by @dunglas in #1428

🐛 Bug Fixes

  • Security: require authentication for the subscription registry. by @dunglas in #1427
  • Security: refuse redirects when retrieving remote JWKS, initially and on refresh, so a trusted endpoint cannot send the hub to another service. by @dunglas in #1424
  • Security: in protocol_version_compatibility 7, require a mercure.publish claim for the public update exemption. Since 1.0, any token verified by the publisher key could publish public updates to any topic, including subscriber tokens on deployments sharing one key between roles. by @dunglas in #1426
  • Security: reject subscription requests whose URL patterns exceed an 8 MiB compilation budget. A request with 100 deprecated topic= URI templates could previously allocate about 1 GiB. by @dunglas in #1420
  • Caddyfile: don't compress responses by default. With the event stream excluded, encode only compressed the subscriptions API, which mixes subscriber payloads with attacker-chosen topics. by @dunglas in #1421
  • Send Expires: 0 on event streams instead of the misspelled Expire header, so HTTP/1.0 caches and proxies don't cache them. by @dunglas in #1429

📖 Documentation

  • New guide: using an OAuth 2.0 authorization server with Mercure, covering the claims an issuer must emit (typ: at+jwt, iss, aud, exp, authorization_details) and how to bind it to the hub with an issuer block and jwks_uri. by @dunglas in #1389
  • mercure-token: recommend --key @file or --key @- over literal keys, which leak through ps and shell history. by @dunglas in #1423
  • Mark encrypted updates as private in the JWE example: encryption protects the content, subscriber authorization controls who receives the ciphertext. by @dunglas in #1425
  • Document that Hub.Publish takes ownership of the update. by @dunglas in #1419

Enterprise

Need prioritized patches, an SLA or a managed hub? Mercure Cloud and Mercure Enterprise get this release today. Contact contact@mercure.rocks.

Full Changelog: v1.0.4...v1.1.0

Don't miss a new mercure release

NewReleases is sending notifications on new releases.