From a390cd1a0a771db91817ff2260ca3f356a0490ce Mon Sep 17 00:00:00 2001 From: Rai Butera Date: Thu, 12 Mar 2026 19:11:05 +0000 Subject: [PATCH] fix: trust device-token auth for internal backend attestation --- .../server/ws-connection/connect-policy.test.ts | 14 ++++++++++++++ src/gateway/server/ws-connection/connect-policy.ts | 7 ++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/gateway/server/ws-connection/connect-policy.test.ts b/src/gateway/server/ws-connection/connect-policy.test.ts index 1770fcecadb..16e5b1c5e16 100644 --- a/src/gateway/server/ws-connection/connect-policy.test.ts +++ b/src/gateway/server/ws-connection/connect-policy.test.ts @@ -424,6 +424,20 @@ describe("ws connect policy", () => { }), ).toBe(false); + // Backend client authenticating via device-token (derived from initial shared-secret pairing) is trusted. + expect( + shouldSkipBackendSelfPairing({ + connectParams: makeConnectParams( + GATEWAY_CLIENT_IDS.GATEWAY_CLIENT, + GATEWAY_CLIENT_MODES.BACKEND, + ), + isLocalClient: true, + hasBrowserOriginHeader: false, + sharedAuthOk: true, + authMethod: "device-token", + }), + ).toBe(true); + // Remote backend client (gateway.mode=remote) with valid shared-secret auth is trusted. expect( shouldSkipBackendSelfPairing({ diff --git a/src/gateway/server/ws-connection/connect-policy.ts b/src/gateway/server/ws-connection/connect-policy.ts index 69ce10c8cc8..aef8d24454b 100644 --- a/src/gateway/server/ws-connection/connect-policy.ts +++ b/src/gateway/server/ws-connection/connect-policy.ts @@ -90,7 +90,12 @@ export function shouldSkipBackendSelfPairing(params: { if (!isGatewayBackendClient) { return false; } - const usesSharedSecretAuth = params.authMethod === "token" || params.authMethod === "password"; + // device-token is a derived credential issued after initial shared-secret pairing, so it + // carries equivalent trust for the internal backend path. + const usesSharedSecretAuth = + params.authMethod === "token" || + params.authMethod === "password" || + params.authMethod === "device-token"; // When auth is disabled entirely (mode="none"), there is no shared secret to verify, but a // local client with no browser origin and the correct gateway-client/backend identity is still // a trusted internal connection.