mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 15:44:31 +00:00
CI: restore main detect-secrets scan (#38438)
* Tests: stabilize detect-secrets fixtures * Tests: fix rebased detect-secrets false positives * Docs: keep snippets valid under detect-secrets * Tests: finalize detect-secrets false-positive fixes * Tests: reduce detect-secrets false positives * Tests: keep detect-secrets pragmas inline * Tests: remediate next detect-secrets batch * Tests: tighten detect-secrets allowlists * Tests: stabilize detect-secrets formatter drift
This commit is contained in:
@@ -102,13 +102,13 @@ async function ensureMinimaxApiKeyWithEnvRefPrompter(params: {
|
||||
return await ensureMinimaxApiKeyInternal({
|
||||
config: params.config,
|
||||
prompter: createPrompter({ select: params.select, text: params.text, note: params.note }),
|
||||
secretInputMode: "ref",
|
||||
secretInputMode: "ref", // pragma: allowlist secret
|
||||
setCredential: params.setCredential,
|
||||
});
|
||||
}
|
||||
|
||||
async function runEnsureMinimaxApiKeyFlow(params: { confirmResult: boolean; textResult: string }) {
|
||||
process.env.MINIMAX_API_KEY = "env-key";
|
||||
process.env.MINIMAX_API_KEY = "env-key"; // pragma: allowlist secret
|
||||
delete process.env.MINIMAX_OAUTH_TOKEN;
|
||||
|
||||
const { confirm, text } = createPromptSpies({
|
||||
@@ -245,7 +245,7 @@ describe("ensureApiKeyFromEnvOrPrompt", () => {
|
||||
});
|
||||
|
||||
it("uses explicit inline env ref when secret-input-mode=ref selects existing env key", async () => {
|
||||
process.env.MINIMAX_API_KEY = "env-key";
|
||||
process.env.MINIMAX_API_KEY = "env-key"; // pragma: allowlist secret
|
||||
delete process.env.MINIMAX_OAUTH_TOKEN;
|
||||
|
||||
const { confirm, text, setCredential } = createPromptAndCredentialSpies({
|
||||
@@ -256,7 +256,7 @@ describe("ensureApiKeyFromEnvOrPrompt", () => {
|
||||
const result = await ensureMinimaxApiKey({
|
||||
confirm,
|
||||
text,
|
||||
secretInputMode: "ref",
|
||||
secretInputMode: "ref", // pragma: allowlist secret
|
||||
setCredential,
|
||||
});
|
||||
|
||||
@@ -278,7 +278,7 @@ describe("ensureApiKeyFromEnvOrPrompt", () => {
|
||||
ensureMinimaxApiKey({
|
||||
confirm,
|
||||
text,
|
||||
secretInputMode: "ref",
|
||||
secretInputMode: "ref", // pragma: allowlist secret
|
||||
setCredential,
|
||||
}),
|
||||
).rejects.toThrow(
|
||||
@@ -288,7 +288,7 @@ describe("ensureApiKeyFromEnvOrPrompt", () => {
|
||||
});
|
||||
|
||||
it("re-prompts after provider ref validation failure and succeeds with env ref", async () => {
|
||||
process.env.MINIMAX_API_KEY = "env-key";
|
||||
process.env.MINIMAX_API_KEY = "env-key"; // pragma: allowlist secret
|
||||
delete process.env.MINIMAX_OAUTH_TOKEN;
|
||||
|
||||
const selectValues: Array<"provider" | "env" | "filemain"> = ["provider", "filemain", "env"];
|
||||
@@ -327,7 +327,7 @@ describe("ensureApiKeyFromEnvOrPrompt", () => {
|
||||
});
|
||||
|
||||
it("never includes resolved env secret values in reference validation notes", async () => {
|
||||
process.env.MINIMAX_API_KEY = "sk-minimax-redacted-value";
|
||||
process.env.MINIMAX_API_KEY = "sk-minimax-redacted-value"; // pragma: allowlist secret
|
||||
delete process.env.MINIMAX_OAUTH_TOKEN;
|
||||
|
||||
const select = vi.fn(async () => "env") as WizardPrompter["select"];
|
||||
@@ -380,7 +380,7 @@ describe("ensureApiKeyFromOptionEnvOrPrompt", () => {
|
||||
|
||||
it("falls back to env flow and shows note when opts provider does not match", async () => {
|
||||
delete process.env.MINIMAX_OAUTH_TOKEN;
|
||||
process.env.MINIMAX_API_KEY = "env-key";
|
||||
process.env.MINIMAX_API_KEY = "env-key"; // pragma: allowlist secret
|
||||
|
||||
const { confirm, note, text, setCredential } = createPromptAndCredentialSpies({
|
||||
confirmResult: true,
|
||||
|
||||
@@ -159,7 +159,7 @@ describe("applyAuthChoiceMiniMax", () => {
|
||||
},
|
||||
{
|
||||
name: "uses env token for minimax-api-key-cn as keyRef in ref mode",
|
||||
opts: { secretInputMode: "ref" as const },
|
||||
opts: { secretInputMode: "ref" as const }, // pragma: allowlist secret
|
||||
expectKey: undefined,
|
||||
expectKeyRef: {
|
||||
source: "env",
|
||||
@@ -172,7 +172,7 @@ describe("applyAuthChoiceMiniMax", () => {
|
||||
const { agentDir, result, text, confirm } = await runMiniMaxChoice({
|
||||
authChoice: "minimax-api-key-cn",
|
||||
opts,
|
||||
env: { apiKey: "mm-env-token" },
|
||||
env: { apiKey: "mm-env-token" }, // pragma: allowlist secret
|
||||
});
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
|
||||
@@ -28,7 +28,7 @@ describe("applyAuthChoiceOpenAI", () => {
|
||||
|
||||
it("writes env-backed OpenAI key as plaintext by default", async () => {
|
||||
const agentDir = await setupTempState();
|
||||
process.env.OPENAI_API_KEY = "sk-openai-env";
|
||||
process.env.OPENAI_API_KEY = "sk-openai-env"; // pragma: allowlist secret
|
||||
|
||||
const confirm = vi.fn(async () => true);
|
||||
const text = vi.fn(async () => "unused");
|
||||
@@ -62,7 +62,7 @@ describe("applyAuthChoiceOpenAI", () => {
|
||||
|
||||
it("writes env-backed OpenAI key as keyRef when secret-input-mode=ref", async () => {
|
||||
const agentDir = await setupTempState();
|
||||
process.env.OPENAI_API_KEY = "sk-openai-env";
|
||||
process.env.OPENAI_API_KEY = "sk-openai-env"; // pragma: allowlist secret
|
||||
|
||||
const confirm = vi.fn(async () => true);
|
||||
const text = vi.fn(async () => "unused");
|
||||
|
||||
@@ -52,7 +52,7 @@ describe("volcengine/byteplus auth choice", () => {
|
||||
defaultSelect?: string;
|
||||
confirmResult?: boolean;
|
||||
textValue?: string;
|
||||
secretInputMode?: "ref";
|
||||
secretInputMode?: "ref"; // pragma: allowlist secret
|
||||
},
|
||||
) {
|
||||
const agentDir = await setupTempState();
|
||||
|
||||
@@ -676,7 +676,7 @@ describe("applyAuthChoice", () => {
|
||||
envValue: "gateway-ref-key",
|
||||
profileId: "vercel-ai-gateway:default",
|
||||
provider: "vercel-ai-gateway",
|
||||
opts: { secretInputMode: "ref" },
|
||||
opts: { secretInputMode: "ref" }, // pragma: allowlist secret
|
||||
expectEnvPrompt: false,
|
||||
expectedTextCalls: 1,
|
||||
expectedKeyRef: { source: "env", provider: "default", id: "AI_GATEWAY_API_KEY" },
|
||||
@@ -742,7 +742,7 @@ describe("applyAuthChoice", () => {
|
||||
|
||||
it("retries ref setup when provider preflight fails and can switch to env ref", async () => {
|
||||
await setupTempState();
|
||||
process.env.OPENAI_API_KEY = "sk-openai-env";
|
||||
process.env.OPENAI_API_KEY = "sk-openai-env"; // pragma: allowlist secret
|
||||
|
||||
const selectValues: Array<"provider" | "env" | "filemain"> = ["provider", "filemain", "env"];
|
||||
const select = vi.fn(async (params: Parameters<WizardPrompter["select"]>[0]) => {
|
||||
@@ -783,7 +783,7 @@ describe("applyAuthChoice", () => {
|
||||
prompter,
|
||||
runtime,
|
||||
setDefaultModel: false,
|
||||
opts: { secretInputMode: "ref" },
|
||||
opts: { secretInputMode: "ref" }, // pragma: allowlist secret
|
||||
});
|
||||
|
||||
expect(result.config.auth?.profiles?.["openai:default"]).toMatchObject({
|
||||
@@ -952,7 +952,7 @@ describe("applyAuthChoice", () => {
|
||||
|
||||
it("ignores legacy LiteLLM oauth profiles when selecting litellm-api-key", async () => {
|
||||
await setupTempState();
|
||||
process.env.LITELLM_API_KEY = "sk-litellm-test";
|
||||
process.env.LITELLM_API_KEY = "sk-litellm-test"; // pragma: allowlist secret
|
||||
|
||||
const authProfilePath = authProfilePathForAgent(requireOpenClawAgentDir());
|
||||
await fs.writeFile(
|
||||
@@ -1018,7 +1018,7 @@ describe("applyAuthChoice", () => {
|
||||
textValues: string[];
|
||||
confirmValue: boolean;
|
||||
opts?: {
|
||||
secretInputMode?: "ref";
|
||||
secretInputMode?: "ref"; // pragma: allowlist secret
|
||||
cloudflareAiGatewayAccountId?: string;
|
||||
cloudflareAiGatewayGatewayId?: string;
|
||||
cloudflareAiGatewayApiKey?: string;
|
||||
@@ -1046,7 +1046,7 @@ describe("applyAuthChoice", () => {
|
||||
textValues: ["cf-account-id-ref", "cf-gateway-id-ref"],
|
||||
confirmValue: true,
|
||||
opts: {
|
||||
secretInputMode: "ref",
|
||||
secretInputMode: "ref", // pragma: allowlist secret
|
||||
},
|
||||
expectEnvPrompt: false,
|
||||
expectedTextCalls: 3,
|
||||
@@ -1062,7 +1062,7 @@ describe("applyAuthChoice", () => {
|
||||
opts: {
|
||||
cloudflareAiGatewayAccountId: "acc-direct",
|
||||
cloudflareAiGatewayGatewayId: "gw-direct",
|
||||
cloudflareAiGatewayApiKey: "cf-direct-key",
|
||||
cloudflareAiGatewayApiKey: "cf-direct-key", // pragma: allowlist secret
|
||||
},
|
||||
expectEnvPrompt: false,
|
||||
expectedTextCalls: 0,
|
||||
@@ -1219,7 +1219,7 @@ describe("applyAuthChoice", () => {
|
||||
baseUrl: "https://portal.qwen.ai/v1",
|
||||
api: "openai-completions",
|
||||
defaultModel: "qwen-portal/coder-model",
|
||||
apiKey: "qwen-oauth",
|
||||
apiKey: "qwen-oauth", // pragma: allowlist secret
|
||||
},
|
||||
{
|
||||
authChoice: "minimax-portal",
|
||||
@@ -1231,7 +1231,7 @@ describe("applyAuthChoice", () => {
|
||||
baseUrl: "https://api.minimax.io/anthropic",
|
||||
api: "anthropic-messages",
|
||||
defaultModel: "minimax-portal/MiniMax-M2.5",
|
||||
apiKey: "minimax-oauth",
|
||||
apiKey: "minimax-oauth", // pragma: allowlist secret
|
||||
selectValue: "oauth",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -123,8 +123,8 @@ function makeUnavailableHttpSlackPlugin(): ChannelPlugin {
|
||||
botTokenSource: "config",
|
||||
botTokenStatus: "available",
|
||||
signingSecret: "",
|
||||
signingSecretSource: "config",
|
||||
signingSecretStatus: "configured_unavailable",
|
||||
signingSecretSource: "config", // pragma: allowlist secret
|
||||
signingSecretStatus: "configured_unavailable", // pragma: allowlist secret
|
||||
}),
|
||||
resolveAccount: () => ({
|
||||
name: "Primary",
|
||||
|
||||
@@ -21,7 +21,7 @@ describe("buildGatewayAuthConfig", () => {
|
||||
const result = buildGatewayAuthConfig({
|
||||
existing: {
|
||||
mode: "password",
|
||||
password: "secret",
|
||||
password: "secret", // pragma: allowlist secret
|
||||
allowTailscale: true,
|
||||
},
|
||||
mode: "token",
|
||||
@@ -35,7 +35,7 @@ describe("buildGatewayAuthConfig", () => {
|
||||
const result = buildGatewayAuthConfig({
|
||||
existing: {
|
||||
mode: "password",
|
||||
password: "secret",
|
||||
password: "secret", // pragma: allowlist secret
|
||||
allowTailscale: false,
|
||||
},
|
||||
mode: "token",
|
||||
@@ -53,19 +53,19 @@ describe("buildGatewayAuthConfig", () => {
|
||||
const result = buildGatewayAuthConfig({
|
||||
existing: { mode: "token", token: "abc" },
|
||||
mode: "password",
|
||||
password: "secret",
|
||||
password: "secret", // pragma: allowlist secret
|
||||
});
|
||||
|
||||
expect(result).toEqual({ mode: "password", password: "secret" });
|
||||
expect(result).toEqual({ mode: "password", password: "secret" }); // pragma: allowlist secret
|
||||
});
|
||||
|
||||
it("does not silently omit password when literal string is provided", () => {
|
||||
const result = buildGatewayAuthConfig({
|
||||
mode: "password",
|
||||
password: "undefined",
|
||||
password: "undefined", // pragma: allowlist secret
|
||||
});
|
||||
|
||||
expect(result).toEqual({ mode: "password", password: "undefined" });
|
||||
expect(result).toEqual({ mode: "password", password: "undefined" }); // pragma: allowlist secret
|
||||
});
|
||||
|
||||
it("generates random token for missing, empty, and coerced-literal token inputs", () => {
|
||||
@@ -165,7 +165,7 @@ describe("buildGatewayAuthConfig", () => {
|
||||
existing: {
|
||||
mode: "token",
|
||||
token: "abc",
|
||||
password: "secret",
|
||||
password: "secret", // pragma: allowlist secret
|
||||
},
|
||||
mode: "trusted-proxy",
|
||||
trustedProxy: {
|
||||
|
||||
@@ -125,7 +125,7 @@ describe("buildGatewayInstallPlan", () => {
|
||||
config: {
|
||||
env: {
|
||||
vars: {
|
||||
GOOGLE_API_KEY: "test-key",
|
||||
GOOGLE_API_KEY: "test-key", // pragma: allowlist secret
|
||||
},
|
||||
CUSTOM_VAR: "custom-value",
|
||||
},
|
||||
|
||||
@@ -6,6 +6,8 @@ import {
|
||||
shouldRequireGatewayTokenForInstall,
|
||||
} from "./doctor-gateway-auth-token.js";
|
||||
|
||||
const envVar = (...parts: string[]) => parts.join("_");
|
||||
|
||||
describe("resolveGatewayAuthTokenForService", () => {
|
||||
it("returns plaintext gateway.auth.token when configured", async () => {
|
||||
const resolved = await resolveGatewayAuthTokenForService(
|
||||
@@ -163,7 +165,8 @@ describe("shouldRequireGatewayTokenForInstall", () => {
|
||||
});
|
||||
|
||||
it("requires token in inferred mode when password env exists only in shell", async () => {
|
||||
await withEnvAsync({ OPENCLAW_GATEWAY_PASSWORD: "password-from-env" }, async () => {
|
||||
await withEnvAsync({ [envVar("OPENCLAW", "GATEWAY", "PASSWORD")]: "password-from-env" }, async () => {
|
||||
// pragma: allowlist secret
|
||||
const required = shouldRequireGatewayTokenForInstall(
|
||||
{
|
||||
gateway: {
|
||||
@@ -203,7 +206,7 @@ describe("shouldRequireGatewayTokenForInstall", () => {
|
||||
},
|
||||
env: {
|
||||
vars: {
|
||||
OPENCLAW_GATEWAY_PASSWORD: "configured-password",
|
||||
OPENCLAW_GATEWAY_PASSWORD: "configured-password", // pragma: allowlist secret
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
|
||||
@@ -275,7 +275,7 @@ describe("noteMemorySearchHealth", () => {
|
||||
resolveApiKeyForProvider.mockImplementation(async ({ provider }: { provider: string }) => {
|
||||
if (provider === "ollama") {
|
||||
return {
|
||||
apiKey: "ollama-local",
|
||||
apiKey: "ollama-local", // pragma: allowlist secret
|
||||
source: "env: OLLAMA_API_KEY",
|
||||
mode: "api-key",
|
||||
};
|
||||
|
||||
@@ -95,7 +95,7 @@ describe("doctor command", () => {
|
||||
mode: "local",
|
||||
auth: {
|
||||
token: "token-value",
|
||||
password: "password-value",
|
||||
password: "password-value", // pragma: allowlist secret
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -140,7 +140,7 @@ describe("resolveGatewayInstallToken", () => {
|
||||
gateway: {
|
||||
auth: {
|
||||
token: "token-value",
|
||||
password: "password-value",
|
||||
password: "password-value", // pragma: allowlist secret
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
|
||||
@@ -180,7 +180,7 @@ describe("resolveAuthForTarget", () => {
|
||||
},
|
||||
remote: {
|
||||
token: "remote-token",
|
||||
password: "remote-password",
|
||||
password: "remote-password", // pragma: allowlist secret
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -190,7 +190,7 @@ function createTelegramSecretRawConfig() {
|
||||
return {
|
||||
channels: {
|
||||
telegram: {
|
||||
token: { $secret: "vault://telegram/token" },
|
||||
token: { $secret: "vault://telegram/token" }, // pragma: allowlist secret
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -102,7 +102,7 @@ describe("promptDefaultModel", () => {
|
||||
expect(result.config?.models?.providers?.vllm).toMatchObject({
|
||||
baseUrl: "http://127.0.0.1:8000/v1",
|
||||
api: "openai-completions",
|
||||
apiKey: "VLLM_API_KEY",
|
||||
apiKey: "VLLM_API_KEY", // pragma: allowlist secret
|
||||
models: [
|
||||
{ id: "meta-llama/Meta-Llama-3-8B-Instruct", name: "meta-llama/Meta-Llama-3-8B-Instruct" },
|
||||
],
|
||||
|
||||
@@ -150,7 +150,7 @@ describe("Kilo Gateway provider config", () => {
|
||||
describe("env var resolution", () => {
|
||||
it("resolves KILOCODE_API_KEY from env", () => {
|
||||
const envSnapshot = captureEnv(["KILOCODE_API_KEY"]);
|
||||
process.env.KILOCODE_API_KEY = "test-kilo-key";
|
||||
process.env.KILOCODE_API_KEY = "test-kilo-key"; // pragma: allowlist secret
|
||||
|
||||
try {
|
||||
const result = resolveEnvApiKey("kilocode");
|
||||
@@ -177,7 +177,7 @@ describe("Kilo Gateway provider config", () => {
|
||||
it("resolves the kilocode api key via resolveApiKeyForProvider", async () => {
|
||||
const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-"));
|
||||
const envSnapshot = captureEnv(["KILOCODE_API_KEY"]);
|
||||
process.env.KILOCODE_API_KEY = "kilo-provider-test-key";
|
||||
process.env.KILOCODE_API_KEY = "kilo-provider-test-key"; // pragma: allowlist secret
|
||||
|
||||
try {
|
||||
const auth = await resolveApiKeyForProvider({
|
||||
|
||||
@@ -94,7 +94,7 @@ describe("onboard auth credentials secret refs", () => {
|
||||
envValue: "sk-moonshot-env",
|
||||
profileId: "moonshot:default",
|
||||
apply: async (agentDir) => {
|
||||
await setMoonshotApiKey("sk-moonshot-env", agentDir, { secretInputMode: "ref" });
|
||||
await setMoonshotApiKey("sk-moonshot-env", agentDir, { secretInputMode: "ref" }); // pragma: allowlist secret
|
||||
},
|
||||
expected: {
|
||||
keyRef: { source: "env", provider: "default", id: "MOONSHOT_API_KEY" },
|
||||
@@ -136,10 +136,10 @@ describe("onboard auth credentials secret refs", () => {
|
||||
it("preserves cloudflare metadata when storing keyRef", async () => {
|
||||
const env = await setupAuthTestEnv("openclaw-onboard-auth-credentials-cloudflare-");
|
||||
lifecycle.setStateDir(env.stateDir);
|
||||
process.env.CLOUDFLARE_AI_GATEWAY_API_KEY = "cf-secret";
|
||||
process.env.CLOUDFLARE_AI_GATEWAY_API_KEY = "cf-secret"; // pragma: allowlist secret
|
||||
|
||||
await setCloudflareAiGatewayConfig("account-1", "gateway-1", "cf-secret", env.agentDir, {
|
||||
secretInputMode: "ref",
|
||||
secretInputMode: "ref", // pragma: allowlist secret
|
||||
});
|
||||
|
||||
const parsed = await readAuthProfilesForAgent<{
|
||||
@@ -175,7 +175,7 @@ describe("onboard auth credentials secret refs", () => {
|
||||
envValue: "sk-openai-env",
|
||||
profileId: "openai:default",
|
||||
apply: async (agentDir) => {
|
||||
await setOpenaiApiKey("sk-openai-env", agentDir, { secretInputMode: "ref" });
|
||||
await setOpenaiApiKey("sk-openai-env", agentDir, { secretInputMode: "ref" }); // pragma: allowlist secret
|
||||
},
|
||||
expected: {
|
||||
keyRef: { source: "env", provider: "default", id: "OPENAI_API_KEY" },
|
||||
@@ -187,11 +187,11 @@ describe("onboard auth credentials secret refs", () => {
|
||||
it("stores env-backed volcengine and byteplus keys as keyRef in ref mode", async () => {
|
||||
const env = await setupAuthTestEnv("openclaw-onboard-auth-credentials-volc-byte-");
|
||||
lifecycle.setStateDir(env.stateDir);
|
||||
process.env.VOLCANO_ENGINE_API_KEY = "volcengine-secret";
|
||||
process.env.BYTEPLUS_API_KEY = "byteplus-secret";
|
||||
process.env.VOLCANO_ENGINE_API_KEY = "volcengine-secret"; // pragma: allowlist secret
|
||||
process.env.BYTEPLUS_API_KEY = "byteplus-secret"; // pragma: allowlist secret
|
||||
|
||||
await setVolcengineApiKey("volcengine-secret", env.agentDir, { secretInputMode: "ref" });
|
||||
await setByteplusApiKey("byteplus-secret", env.agentDir, { secretInputMode: "ref" });
|
||||
await setVolcengineApiKey("volcengine-secret", env.agentDir, { secretInputMode: "ref" }); // pragma: allowlist secret
|
||||
await setByteplusApiKey("byteplus-secret", env.agentDir, { secretInputMode: "ref" }); // pragma: allowlist secret
|
||||
|
||||
const parsed = await readAuthProfilesForAgent<{
|
||||
profiles?: Record<string, { key?: string; keyRef?: unknown }>;
|
||||
|
||||
@@ -420,7 +420,7 @@ describe("applyMinimaxApiConfig", () => {
|
||||
providers: {
|
||||
anthropic: {
|
||||
baseUrl: "https://api.anthropic.com",
|
||||
apiKey: "anthropic-key",
|
||||
apiKey: "anthropic-key", // pragma: allowlist secret
|
||||
api: "anthropic-messages",
|
||||
models: [
|
||||
{
|
||||
|
||||
@@ -58,7 +58,7 @@ describe("detectZaiEndpoint", () => {
|
||||
|
||||
for (const scenario of scenarios) {
|
||||
const detected = await detectZaiEndpoint({
|
||||
apiKey: "sk-test",
|
||||
apiKey: "sk-test", // pragma: allowlist secret
|
||||
fetchFn: makeFetch(scenario.responses),
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user