diff --git a/src/gateway/probe.ts b/src/gateway/probe.ts index f5c6b94ea87..ffb16d57ae1 100644 --- a/src/gateway/probe.ts +++ b/src/gateway/probe.ts @@ -50,9 +50,15 @@ export async function probeGateway(opts: { // We used to disable identity for all local probes without token/password, // but that breaks authenticated status checks when hardening is enabled. // - // Now we only disable it for literal anonymous loopback probes (opts.auth - // undefined) to maintain legacy "no-setup" local status behavior. - return isLoopbackHost(hostname) && opts.auth === undefined; + // Disable device identity for loopback probes that are effectively + // unauthenticated: opts.auth undefined OR an auth object with no + // credentials. Callers like status/probe pass { token, password } from + // resolveGatewayProbeAuth even when both are missing; treat that as + // anonymous to preserve legacy "no-setup" local status behavior. + const hasCredentials = + (typeof opts.auth?.token === "string" && opts.auth.token.trim().length > 0) || + (typeof opts.auth?.password === "string" && opts.auth.password.trim().length > 0); + return isLoopbackHost(hostname) && !hasCredentials; } catch { return false; } diff --git a/src/gateway/server/ws-connection/message-handler.ts b/src/gateway/server/ws-connection/message-handler.ts index 544246949b8..41d8234f45b 100644 --- a/src/gateway/server/ws-connection/message-handler.ts +++ b/src/gateway/server/ws-connection/message-handler.ts @@ -548,7 +548,6 @@ export function attachGatewayWsMessageHandler(params: { if (!device && (!isControlUi || decision.kind !== "allow" || trustedProxyAuthOk)) { clearUnboundScopes(grantReadForTokenAuth); } - } if (decision.kind === "allow") { return true; }