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:
Vincent Koc
2026-03-07 13:06:35 -05:00
committed by GitHub
parent 46e324e269
commit e4d80ed556
137 changed files with 1231 additions and 2700 deletions

View File

@@ -23,8 +23,8 @@ vi.mock("@mariozechner/pi-ai", async () => {
...actual,
getOAuthApiKey: getOAuthApiKeyMock,
getOAuthProviders: () => [
{ id: "openai-codex", envApiKey: "OPENAI_API_KEY", oauthTokenEnv: "OPENAI_OAUTH_TOKEN" },
{ id: "anthropic", envApiKey: "ANTHROPIC_API_KEY", oauthTokenEnv: "ANTHROPIC_OAUTH_TOKEN" },
{ id: "openai-codex", envApiKey: "OPENAI_API_KEY", oauthTokenEnv: "OPENAI_OAUTH_TOKEN" }, // pragma: allowlist secret
{ id: "anthropic", envApiKey: "ANTHROPIC_API_KEY", oauthTokenEnv: "ANTHROPIC_OAUTH_TOKEN" }, // pragma: allowlist secret
],
};
});
@@ -91,7 +91,7 @@ describe("resolveApiKeyForProfile openai-codex refresh fallback", () => {
});
expect(result).toEqual({
apiKey: "cached-access-token",
apiKey: "cached-access-token", // pragma: allowlist secret
provider: "openai-codex",
email: undefined,
});

View File

@@ -54,7 +54,7 @@ describe("compaction toolResult details stripping", () => {
messages,
// Minimal shape; compaction won't use these fields in our mocked generateSummary.
model: { id: "mock", name: "mock", contextWindow: 10000, maxTokens: 1000 } as never,
apiKey: "test",
apiKey: "test", // pragma: allowlist secret
signal: new AbortController().signal,
reserveTokens: 100,
maxChunkTokens: 5000,

View File

@@ -188,7 +188,7 @@ describe("memory search config", () => {
provider: "openai",
remote: {
baseUrl: "https://default.example/v1",
apiKey: "default-key",
apiKey: "default-key", // pragma: allowlist secret
headers: { "X-Default": "on" },
},
},
@@ -209,7 +209,7 @@ describe("memory search config", () => {
const resolved = resolveMemorySearchConfig(cfg, "main");
expect(resolved?.remote).toEqual({
baseUrl: "https://agent.example/v1",
apiKey: "default-key",
apiKey: "default-key", // pragma: allowlist secret
headers: { "X-Default": "on" },
batch: {
enabled: false,
@@ -228,7 +228,7 @@ describe("memory search config", () => {
memorySearch: {
provider: "openai",
remote: {
apiKey: { source: "env", provider: "default", id: "OPENAI_API_KEY" },
apiKey: { source: "env", provider: "default", id: "OPENAI_API_KEY" }, // pragma: allowlist secret
headers: { "X-Default": "on" },
},
},

View File

@@ -32,7 +32,7 @@ describe("resolveModelAuthLabel", () => {
"github-copilot:default": {
type: "token",
provider: "github-copilot",
token: "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
token: "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // pragma: allowlist secret
tokenRef: { source: "env", provider: "default", id: "GITHUB_TOKEN" },
},
},
@@ -52,7 +52,7 @@ describe("resolveModelAuthLabel", () => {
});
it("does not include api-key value in label for api-key profiles", () => {
const shortSecret = "abc123";
const shortSecret = "abc123"; // pragma: allowlist secret
ensureAuthProfileStoreMock.mockReturnValue({
version: 1,
profiles: {

View File

@@ -7,6 +7,8 @@ import { withEnvAsync } from "../test-utils/env.js";
import { ensureAuthProfileStore } from "./auth-profiles.js";
import { getApiKeyForModel, resolveApiKeyForProvider, resolveEnvApiKey } from "./model-auth.js";
const envVar = (...parts: string[]) => parts.join("_");
const oauthFixture = {
access: "access-token",
refresh: "refresh-token",
@@ -191,7 +193,7 @@ describe("getApiKeyForModel", () => {
await withEnvAsync(
{
ZAI_API_KEY: undefined,
Z_AI_API_KEY: "zai-test-key",
Z_AI_API_KEY: "zai-test-key", // pragma: allowlist secret
},
async () => {
const resolved = await resolveApiKeyForProvider({
@@ -205,7 +207,8 @@ describe("getApiKeyForModel", () => {
});
it("resolves Synthetic API key from env", async () => {
await withEnvAsync({ SYNTHETIC_API_KEY: "synthetic-test-key" }, async () => {
await withEnvAsync({ [envVar("SYNTHETIC", "API", "KEY")]: "synthetic-test-key" }, async () => {
// pragma: allowlist secret
const resolved = await resolveApiKeyForProvider({
provider: "synthetic",
store: { version: 1, profiles: {} },
@@ -216,7 +219,8 @@ describe("getApiKeyForModel", () => {
});
it("resolves Qianfan API key from env", async () => {
await withEnvAsync({ QIANFAN_API_KEY: "qianfan-test-key" }, async () => {
await withEnvAsync({ [envVar("QIANFAN", "API", "KEY")]: "qianfan-test-key" }, async () => {
// pragma: allowlist secret
const resolved = await resolveApiKeyForProvider({
provider: "qianfan",
store: { version: 1, profiles: {} },
@@ -250,7 +254,8 @@ describe("getApiKeyForModel", () => {
});
it("prefers explicit OLLAMA_API_KEY over synthetic local key", async () => {
await withEnvAsync({ OLLAMA_API_KEY: "env-ollama-key" }, async () => {
await withEnvAsync({ [envVar("OLLAMA", "API", "KEY")]: "env-ollama-key" }, async () => {
// pragma: allowlist secret
const resolved = await resolveApiKeyForProvider({
provider: "ollama",
store: { version: 1, profiles: {} },
@@ -283,7 +288,8 @@ describe("getApiKeyForModel", () => {
});
it("resolves Vercel AI Gateway API key from env", async () => {
await withEnvAsync({ AI_GATEWAY_API_KEY: "gateway-test-key" }, async () => {
await withEnvAsync({ [envVar("AI_GATEWAY", "API", "KEY")]: "gateway-test-key" }, async () => {
// pragma: allowlist secret
const resolved = await resolveApiKeyForProvider({
provider: "vercel-ai-gateway",
store: { version: 1, profiles: {} },
@@ -296,9 +302,9 @@ describe("getApiKeyForModel", () => {
it("prefers Bedrock bearer token over access keys and profile", async () => {
await expectBedrockAuthSource({
env: {
AWS_BEARER_TOKEN_BEDROCK: "bedrock-token",
AWS_BEARER_TOKEN_BEDROCK: "bedrock-token", // pragma: allowlist secret
AWS_ACCESS_KEY_ID: "access-key",
AWS_SECRET_ACCESS_KEY: "secret-key",
[envVar("AWS", "SECRET", "ACCESS", "KEY")]: "secret-key", // pragma: allowlist secret
AWS_PROFILE: "profile",
},
expectedSource: "AWS_BEARER_TOKEN_BEDROCK",
@@ -310,7 +316,7 @@ describe("getApiKeyForModel", () => {
env: {
AWS_BEARER_TOKEN_BEDROCK: undefined,
AWS_ACCESS_KEY_ID: "access-key",
AWS_SECRET_ACCESS_KEY: "secret-key",
[envVar("AWS", "SECRET", "ACCESS", "KEY")]: "secret-key", // pragma: allowlist secret
AWS_PROFILE: "profile",
},
expectedSource: "AWS_ACCESS_KEY_ID",
@@ -330,7 +336,8 @@ describe("getApiKeyForModel", () => {
});
it("accepts VOYAGE_API_KEY for voyage", async () => {
await withEnvAsync({ VOYAGE_API_KEY: "voyage-test-key" }, async () => {
await withEnvAsync({ [envVar("VOYAGE", "API", "KEY")]: "voyage-test-key" }, async () => {
// pragma: allowlist secret
const voyage = await resolveApiKeyForProvider({
provider: "voyage",
store: { version: 1, profiles: {} },
@@ -341,7 +348,8 @@ describe("getApiKeyForModel", () => {
});
it("strips embedded CR/LF from ANTHROPIC_API_KEY", async () => {
await withEnvAsync({ ANTHROPIC_API_KEY: "sk-ant-test-\r\nkey" }, async () => {
await withEnvAsync({ [envVar("ANTHROPIC", "API", "KEY")]: "sk-ant-test-\r\nkey" }, async () => {
// pragma: allowlist secret
const resolved = resolveEnvApiKey("anthropic");
expect(resolved?.apiKey).toBe("sk-ant-test-key");
expect(resolved?.source).toContain("ANTHROPIC_API_KEY");

View File

@@ -95,6 +95,7 @@ const makeAttempt = (overrides: Partial<EmbeddedRunAttemptResult>): EmbeddedRunA
});
function makeConfig(): OpenClawConfig {
const apiKeyField = ["api", "Key"].join("");
return {
agents: {
defaults: {
@@ -108,7 +109,7 @@ function makeConfig(): OpenClawConfig {
providers: {
openai: {
api: "openai-responses",
apiKey: "sk-openai",
[apiKeyField]: "openai-test-key", // pragma: allowlist secret
baseUrl: "https://example.com/openai",
models: [
{
@@ -124,7 +125,7 @@ function makeConfig(): OpenClawConfig {
},
groq: {
api: "openai-responses",
apiKey: "sk-groq",
[apiKeyField]: "groq-test-key", // pragma: allowlist secret
baseUrl: "https://example.com/groq",
models: [
{

View File

@@ -44,7 +44,7 @@ async function writeAgentModelsJson(content: unknown): Promise<void> {
function createMergeConfigProvider() {
return {
baseUrl: "https://config.example/v1",
apiKey: "CONFIG_KEY",
apiKey: "CONFIG_KEY", // pragma: allowlist secret
api: "openai-responses" as const,
models: [
{
@@ -115,7 +115,7 @@ describe("models-config", () => {
providers: {
anthropic: {
baseUrl: "https://relay.example.com/api",
apiKey: "cr_xxxx",
apiKey: "cr_xxxx", // pragma: allowlist secret
models: [{ id: "claude-opus-4-6", name: "Claude Opus 4.6" }],
},
},
@@ -179,7 +179,7 @@ describe("models-config", () => {
providers: {
existing: {
baseUrl: "http://localhost:1234/v1",
apiKey: "EXISTING_KEY",
apiKey: "EXISTING_KEY", // pragma: allowlist secret
api: "openai-completions",
models: [
{
@@ -212,7 +212,7 @@ describe("models-config", () => {
await withTempHome(async () => {
const parsed = await runCustomProviderMergeTest({
baseUrl: "https://agent.example/v1",
apiKey: "AGENT_KEY",
apiKey: "AGENT_KEY", // pragma: allowlist secret
api: "openai-responses",
models: [{ id: "agent-model", name: "Agent model", input: ["text"] }],
});

View File

@@ -14,7 +14,7 @@ describe("models-config", () => {
providers: {
google: {
baseUrl: "https://generativelanguage.googleapis.com/v1beta",
apiKey: "GEMINI_KEY",
apiKey: "GEMINI_KEY", // pragma: allowlist secret
api: "google-generative-ai",
models: [
{

View File

@@ -24,7 +24,7 @@ function buildProvider(modelIds: string[]): ProviderConfig {
return {
baseUrl: "https://example.invalid/v1",
api: "openai-completions",
apiKey: "EXAMPLE_KEY",
apiKey: "EXAMPLE_KEY", // pragma: allowlist secret
models: modelIds.map((id) => buildModel(id)),
};
}

View File

@@ -11,7 +11,7 @@ describe("Kilo Gateway implicit provider", () => {
it("should include kilocode when KILOCODE_API_KEY is configured", async () => {
const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-"));
const envSnapshot = captureEnv(["KILOCODE_API_KEY"]);
process.env.KILOCODE_API_KEY = "test-key";
process.env.KILOCODE_API_KEY = "test-key"; // pragma: allowlist secret
try {
const providers = await resolveImplicitProviders({ agentDir });

View File

@@ -9,7 +9,7 @@ describe("kimi-coding implicit provider (#22409)", () => {
it("should include kimi-coding when KIMI_API_KEY is configured", async () => {
const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-"));
const envSnapshot = captureEnv(["KIMI_API_KEY"]);
process.env.KIMI_API_KEY = "test-key";
process.env.KIMI_API_KEY = "test-key"; // pragma: allowlist secret
try {
const providers = await resolveImplicitProviders({ agentDir });

View File

@@ -14,7 +14,7 @@ describe("normalizeProviders", () => {
" dashscope-vision ": {
baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1",
api: "openai-completions",
apiKey: "DASHSCOPE_API_KEY",
apiKey: "DASHSCOPE_API_KEY", // pragma: allowlist secret
models: [
{
id: "qwen-vl-max",
@@ -44,13 +44,13 @@ describe("normalizeProviders", () => {
openai: {
baseUrl: "https://api.openai.com/v1",
api: "openai-completions",
apiKey: "OPENAI_API_KEY",
apiKey: "OPENAI_API_KEY", // pragma: allowlist secret
models: [],
},
" openai ": {
baseUrl: "https://example.com/v1",
api: "openai-completions",
apiKey: "CUSTOM_OPENAI_API_KEY",
apiKey: "CUSTOM_OPENAI_API_KEY", // pragma: allowlist secret
models: [
{
id: "gpt-4.1-mini",

View File

@@ -51,7 +51,7 @@ describe("Ollama provider", () => {
};
async function withOllamaApiKey<T>(run: () => Promise<T>): Promise<T> {
process.env.OLLAMA_API_KEY = "test-key";
process.env.OLLAMA_API_KEY = "test-key"; // pragma: allowlist secret
try {
return await run();
} finally {
@@ -245,7 +245,7 @@ describe("Ollama provider", () => {
ollama: {
baseUrl: "http://remote-ollama:11434/v1",
models: explicitModels,
apiKey: "config-ollama-key",
apiKey: "config-ollama-key", // pragma: allowlist secret
},
},
});
@@ -271,7 +271,7 @@ describe("Ollama provider", () => {
baseUrl: "http://remote-ollama:11434/v1",
api: "openai-completions",
models: [],
apiKey: "config-ollama-key",
apiKey: "config-ollama-key", // pragma: allowlist secret
},
},
});

View File

@@ -5,10 +5,14 @@ import { describe, expect, it } from "vitest";
import { withEnvAsync } from "../test-utils/env.js";
import { resolveImplicitProviders } from "./models-config.providers.js";
const qianfanApiKeyEnv = ["QIANFAN_API", "KEY"].join("_");
describe("Qianfan provider", () => {
it("should include qianfan when QIANFAN_API_KEY is configured", async () => {
// pragma: allowlist secret
const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-"));
await withEnvAsync({ QIANFAN_API_KEY: "test-key" }, async () => {
const qianfanApiKey = "test-key"; // pragma: allowlist secret
await withEnvAsync({ [qianfanApiKeyEnv]: qianfanApiKey }, async () => {
const providers = await resolveImplicitProviders({ agentDir });
expect(providers?.qianfan).toBeDefined();
expect(providers?.qianfan?.apiKey).toBe("QIANFAN_API_KEY");

View File

@@ -10,7 +10,7 @@ describe("Volcengine and BytePlus providers", () => {
it("includes volcengine and volcengine-plan when VOLCANO_ENGINE_API_KEY is configured", async () => {
const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-"));
const envSnapshot = captureEnv(["VOLCANO_ENGINE_API_KEY"]);
process.env.VOLCANO_ENGINE_API_KEY = "test-key";
process.env.VOLCANO_ENGINE_API_KEY = "test-key"; // pragma: allowlist secret
try {
const providers = await resolveImplicitProviders({ agentDir });
@@ -26,7 +26,7 @@ describe("Volcengine and BytePlus providers", () => {
it("includes byteplus and byteplus-plan when BYTEPLUS_API_KEY is configured", async () => {
const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-"));
const envSnapshot = captureEnv(["BYTEPLUS_API_KEY"]);
process.env.BYTEPLUS_API_KEY = "test-key";
process.env.BYTEPLUS_API_KEY = "test-key"; // pragma: allowlist secret
try {
const providers = await resolveImplicitProviders({ agentDir });

View File

@@ -97,7 +97,7 @@ describe("models-config", () => {
envValue: "sk-minimax-test",
providerKey: "minimax",
expectedBaseUrl: "https://api.minimax.io/anthropic",
expectedApiKeyRef: "MINIMAX_API_KEY",
expectedApiKeyRef: "MINIMAX_API_KEY", // pragma: allowlist secret
expectedModelIds: ["MiniMax-M2.5", "MiniMax-VL-01"],
});
});
@@ -110,7 +110,7 @@ describe("models-config", () => {
envValue: "sk-synthetic-test",
providerKey: "synthetic",
expectedBaseUrl: "https://api.synthetic.new/anthropic",
expectedApiKeyRef: "SYNTHETIC_API_KEY",
expectedApiKeyRef: "SYNTHETIC_API_KEY", // pragma: allowlist secret
expectedModelIds: ["hf:MiniMaxAI/MiniMax-M2.5"],
});
});

View File

@@ -13,7 +13,7 @@ describe("resolveOwnerDisplaySetting", () => {
expect(resolveOwnerDisplaySetting(cfg)).toEqual({
ownerDisplay: "hash",
ownerDisplaySecret: "owner-secret",
ownerDisplaySecret: "owner-secret", // pragma: allowlist secret
});
});
@@ -38,7 +38,7 @@ describe("resolveOwnerDisplaySetting", () => {
const cfg = {
commands: {
ownerDisplay: "raw",
ownerDisplaySecret: "owner-secret",
ownerDisplaySecret: "owner-secret", // pragma: allowlist secret
},
} as OpenClawConfig;
@@ -67,7 +67,7 @@ describe("ensureOwnerDisplaySecret", () => {
const cfg = {
commands: {
ownerDisplay: "hash",
ownerDisplaySecret: "existing-owner-secret",
ownerDisplaySecret: "existing-owner-secret", // pragma: allowlist secret
},
} as OpenClawConfig;

View File

@@ -1072,7 +1072,7 @@ describe("applyExtraParamsToAgent", () => {
// Simulate pi-agent-core passing apiKey in options (API key, not OAuth token)
void agent.streamFn?.(model, context, {
apiKey: "sk-ant-api03-test",
apiKey: "sk-ant-api03-test", // pragma: allowlist secret
headers: { "X-Custom": "1" },
});
@@ -1130,7 +1130,7 @@ describe("applyExtraParamsToAgent", () => {
// Simulate pi-agent-core passing an OAuth token (sk-ant-oat-*) as apiKey
void agent.streamFn?.(model, context, {
apiKey: "sk-ant-oat01-test-oauth-token",
apiKey: "sk-ant-oat01-test-oauth-token", // pragma: allowlist secret
headers: { "X-Custom": "1" },
});
@@ -1151,7 +1151,7 @@ describe("applyExtraParamsToAgent", () => {
cfg,
modelId: "claude-sonnet-4-5",
options: {
apiKey: "sk-ant-api03-test",
apiKey: "sk-ant-api03-test", // pragma: allowlist secret
headers: { "anthropic-beta": "prompt-caching-2024-07-31" },
},
});

View File

@@ -156,7 +156,7 @@ const makeAgentOverrideOnlyFallbackConfig = (agentId: string): OpenClawConfig =>
providers: {
openai: {
api: "openai-responses",
apiKey: "sk-test",
apiKey: "sk-test", // pragma: allowlist secret
baseUrl: "https://example.com",
models: [
{

View File

@@ -697,7 +697,7 @@ describe("compaction-safeguard recent-turn preservation", () => {
"Track id a1b2c3d4e5f6 plus A1B2C3D4E5F6 and URL https://example.com/a and /tmp/x.log plus port host.local:18789",
);
expect(identifiers.length).toBeGreaterThan(0);
expect(identifiers).toContain("A1B2C3D4E5F6");
expect(identifiers).toContain("A1B2C3D4E5F6"); // pragma: allowlist secret
const summary = [
"## Decisions",
@@ -724,7 +724,7 @@ describe("compaction-safeguard recent-turn preservation", () => {
const identifiers = extractOpaqueIdentifiers(
"Track id a1b2c3d4e5f6 plus A1B2C3D4E5F6 and again a1b2c3d4e5f6",
);
expect(identifiers.filter((id) => id === "A1B2C3D4E5F6")).toHaveLength(1);
expect(identifiers.filter((id) => id === "A1B2C3D4E5F6")).toHaveLength(1); // pragma: allowlist secret
});
it("dedupes identifiers before applying the result cap", () => {
@@ -843,9 +843,9 @@ describe("compaction-safeguard recent-turn preservation", () => {
"## Pending user asks",
"Provide status.",
"## Exact identifiers",
"a1b2c3d4e5f6",
"a1b2c3d4e5f6", // pragma: allowlist secret
].join("\n"),
identifiers: ["A1B2C3D4E5F6"],
identifiers: ["A1B2C3D4E5F6"], // pragma: allowlist secret
latestAsk: "Provide status.",
identifierPolicy: "strict",
});
@@ -1522,7 +1522,7 @@ describe("compaction-safeguard double-compaction guard", () => {
const { result, getApiKeyMock } = await runCompactionScenario({
sessionManager,
event: mockEvent,
apiKey: "sk-test",
apiKey: "sk-test", // pragma: allowlist secret
});
expect(result).toEqual({ cancel: true });
expect(getApiKeyMock).not.toHaveBeenCalled();

View File

@@ -9,13 +9,16 @@ import {
resetNoVncObserverTokensForTests,
} from "./novnc-auth.js";
const passwordKey = ["pass", "word"].join("");
describe("noVNC auth helpers", () => {
it("builds the default observer URL without password", () => {
expect(buildNoVncDirectUrl(45678)).toBe("http://127.0.0.1:45678/vnc.html");
});
it("builds a fragment-based observer target URL with password", () => {
expect(buildNoVncObserverTargetUrl({ port: 45678, password: "a+b c&d" })).toBe(
const observerPassword = "a+b c&d"; // pragma: allowlist secret
expect(buildNoVncObserverTargetUrl({ port: 45678, [passwordKey]: observerPassword })).toBe(
"http://127.0.0.1:45678/vnc.html#autoconnect=1&resize=remote&password=a%2Bb+c%26d",
);
});
@@ -24,7 +27,7 @@ describe("noVNC auth helpers", () => {
resetNoVncObserverTokensForTests();
const token = issueNoVncObserverToken({
noVncPort: 50123,
password: "abcd1234",
[passwordKey]: "abcd1234", // pragma: allowlist secret
nowMs: 1000,
ttlMs: 100,
});
@@ -33,7 +36,7 @@ describe("noVNC auth helpers", () => {
);
expect(consumeNoVncObserverToken(token, 1050)).toEqual({
noVncPort: 50123,
password: "abcd1234",
[passwordKey]: "abcd1234", // pragma: allowlist secret
});
expect(consumeNoVncObserverToken(token, 1050)).toBeNull();
});
@@ -42,7 +45,7 @@ describe("noVNC auth helpers", () => {
resetNoVncObserverTokensForTests();
const token = issueNoVncObserverToken({
noVncPort: 50123,
password: "abcd1234",
password: "abcd1234", // pragma: allowlist secret
nowMs: 1000,
ttlMs: 100,
});

View File

@@ -5,9 +5,9 @@ describe("sanitizeEnvVars", () => {
it("keeps normal env vars and blocks obvious credentials", () => {
const result = sanitizeEnvVars({
NODE_ENV: "test",
OPENAI_API_KEY: "sk-live-xxx",
OPENAI_API_KEY: "sk-live-xxx", // pragma: allowlist secret
FOO: "bar",
GITHUB_TOKEN: "gh-token",
GITHUB_TOKEN: "gh-token", // pragma: allowlist secret
});
expect(result.allowed).toEqual({

View File

@@ -29,7 +29,7 @@ function mkSessionsSpawnToolCall(content: string): AgentMessage {
describe("sanitizeToolCallInputs redacts sessions_spawn attachments", () => {
it("replaces attachments[].content with __OPENCLAW_REDACTED__", () => {
const secret = "SUPER_SECRET_SHOULD_NOT_PERSIST";
const secret = "SUPER_SECRET_SHOULD_NOT_PERSIST"; // pragma: allowlist secret
const input = [mkSessionsSpawnToolCall(secret)];
const out = sanitizeToolCallInputs(input);
expect(out).toHaveLength(1);
@@ -44,7 +44,7 @@ describe("sanitizeToolCallInputs redacts sessions_spawn attachments", () => {
});
it("redacts attachments content from tool input payloads too", () => {
const secret = "INPUT_SECRET_SHOULD_NOT_PERSIST";
const secret = "INPUT_SECRET_SHOULD_NOT_PERSIST"; // pragma: allowlist secret
const input = castAgentMessages([
{
role: "assistant",

View File

@@ -48,7 +48,7 @@ const ZIP_SLIP_BUFFER = Buffer.from(
);
const TAR_GZ_TRAVERSAL_BUFFER = Buffer.from(
// Prebuilt archive containing ../outside-write/pwned.txt.
"H4sIAK4xm2kAA+2VvU7DMBDH3UoIUWaYLXbcS5PYZegQEKhBRUBbIT4GZBpXCqJNSFySlSdgZed1eCgcUvFRaMsQgVD9k05nW3eWz8nfR0g1GMnY98RmEvlSVMllmAyFR2QqUUEAALUsnHlG7VcPtXwO+djEhm1YlJpAbYrBYAYDhKGoA8xiFEseqaPEUvihkGJanArr92fsk5eC3/x/YWl9GZUROuA9fNjBp3hMtoZWlNWU3SrL5k8/29LpdtvjYZbxqGx1IqT0vr7WCwaEh+GNIGEU3IkhH/YEKpXRxv3FQznsPxdQpGYaZFL/RzxtCu6JqFrYOzBX/wZ81n8NmEERTosocB4Lrn8T8ED6A9EwmHp0Wd1idQK2ZVIAm1ZshlvuttPeabonuyTlUkbkO7k2nGPXcYO9q+tkPzmPk4q1hTsqqXU2K+mDxit/fQ+Lyhf9F9795+tf/WoT/Z8yi+n+/xuoz+1p8Wk0Gs3i8QJSs3VlABAAAA==",
"H4sIAK4xm2kAA+2VvU7DMBDH3UoIUWaYLXbcS5PYZegQEKhBRUBbIT4GZBpXCqJNSFySlSdgZed1eCgcUvFRaMsQgVD9k05nW3eWz8nfR0g1GMnY98RmEvlSVMllmAyFR2QqUUEAALUsnHlG7VcPtXwO+djEhm1YlJpAbYrBYAYDhKGoA8xiFEseqaPEUvihkGJanArr92fsk5eC3/x/YWl9GZUROuA9fNjBp3hMtoZWlNWU3SrL5k8/29LpdtvjYZbxqGx1IqT0vr7WCwaEh+GNIGEU3IkhH/YEKpXRxv3FQznsPxdQpGYaZFL/RzxtCu6JqFrYOzBX/wZ81n8NmEERTosocB4Lrn8T8ED6A9EwmHp0Wd1idQK2ZVIAm1ZshlvuttPeabonuyTlUkbkO7k2nGPXcYO9q+tkPzmPk4q1hTsqqXU2K+mDxit/fQ+Lyhf9F9795+tf/WoT/Z8yi+n+/xuoz+1p8Wk0Gs3i8QJSs3VlABAAAA==", // pragma: allowlist secret
"base64",
);

View File

@@ -115,7 +115,7 @@ describe("buildWorkspaceSkillsPrompt", () => {
managedSkillsDir,
config: {
browser: { enabled: false },
skills: { entries: { "env-skill": { apiKey: "ok" } } },
skills: { entries: { "env-skill": { apiKey: "ok" } } }, // pragma: allowlist secret
},
eligibility: {
remote: {

View File

@@ -178,7 +178,7 @@ describe("buildWorkspaceSkillsPrompt", () => {
const enabledPrompt = buildPrompt(workspaceDir, {
managedSkillsDir: path.join(workspaceDir, ".managed"),
config: {
skills: { entries: { "nano-banana-pro": { apiKey: "test-key" } } },
skills: { entries: { "nano-banana-pro": { apiKey: "test-key" } } }, // pragma: allowlist secret
},
});
expect(enabledPrompt).toContain("nano-banana-pro");

View File

@@ -23,6 +23,7 @@ const resolveTestSkillDirs = (workspaceDir: string) => ({
});
const makeWorkspace = async () => await fixtureSuite.createCaseDir("workspace");
const apiKeyField = ["api", "Key"].join("");
const withClearedEnv = <T>(
keys: string[],
@@ -252,7 +253,7 @@ describe("applySkillEnvOverrides", () => {
withClearedEnv(["ENV_KEY"], () => {
const restore = applySkillEnvOverrides({
skills: entries,
config: { skills: { entries: { "env-skill": { apiKey: "injected" } } } },
config: { skills: { entries: { "env-skill": { apiKey: "injected" } } } }, // pragma: allowlist secret
});
try {
@@ -279,7 +280,7 @@ describe("applySkillEnvOverrides", () => {
const entries = loadWorkspaceSkillEntries(workspaceDir, resolveTestSkillDirs(workspaceDir));
withClearedEnv(["ENV_KEY"], () => {
const config = { skills: { entries: { "env-skill": { apiKey: "injected" } } } };
const config = { skills: { entries: { "env-skill": { [apiKeyField]: "injected" } } } }; // pragma: allowlist secret
const restoreFirst = applySkillEnvOverrides({ skills: entries, config });
const restoreSecond = applySkillEnvOverrides({ skills: entries, config });
@@ -310,13 +311,13 @@ describe("applySkillEnvOverrides", () => {
const snapshot = buildWorkspaceSkillSnapshot(workspaceDir, {
...resolveTestSkillDirs(workspaceDir),
config: { skills: { entries: { "env-skill": { apiKey: "snap-key" } } } },
config: { skills: { entries: { "env-skill": { apiKey: "snap-key" } } } }, // pragma: allowlist secret
});
withClearedEnv(["ENV_KEY"], () => {
const restore = applySkillEnvOverridesFromSnapshot({
snapshot,
config: { skills: { entries: { "env-skill": { apiKey: "snap-key" } } } },
config: { skills: { entries: { "env-skill": { apiKey: "snap-key" } } } }, // pragma: allowlist secret
});
try {
@@ -349,7 +350,7 @@ describe("applySkillEnvOverrides", () => {
entries: {
"unsafe-env-skill": {
env: {
OPENAI_API_KEY: "sk-test",
OPENAI_API_KEY: "sk-test", // pragma: allowlist secret
NODE_OPTIONS: "--require /tmp/evil.js",
},
},
@@ -424,7 +425,7 @@ describe("applySkillEnvOverrides", () => {
entries: {
"snapshot-env-skill": {
env: {
OPENAI_API_KEY: "snap-secret",
OPENAI_API_KEY: "snap-secret", // pragma: allowlist secret
},
},
},

View File

@@ -73,14 +73,14 @@ describe("buildAgentSystemPrompt", () => {
workspaceDir: "/tmp/openclaw",
ownerNumbers: ["+123"],
ownerDisplay: "hash",
ownerDisplaySecret: "secret-key-A",
ownerDisplaySecret: "secret-key-A", // pragma: allowlist secret
});
const secretB = buildAgentSystemPrompt({
workspaceDir: "/tmp/openclaw",
ownerNumbers: ["+123"],
ownerDisplay: "hash",
ownerDisplaySecret: "secret-key-B",
ownerDisplaySecret: "secret-key-B", // pragma: allowlist secret
});
const lineA = secretA.split("## Authorized Senders")[1]?.split("\n")[1];

View File

@@ -71,7 +71,7 @@ function makeAnthropicAnalyzeParams(
}> = {},
) {
return {
apiKey: "test-key",
apiKey: "test-key", // pragma: allowlist secret
modelId: "claude-opus-4-6",
prompt: "test",
pdfs: [TEST_PDF_INPUT],
@@ -89,7 +89,7 @@ function makeGeminiAnalyzeParams(
}> = {},
) {
return {
apiKey: "test-key",
apiKey: "test-key", // pragma: allowlist secret
modelId: "gemini-2.5-pro",
prompt: "test",
pdfs: [TEST_PDF_INPUT],
@@ -156,7 +156,7 @@ async function stubPdfToolInfra(
});
const modelAuth = await import("../model-auth.js");
vi.spyOn(modelAuth, "getApiKeyForModel").mockResolvedValue({ apiKey: "test-key" } as never);
vi.spyOn(modelAuth, "getApiKeyForModel").mockResolvedValue({ apiKey: "test-key" } as never); // pragma: allowlist secret
vi.spyOn(modelAuth, "requireApiKey").mockReturnValue("test-key");
return { loadSpy };

View File

@@ -81,7 +81,7 @@ describe("web_fetch SSRF protection", () => {
it("blocks localhost hostnames before fetch/firecrawl", async () => {
const fetchSpy = setMockFetch();
const tool = await createWebFetchToolForTest({
firecrawl: { apiKey: "firecrawl-test" },
firecrawl: { apiKey: "firecrawl-test" }, // pragma: allowlist secret
});
await expectBlockedUrl(tool, "http://localhost/test", /Blocked hostname/i);
@@ -123,7 +123,7 @@ describe("web_fetch SSRF protection", () => {
redirectResponse("http://127.0.0.1/secret"),
);
const tool = await createWebFetchToolForTest({
firecrawl: { apiKey: "firecrawl-test" },
firecrawl: { apiKey: "firecrawl-test" }, // pragma: allowlist secret
});
await expectBlockedUrl(tool, "https://example.com", /private|internal|blocked/i);

View File

@@ -17,6 +17,9 @@ const {
extractKimiCitations,
} = __testing;
const kimiApiKeyEnv = ["KIMI_API", "KEY"].join("_");
const moonshotApiKeyEnv = ["MOONSHOT_API", "KEY"].join("_");
describe("web_search brave language param normalization", () => {
it("normalizes and auto-corrects swapped Brave language params", () => {
expect(normalizeBraveLanguageParams({ search_lang: "tr-TR", ui_lang: "tr" })).toEqual({
@@ -102,7 +105,7 @@ describe("web_search date normalization", () => {
describe("web_search grok config resolution", () => {
it("uses config apiKey when provided", () => {
expect(resolveGrokApiKey({ apiKey: "xai-test-key" })).toBe("xai-test-key");
expect(resolveGrokApiKey({ apiKey: "xai-test-key" })).toBe("xai-test-key"); // pragma: allowlist secret
});
it("returns undefined when no apiKey is available", () => {
@@ -221,15 +224,17 @@ describe("web_search grok response parsing", () => {
describe("web_search kimi config resolution", () => {
it("uses config apiKey when provided", () => {
expect(resolveKimiApiKey({ apiKey: "kimi-test-key" })).toBe("kimi-test-key");
expect(resolveKimiApiKey({ apiKey: "kimi-test-key" })).toBe("kimi-test-key"); // pragma: allowlist secret
});
it("falls back to KIMI_API_KEY, then MOONSHOT_API_KEY", () => {
withEnv({ KIMI_API_KEY: "kimi-env", MOONSHOT_API_KEY: "moonshot-env" }, () => {
expect(resolveKimiApiKey({})).toBe("kimi-env");
const kimiEnvValue = "kimi-env"; // pragma: allowlist secret
const moonshotEnvValue = "moonshot-env"; // pragma: allowlist secret
withEnv({ [kimiApiKeyEnv]: kimiEnvValue, [moonshotApiKeyEnv]: moonshotEnvValue }, () => {
expect(resolveKimiApiKey({})).toBe(kimiEnvValue);
});
withEnv({ KIMI_API_KEY: undefined, MOONSHOT_API_KEY: "moonshot-env" }, () => {
expect(resolveKimiApiKey({})).toBe("moonshot-env");
withEnv({ [kimiApiKeyEnv]: undefined, [moonshotApiKeyEnv]: moonshotEnvValue }, () => {
expect(resolveKimiApiKey({})).toBe(moonshotEnvValue);
});
});

View File

@@ -50,14 +50,14 @@ function createKimiSearchTool(kimiConfig?: { apiKey?: string; baseUrl?: string;
function createProviderSearchTool(provider: "brave" | "perplexity" | "grok" | "gemini" | "kimi") {
const searchConfig =
provider === "perplexity"
? { provider, perplexity: { apiKey: "pplx-config-test" } }
? { provider, perplexity: { apiKey: "pplx-config-test" } } // pragma: allowlist secret
: provider === "grok"
? { provider, grok: { apiKey: "xai-config-test" } }
? { provider, grok: { apiKey: "xai-config-test" } } // pragma: allowlist secret
: provider === "gemini"
? { provider, gemini: { apiKey: "gemini-config-test" } }
? { provider, gemini: { apiKey: "gemini-config-test" } } // pragma: allowlist secret
: provider === "kimi"
? { provider, kimi: { apiKey: "moonshot-config-test" } }
: { provider, apiKey: "brave-config-test" };
? { provider, kimi: { apiKey: "moonshot-config-test" } } // pragma: allowlist secret
: { provider, apiKey: "brave-config-test" }; // pragma: allowlist secret
return createWebSearchTool({
config: {
tools: {
@@ -458,7 +458,7 @@ describe("web_search kimi provider", () => {
global.fetch = withFetchPreconnect(mockFetch);
const tool = createKimiSearchTool({
apiKey: "kimi-config-key",
apiKey: "kimi-config-key", // pragma: allowlist secret
baseUrl: "https://api.moonshot.ai/v1",
model: "moonshot-v1-128k",
});

View File

@@ -29,6 +29,8 @@ function htmlResponse(html: string, url = "https://example.com/"): MockResponse
};
}
const apiKeyField = ["api", "Key"].join("");
function firecrawlResponse(markdown: string, url = "https://example.com/"): MockResponse {
return {
ok: true,
@@ -130,8 +132,12 @@ function installPlainTextFetch(text: string) {
);
}
function createFirecrawlTool(apiKey = "firecrawl-test") {
return createFetchTool({ firecrawl: { apiKey } });
function createFirecrawlTool(apiKey = defaultFirecrawlApiKey()) {
return createFetchTool({ firecrawl: { [apiKeyField]: apiKey } });
}
function defaultFirecrawlApiKey() {
return "firecrawl-test"; // pragma: allowlist secret
}
async function executeFetch(
@@ -385,7 +391,7 @@ describe("web_fetch extraction fallbacks", () => {
});
const tool = createFetchTool({
firecrawl: { apiKey: "firecrawl-test" },
firecrawl: { apiKey: "firecrawl-test" }, // pragma: allowlist secret
});
const result = await tool?.execute?.("call", { url: "https://example.com/blocked" });
@@ -477,7 +483,7 @@ describe("web_fetch extraction fallbacks", () => {
});
const tool = createFetchTool({
firecrawl: { apiKey: "firecrawl-test" },
firecrawl: { apiKey: "firecrawl-test" }, // pragma: allowlist secret
});
const message = await captureToolErrorMessage({