Skip to content

Sealed push through the Hosted Relay - #870

Open
nedtwigg wants to merge 2 commits into
remote-network-hosted-dofrom
remote-network-hosted-push
Open

nedtwigg wants to merge 2 commits into
remote-network-hosted-dofrom
remote-network-hosted-push

Conversation

@nedtwigg

@nedtwigg nedtwigg commented Oct 1, 2026

Copy link
Copy Markdown
Member

Fourth of the Hosted persistent stack, on #869. It adds push on relay.dormouse.sh, with the self-host Relay's routes, shapes, error strings, and rules (docs/specs/relay.md → "Web Push").

What's the same:

  • deliveryId possession is the whole authorization, and a session is never shown the list of ids.
  • The Relay forwards exactly { burrowId, v, salt, ct } field by field, with burrowId taken from the Burrow token.
  • 404/410 answers prune the subscription; other failures are counted, never silent.
  • A 15 s route deadline, and delivery views keyed to the current VAPID key.

What differs on Workers:

  • Sender: WebCrypto + fetch instead of web-push, which needs Node https, ECDH, and PEM signing. It implements RFC 8291 aes128gcm and RFC 8292 VAPID ES256.
    • Pinned byte for byte to the RFC 8291 Appendix A vector.
    • The JWT is checked with WebCrypto, and a round-trip test decrypts with Node crypto independently.
    • One VAPID signature per push-service origin per send.
  • Endpoint egress: Workers can't apply the self-host DNS guard, so only the known push services are registered or fetched: FCM, *.push.apple.com, Mozilla, and WNS. No redirect is followed, and a refusal body is read to at most 1 KiB.
  • Storage: Postgres (003_relay_push.sql):
    • endpoint rotation and caps are scoped to the account: 32 per Burrow, 256 per account;
    • removing a computer cascades its subscriptions;
    • subscribing is serialized against removal;
    • no database connection is held across the push fan-out.
  • Subscription keys: checked by what they decode to (a 65-byte uncompressed P-256 point and a 16-byte auth secret), so a key that can never be encrypted to is refused at registration.
  • Repeated recipients: sent once, to stay under the Worker subrequest limit; documented.
  • e2e lint: admits AES-GCM in exactly remote-lib-common/src/remote/web-push.ts, which RFC 8291 requires, with a self-test case.

Operator step before production: generate the VAPID pair and wrangler secret bulk both keys onto dormouse-relay (hosted/README.md). Preflight checks only that the names exist; pushConfigSmoke checks that a key is actually served. Each preview derives its own stable VAPID pair from PREVIEW_AUTH_SECRET, so push can be tried end to end on a PR preview with no production credential.

Test plan

  • Root pnpm test green; Hosted Docker suite 152/152.
  • Manual, on the preview: install Pocket to the Home Screen from the relay preview, pair, Enable push, and ring a pane on the desktop. A notification arrives; tapping it focuses Pocket.

🤖 Generated with Claude Code

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Deploying mouseterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: 6353f0e
Status: ✅  Deploy successful!
Preview URL: https://c5241008.mouseterm.pages.dev
Branch Preview URL: https://remote-network-hosted-push.mouseterm.pages.dev

View logs

nedtwigg and others added 2 commits October 1, 2026 02:33
The self-host push routes on relay.dormouse.sh over Postgres, with a WebCrypto
Web Push sender (RFC 8291 aes128gcm, pinned to the Appendix A vector; RFC 8292
VAPID ES256), endpoints limited to the known push services, account-scoped
rotation and caps, and per-preview VAPID keys. Push is HTTPS from the Burrow,
independent of terminal transport.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review fixes: subscription keys checked by what they decode to, no database
connection held across the push fan-out, a refusal body read to at most 1 KiB,
lock-ordered timestamps, subscribe serialized against Burrow removal, one VAPID
signature per origin, the VAPID smoke, and the e2e lint admitting AES-GCM in the
Web Push sender alone.

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

This branch is waiting to be deployed

1 waiting (outdated) deployment
hosted-preview — d2c95d63 Waiting Oct 1, 2026 by nedtwigg via deploy #613
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.

2 participants