mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-17 20:21:13 +00:00
148 lines
4.7 KiB
TypeScript
148 lines
4.7 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import type { OpenClawConfig } from "../config/config.js";
|
|
import { resolveGatewayProbeAuthSafe, resolveGatewayProbeTarget } from "../gateway/probe-auth.js";
|
|
import { collectDeepProbeFindings } from "./audit-deep-probe-findings.js";
|
|
|
|
describe("security audit gateway auth selection", () => {
|
|
it("applies gateway auth precedence across local and remote modes", async () => {
|
|
const makeProbeEnv = (env?: { token?: string; password?: string }) => {
|
|
const probeEnv: NodeJS.ProcessEnv = {};
|
|
if (env?.token !== undefined) {
|
|
probeEnv.OPENCLAW_GATEWAY_TOKEN = env.token;
|
|
}
|
|
if (env?.password !== undefined) {
|
|
probeEnv.OPENCLAW_GATEWAY_PASSWORD = env.password;
|
|
}
|
|
return probeEnv;
|
|
};
|
|
|
|
const cases: Array<{
|
|
name: string;
|
|
cfg: OpenClawConfig;
|
|
env?: { token?: string; password?: string };
|
|
expectedAuth: { token?: string; password?: string };
|
|
}> = [
|
|
{
|
|
name: "uses local auth when gateway.mode is local",
|
|
cfg: { gateway: { mode: "local", auth: { token: "local-token-abc123" } } },
|
|
expectedAuth: { token: "local-token-abc123" },
|
|
},
|
|
{
|
|
name: "prefers env token over local config token",
|
|
cfg: { gateway: { mode: "local", auth: { token: "local-token" } } },
|
|
env: { token: "env-token" },
|
|
expectedAuth: { token: "env-token" },
|
|
},
|
|
{
|
|
name: "uses local auth when gateway.mode is undefined (default)",
|
|
cfg: { gateway: { auth: { token: "default-local-token" } } },
|
|
expectedAuth: { token: "default-local-token" },
|
|
},
|
|
{
|
|
name: "uses remote auth when gateway.mode is remote with URL",
|
|
cfg: {
|
|
gateway: {
|
|
mode: "remote",
|
|
auth: { token: "local-token-should-not-use" },
|
|
remote: { url: "wss://remote.example.com:18789", token: "remote-token-xyz789" },
|
|
},
|
|
},
|
|
expectedAuth: { token: "remote-token-xyz789" },
|
|
},
|
|
{
|
|
name: "ignores env token when gateway.mode is remote",
|
|
cfg: {
|
|
gateway: {
|
|
mode: "remote",
|
|
auth: { token: "local-token-should-not-use" },
|
|
remote: { url: "wss://remote.example.com:18789", token: "remote-token" },
|
|
},
|
|
},
|
|
env: { token: "env-token" },
|
|
expectedAuth: { token: "remote-token" },
|
|
},
|
|
{
|
|
name: "falls back to local auth when gateway.mode is remote but URL is missing",
|
|
cfg: {
|
|
gateway: {
|
|
mode: "remote",
|
|
auth: { token: "fallback-local-token" },
|
|
remote: { token: "remote-token-should-not-use" },
|
|
},
|
|
},
|
|
expectedAuth: { token: "fallback-local-token" },
|
|
},
|
|
{
|
|
name: "uses remote password when env is unset",
|
|
cfg: {
|
|
gateway: {
|
|
mode: "remote",
|
|
remote: { url: "wss://remote.example.com:18789", password: "remote-pass" },
|
|
},
|
|
},
|
|
expectedAuth: { password: "remote-pass" },
|
|
},
|
|
{
|
|
name: "prefers env password over remote password",
|
|
cfg: {
|
|
gateway: {
|
|
mode: "remote",
|
|
remote: { url: "wss://remote.example.com:18789", password: "remote-pass" },
|
|
},
|
|
},
|
|
env: { password: "env-pass" },
|
|
expectedAuth: { password: "env-pass" },
|
|
},
|
|
];
|
|
|
|
await Promise.all(
|
|
cases.map(async (testCase) => {
|
|
const target = resolveGatewayProbeTarget(testCase.cfg);
|
|
const result = resolveGatewayProbeAuthSafe({
|
|
cfg: testCase.cfg,
|
|
env: makeProbeEnv(testCase.env),
|
|
mode: target.mode,
|
|
});
|
|
expect(result.auth, testCase.name).toEqual(testCase.expectedAuth);
|
|
}),
|
|
);
|
|
});
|
|
|
|
it("adds warning finding when probe auth SecretRef is unavailable", () => {
|
|
const cfg: OpenClawConfig = {
|
|
gateway: {
|
|
mode: "local",
|
|
auth: {
|
|
mode: "token",
|
|
token: { source: "env", provider: "default", id: "MISSING_GATEWAY_TOKEN" },
|
|
},
|
|
},
|
|
secrets: {
|
|
providers: {
|
|
default: { source: "env" },
|
|
},
|
|
},
|
|
};
|
|
|
|
const result = resolveGatewayProbeAuthSafe({
|
|
cfg,
|
|
mode: "local",
|
|
env: {},
|
|
});
|
|
const warning = collectDeepProbeFindings({
|
|
deep: {
|
|
gateway: {
|
|
attempted: true,
|
|
url: "ws://127.0.0.1:18789",
|
|
ok: true,
|
|
error: null,
|
|
close: null,
|
|
},
|
|
},
|
|
authWarning: result.warning,
|
|
}).find((finding) => finding.checkId === "gateway.probe_auth_secretref_unavailable");
|
|
expect(warning?.severity).toBe("warn");
|
|
expect(warning?.detail).toContain("gateway.auth.token");
|
|
});
|
|
});
|