From 2539bcafe0bf9d9ddf5621ad0105c835a16b80f3 Mon Sep 17 00:00:00 2001 From: simianastronaut Date: Sun, 15 Mar 2026 16:37:41 -0400 Subject: [PATCH] fix(gateway): pass bearer token in WebSocket subprotocol for dashboard auth The dashboard WebSocket client was only sending ['zeroclaw.v1'] as the protocols parameter, omitting the bearer token subprotocol. When require_pairing = true, the server extracts the token from Sec-WebSocket-Protocol as a fallback (browsers cannot set custom headers on WebSocket connections). Without the bearer. entry in the protocols array, subprotocol-based authentication always failed. Include `bearer.` in the protocols array when a token is available, matching the server's extract_ws_token() expectation. Closes #3011 Co-Authored-By: Claude Opus 4.6 (1M context) --- web/src/lib/ws.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/src/lib/ws.ts b/web/src/lib/ws.ts index fdb7315d4..c5514bd94 100644 --- a/web/src/lib/ws.ts +++ b/web/src/lib/ws.ts @@ -71,7 +71,9 @@ export class WebSocketClient { params.set('session_id', sessionId); const url = `${this.baseUrl}/ws/chat?${params.toString()}`; - this.ws = new WebSocket(url, ['zeroclaw.v1']); + const protocols: string[] = ['zeroclaw.v1']; + if (token) protocols.push(`bearer.${token}`); + this.ws = new WebSocket(url, protocols); this.ws.onopen = () => { this.currentDelay = this.reconnectDelay;