// Detect Tailscale binary before proceeding with serve/funnel setup. // Persist the path so getTailnetHostname can reuse it for origin injection.
let tailscaleBin: string | null = null; if (tailscaleMode !== "off") {
tailscaleBin = await findTailscaleBinary(); if (!tailscaleBin) {
note(TAILSCALE_MISSING_BIN_NOTE_LINES.join("\n"), "Tailscale Warning");
}
}
let tailscaleResetOnExit = false; if (tailscaleMode !== "off") {
note(TAILSCALE_DOCS_LINES.join("\n"), "Tailscale");
tailscaleResetOnExit = guardCancel(
await confirm({
message: "Reset Tailscale serve/funnel on exit?",
initialValue: false,
}),
runtime,
);
}
// trusted-proxy + loopback is valid when the reverse proxy runs on the same // host (e.g. cloudflared, nginx, Caddy). trustedProxies must include 127.0.0.1. 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: SecretInput | undefined;
let gatewayTokenForCalls: string | undefined;
let gatewayPassword: string | undefined;
let trustedProxyConfig:
| { userHeader: string; requiredHeaders?: string[]; allowUsers?: string[] }
| undefined;
let trustedProxies: string[] | undefined;
let next = cfg;
if (authMode === "token") { const tokenInputMode = guardCancel(
await select<GatewayTokenInputMode>({
message: "Gateway token source",
options: [
{
value: "plaintext",
label: "Generate/store plaintext token",
hint: "Default",
},
{
value: "ref",
label: "Use SecretRef",
hint: "Store an env-backed reference instead of plaintext",
},
],
initialValue: "plaintext",
}),
runtime,
); if (tokenInputMode === "ref") { const envVar = guardCancel(
await text({
message: "Gateway token env var",
initialValue: "OPENCLAW_GATEWAY_TOKEN",
placeholder: "OPENCLAW_GATEWAY_TOKEN",
validate: (value) => { const candidate = normalizeOptionalString(value) ?? ""; if (!isValidEnvSecretRefId(candidate)) { return"Use an env var name like OPENCLAW_GATEWAY_TOKEN.";
} const resolved = process.env[candidate]?.trim(); if (!resolved) { return `Environment variable "${candidate}" is missing or empty in this session.`;
} return undefined;
},
}),
runtime,
); const envVarName = normalizeOptionalString(envVar) ?? "";
gatewayToken = {
source: "env",
provider: resolveDefaultSecretProviderAlias(cfg, "env", {
preferFirstProviderForSource: true,
}),
id: envVarName,
};
note(`Validated ${envVarName}. OpenClaw will store a token SecretRef.`, "Gateway token");
} else { const tokenInput = guardCancel(
await text({
message: "Gateway token (blank to generate)",
initialValue: randomToken(),
}),
runtime,
);
gatewayTokenForCalls = normalizeGatewayTokenInput(tokenInput) || randomToken();
gatewayToken = gatewayTokenForCalls;
}
}
if (authMode === "trusted-proxy") {
note(
[ "Trusted proxy mode: OpenClaw trusts user identity from a reverse proxy.", "The proxy must authenticate users and pass identity via headers.", "Only requests from specified proxy IPs will be trusted.", "", "Common use cases: Pomerium, Caddy + OAuth, Traefik + forward auth", "Docs: https://docs.openclaw.ai/gateway/trusted-proxy-auth",
].join("\n"), "Trusted Proxy Auth",
);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.