fix(pairing): require explicit pairing relay discovery - #6183
Draft
kunalbhatt wants to merge 1 commit into
Draft
Conversation
Signed-off-by: Kunal Bhatt <kbhatt@squareup.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix Desktop pairing discovery so NIP-43 is treated as relay membership support,
not proof that a legacy same-host
/pairWebSocket endpoint exists.Desktop now prefers an explicitly advertised, valid
pairing_relay_url. Itreturns an actionable configuration error before opening a WebSocket when that
field is invalid, or when a membership-gated NIP-43 relay does not advertise
one. Non-NIP-43 relays retain their existing main-relay pairing behavior, and a
same-host
/pairendpoint remains supported when explicitly advertised.Production Compose now includes the existing stateless
buzz-pair-relaybinary and an Nginx gateway. The gateway is the only service publishing host
port 3000:
/pairtraffic goes to the pairing relay and all other traffic goesto the main relay. The optional Caddy overlay proxies through the gateway, and
the documentation includes direct Cloudflare Tunnel routing.
Related issue
Fixes #2734.
Related open work found before opening this PR: #2736 and #5715 add Compose
pairing sidecars but retain the incorrect NIP-43-to-
/pairclient fallback;#3424 covers chart routing only. This PR includes the Desktop discovery fix,
regression coverage, and the Compose gateway architecture together.
Problem and root cause
A membership-gated relay correctly advertises NIP-43 in its NIP-11 document.
Desktop interpreted
supported_nips: [43]as endpoint discovery, derivedwss://<relay>/pair, and attempted to connect. NIP-43 describes relaymembership support and says nothing about a pairing endpoint. Production
Compose exposed only the main relay on port 3000, so the invented endpoint
returned HTTP 404.
Reproduction
BUZZ_REQUIRE_RELAY_MEMBERSHIP=true.RELAY_OWNER_PUBKEY.BUZZ_PAIRING_RELAY_URLunset./pairand receiving HTTP 404 Not Found.Before and after
pairing_relay_urlwas treated as if<relay>/pairexisted.with guidance to configure the stateless sidecar through
BUZZ_PAIRING_RELAY_URL.to legacy behavior.
ws://orwss://URLs with a host are accepted; invalid valuesreturn an actionable configuration error.
main relay.
/pairremains usable when it is explicitlyadvertised as
pairing_relay_url.Security and deployment implications
invalid/missing membership-gated pairing configuration.
have no host ports when the gateway is enabled.
BUZZ_HTTP_BIND_IP=127.0.0.1binds public port 3000 to loopback for ahost-installed Cloudflare Tunnel or proxy.
Optional Caddy support routes through the gateway instead of duplicating
/pairbehavior.buzz-pair-relayremains anonymous and ephemeral: it has no identity,database, or persistent volume.
.env,.env.backup*, backup Compose file, volume contents,identity key, or private-host configuration is included. The only environment
file changed is the public
.env.example, withBUZZ_PAIRING_RELAY_URL=wss://buzz.example.com/pair.Testing
All commands below ran with the repository Hermit environment activated.
. ./bin/activate-hermitjust desktop-tauri-fmtcargo fmt --alljust desktop-tauri-fmt-checkcargo fmt --all -- --checkgit diff --checkjust _ensure-sidecar-stubscargo test --manifest-path desktop/src-tauri/Cargo.toml -p buzz-desktop pairing_relay_testscargo test -p buzz-relay nip11::testsjust desktop-tauri-clippycargo clippy -p buzz-relay --all-targets -- -D warningsbash -n deploy/compose/run.shjust ciDeployment configuration validation:
config --format jsonpassed for the baseconfiguration using an isolated copy of the public sample config and
BUZZ_HTTP_BIND_IP=127.0.0.1. Assertions confirmed that only the gatewaypublishes
127.0.0.1:3000, the relay and pairing relay publish no host ports,and the pairing relay has no volumes.
confirmed that it resets the gateway host port and waits for the healthy
gateway.
BUZZ_DOMAIN=buzz.example.com caddy validate --config deploy/compose/Caddyfile --adapter caddyfilepassed with Caddy v2.11.4, and
the Caddyfile is canonically formatted.
nginx -t -c <temporary-config>passed with Nginx 1.19.4. The temporaryconfig changed only the Compose-DNS upstream names to loopback so local Nginx
could resolve them; the committed config retains
relay:3000andpairing-relay:5000.and a live cross-container WebSocket handshake were not exercised locally.
Screenshots are not applicable; the Desktop change is pairing endpoint
selection and error handling, and the deployment change is proxy routing.