Add authenticated WebSocket recovery telemetry - #7546
Merged
Merged
Conversation
Track one bounded terminal outcome and duration for every completed NIP-42 authentication lifecycle. Expose an exactly-once active gauge for authenticated WebSocket connections so rollout recovery can be measured without identity or error-string labels. Co-authored-by: Ravneet Arora <rarora@squareup.com> Signed-off-by: Ravneet Arora <rarora@squareup.com>
Co-authored-by: Ravneet Arora <rarora@squareup.com> Signed-off-by: Ravneet Arora <rarora@squareup.com>
🔐 Codex Security Review
|
ravarora2
marked this pull request as ready for review
September 9, 2026 22:24
Co-authored-by: Ravneet Arora <rarora@squareup.com> Signed-off-by: Ravneet Arora <rarora@squareup.com>
Classify dependency failures separately from policy denials and keep post-terminal AUTH traffic outside rollout-gating lifecycle metrics. Make AUTH cancellation and writer teardown bounded and drop-safe, publish stable histogram zeros, and bind regressions to production dispatch, boot, and upgraded WebSocket seams. Co-authored-by: Ravneet Arora <rarora@squareup.com> Signed-off-by: Ravneet Arora <rarora@squareup.com>
Bring in the latest unrelated buzz-acp model-listing fix before updating the pull request. Co-authored-by: Ravneet Arora <rarora@squareup.com> Signed-off-by: Ravneet Arora <rarora@squareup.com>
bradseiler
approved these changes
Sep 15, 2026
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
Argo rollout recovery needs to distinguish an open WebSocket from a connection that completed NIP-42 authentication and is usable. The relay currently exposes total WebSocket connections, but it cannot answer whether authenticated clients recovered after a pod drain or why authentication failed.
This change adds a bounded recovery contract:
buzz_auth_attempts_total{method="nip42"}buzz_auth_outcomes_total{method="nip42",outcome}buzz_auth_duration_seconds{method="nip42",outcome}buzz_ws_authenticated_connections_activebuzz_auth_post_terminal_frames_total{state}buzz_auth_attempts_totalnow has one consistent recovery-oriented unit: a challenge lifecycle successfully queued to the connection writer. This intentionally replaces the historical unit of AUTH frames that reached the pending handler. AUTH frames received after a lifecycle is already authenticated or failed are protocol noise; they use the separate bounded post-terminal counter and cannot inflate rollout-gating attempts or outcomes.Each issued challenge reaches exactly one terminal outcome. Authentication transitions and active-gauge changes share one short synchronous state lock, cancellation can claim a pending database-backed AUTH before a late handler result, and a drop guard reconciles aborted or panicked connection futures. Accounting is terminalized before writer joins, while terminal socket delivery has a one-second best-effort bound so a stalled sink cannot retain the authenticated gauge or connection permit indefinitely.
Dependency failures are distinct from policy verdicts: allowlist and relay-membership lookup errors now emit
allowlist_check_errorandrelay_membership_check_error, neverallowlist_deniedornot_relay_member. The fail-closed allow/deny policy is unchanged. All rollout-facing labels come from fixed enums; identities, challenges, URLs, and raw error strings are never exported.All fixed counter and histogram label sets, including zero histogram buckets, counts, and sums, are present on the first real exporter scrape. This is the first implementation slice of the rollout-reliability plan. A later PR will consume these metrics from opt-in Argo Rollout analysis; merging this PR alone does not change deployment behavior.
Related issue
None found.
Testing
Validated at final head
f9992cac835284c25ee0f99e17ddba0b932d7c69, which contains currentorigin/main:cargo fmt --all -- --checkcargo clippy -p buzz-relay --all-targets -- -D warningsbuzz-relaytest targetbuzz-relay,buzz,buzz-admin, andbuzz-test-cliMutation checks proved that the production regressions fail when any of these are removed or reintroduced:
handle_active_connectionThe exact-head release binaries were also exercised against the isolated review database:
attempt_delta=2,success_delta=2,active_while_subscribed=1, andactive_after_disconnect=0.Local caveat
The full relay library target consistently reached 1,049 passes with 89 intentionally ignored tests, but the untouched
api::mesh_demo::tests::demo_join_forwarded_arm_round_trips_echointermittently returned HTTP 504 instead of 200. One isolated rerun passed; later isolated and full reruns reproduced the 504. No mesh files are changed by this PR, and all changed-path, main-target, boot-lifecycle, lint, build, mutation, and live-local checks above passed at the final head.Generated with Codex