fix(doctor,configure): skip gateway auth for loopback-only setups

This commit is contained in:
Knox
2026-02-16 22:21:02 +05:30
committed by Peter Steinberger
parent 6757a9fedc
commit 9aa8db5c81
3 changed files with 71 additions and 53 deletions

View File

@@ -85,22 +85,7 @@ export async function promptGatewayConfig(
customBindHost = typeof input === "string" ? input : undefined;
}
let authMode = guardCancel(
await select({
message: "Gateway auth",
options: [
{ value: "token", label: "Token", hint: "Recommended default" },
{ value: "password", label: "Password" },
{
value: "trusted-proxy",
label: "Trusted Proxy",
hint: "Behind reverse proxy (Pomerium, Caddy, Traefik, etc.)",
},
],
initialValue: "token",
}),
runtime,
) as GatewayAuthChoice;
let authMode: GatewayAuthChoice = "token";
let tailscaleMode = guardCancel(
await select({
@@ -137,22 +122,44 @@ export async function promptGatewayConfig(
bind = "loopback";
}
if (tailscaleMode === "funnel" && authMode !== "password") {
note("Tailscale funnel requires password auth.", "Note");
authMode = "password";
}
const loopbackOnlyGateway = bind === "loopback" && tailscaleMode === "off";
if (loopbackOnlyGateway) {
note("Loopback-only gateway does not require gateway.auth. Keeping auth disabled.", "Note");
} else {
authMode = guardCancel(
await select({
message: "Gateway auth",
options: [
{ value: "token", label: "Token", hint: "Recommended default" },
{ value: "password", label: "Password" },
{
value: "trusted-proxy",
label: "Trusted Proxy",
hint: "Behind reverse proxy (Pomerium, Caddy, Traefik, etc.)",
},
],
initialValue: tailscaleMode === "funnel" ? "password" : "token",
}),
runtime,
) as GatewayAuthChoice;
if (authMode === "trusted-proxy" && bind === "loopback") {
note("Trusted proxy auth requires network bind. Adjusting bind to lan.", "Note");
bind = "lan";
}
if (authMode === "trusted-proxy" && tailscaleMode !== "off") {
note(
"Trusted proxy auth is incompatible with Tailscale serve/funnel. Disabling Tailscale.",
"Note",
);
tailscaleMode = "off";
tailscaleResetOnExit = false;
if (tailscaleMode === "funnel" && authMode !== "password") {
note("Tailscale funnel requires password auth.", "Note");
authMode = "password";
}
if (authMode === "trusted-proxy" && bind === "loopback") {
note("Trusted proxy auth requires network bind. Adjusting bind to lan.", "Note");
bind = "lan";
}
if (authMode === "trusted-proxy" && tailscaleMode !== "off") {
note(
"Trusted proxy auth is incompatible with Tailscale serve/funnel. Disabling Tailscale.",
"Note",
);
tailscaleMode = "off";
tailscaleResetOnExit = false;
}
}
let gatewayToken: string | undefined;
@@ -163,7 +170,7 @@ export async function promptGatewayConfig(
let trustedProxies: string[] | undefined;
let next = cfg;
if (authMode === "token") {
if (!loopbackOnlyGateway && authMode === "token") {
const tokenInput = guardCancel(
await text({
message: "Gateway token (blank to generate)",
@@ -174,7 +181,7 @@ export async function promptGatewayConfig(
gatewayToken = normalizeGatewayTokenInput(tokenInput) || randomToken();
}
if (authMode === "password") {
if (!loopbackOnlyGateway && authMode === "password") {
const password = guardCancel(
await text({
message: "Gateway password",
@@ -185,7 +192,7 @@ export async function promptGatewayConfig(
gatewayPassword = String(password ?? "").trim();
}
if (authMode === "trusted-proxy") {
if (!loopbackOnlyGateway && authMode === "trusted-proxy") {
note(
[
"Trusted proxy mode: OpenClaw trusts user identity from a reverse proxy.",
@@ -261,22 +268,26 @@ export async function promptGatewayConfig(
};
}
const authConfig = buildGatewayAuthConfig({
existing: next.gateway?.auth,
mode: authMode,
token: gatewayToken,
password: gatewayPassword,
trustedProxy: trustedProxyConfig,
});
const authConfig = loopbackOnlyGateway
? undefined
: buildGatewayAuthConfig({
existing: next.gateway?.auth,
mode: authMode,
token: gatewayToken,
password: gatewayPassword,
trustedProxy: trustedProxyConfig,
});
const gatewayWithoutAuth = { ...next.gateway };
delete gatewayWithoutAuth.auth;
next = {
...next,
gateway: {
...next.gateway,
...gatewayWithoutAuth,
mode: "local",
port,
bind,
auth: authConfig,
...(authConfig ? { auth: authConfig } : {}),
...(customBindHost && { customBindHost }),
...(trustedProxies && { trustedProxies }),
tailscale: {