fix(gateway): land #28428 from @l0cka

Landed from contributor PR #28428 by @l0cka.

Co-authored-by: Daniel Alkurdi <danielalkurdi@gmail.com>
This commit is contained in:
Peter Steinberger
2026-03-07 22:49:50 +00:00
parent e83094e63f
commit 265367d99b
26 changed files with 289 additions and 165 deletions

View File

@@ -41,6 +41,7 @@ function withGatewayAuthEnv<T>(env: NodeJS.ProcessEnv, fn: () => T): T {
const keys = [
"OPENCLAW_GATEWAY_TOKEN",
"OPENCLAW_GATEWAY_PASSWORD",
"OPENCLAW_SERVICE_KIND",
"CLAWDBOT_GATEWAY_TOKEN",
"CLAWDBOT_GATEWAY_PASSWORD",
] as const;
@@ -138,6 +139,29 @@ describe("gateway credential precedence parity", () => {
auth: { token: undefined, password: undefined },
},
},
{
name: "local mode in gateway service runtime uses config-first token precedence",
cfg: {
gateway: {
mode: "local",
auth: {
token: "config-token",
password: "config-password",
},
},
} as OpenClawConfig,
env: {
OPENCLAW_GATEWAY_TOKEN: "env-token",
OPENCLAW_GATEWAY_PASSWORD: "env-password",
OPENCLAW_SERVICE_KIND: "gateway",
} as NodeJS.ProcessEnv,
expected: {
call: { token: "config-token", password: "env-password" },
probe: { token: "config-token", password: "env-password" },
status: { token: "config-token", password: "env-password" },
auth: { token: "config-token", password: "config-password" },
},
},
];
it.each(cases)("$name", ({ cfg, env, expected }) => {

View File

@@ -120,6 +120,26 @@ describe("resolveGatewayCredentialsFromConfig", () => {
expectEnvGatewayCredentials(resolved);
});
it("uses config-first local token precedence inside gateway service runtime", () => {
const resolved = resolveGatewayCredentialsFromConfig({
cfg: cfg({
gateway: {
mode: "local",
auth: { token: "config-token", password: "config-password" },
},
}),
env: {
OPENCLAW_GATEWAY_TOKEN: "env-token",
OPENCLAW_GATEWAY_PASSWORD: "env-password",
OPENCLAW_SERVICE_KIND: "gateway",
} as NodeJS.ProcessEnv,
});
expect(resolved).toEqual({
token: "config-token",
password: "env-password",
});
});
it("falls back to remote credentials in local mode when local auth is missing", () => {
const resolved = resolveGatewayCredentialsFromConfig({
cfg: cfg({

View File

@@ -223,7 +223,9 @@ export function resolveGatewayCredentialsFromConfig(params: {
? undefined
: trimToUndefined(params.cfg.gateway?.auth?.password);
const localTokenPrecedence = params.localTokenPrecedence ?? "env-first";
const localTokenPrecedence =
params.localTokenPrecedence ??
(env.OPENCLAW_SERVICE_KIND === "gateway" ? "config-first" : "env-first");
const localPasswordPrecedence = params.localPasswordPrecedence ?? "env-first";
if (mode === "local") {