fix(claude-cli): harden gateway auth env

This commit is contained in:
Peter Steinberger
2026-04-10 08:10:05 +01:00
parent 7e2a1db53b
commit 7e7a8d6b0f
7 changed files with 106 additions and 14 deletions

View File

@@ -13,7 +13,7 @@ import {
restoreCliRunnerPrepareTestDeps,
supervisorSpawnMock,
} from "./cli-runner.test-support.js";
import { executePreparedCliRun } from "./cli-runner/execute.js";
import { buildCliEnvAuthLog, executePreparedCliRun } from "./cli-runner/execute.js";
import { buildSystemPrompt } from "./cli-runner/helpers.js";
import { setCliRunnerPrepareTestDeps } from "./cli-runner/prepare.js";
import type { PreparedCliRunContext } from "./cli-runner/types.js";
@@ -560,6 +560,9 @@ describe("runCliAgent spawn path", () => {
it("clears claude-cli provider-routing, auth, and telemetry env while keeping host-managed hardening", async () => {
vi.stubEnv("ANTHROPIC_BASE_URL", "https://proxy.example.com/v1");
vi.stubEnv("ANTHROPIC_API_TOKEN", "env-api-token");
vi.stubEnv("ANTHROPIC_CUSTOM_HEADERS", "x-test-header: env");
vi.stubEnv("ANTHROPIC_OAUTH_TOKEN", "env-oauth-token");
vi.stubEnv("CLAUDE_CODE_USE_BEDROCK", "1");
vi.stubEnv("ANTHROPIC_AUTH_TOKEN", "env-auth-token");
vi.stubEnv("CLAUDE_CODE_OAUTH_TOKEN", "env-oauth-token");
@@ -586,6 +589,9 @@ describe("runCliAgent spawn path", () => {
},
clearEnv: [
"ANTHROPIC_BASE_URL",
"ANTHROPIC_API_TOKEN",
"ANTHROPIC_CUSTOM_HEADERS",
"ANTHROPIC_OAUTH_TOKEN",
"CLAUDE_CODE_USE_BEDROCK",
"ANTHROPIC_AUTH_TOKEN",
"CLAUDE_CODE_OAUTH_TOKEN",
@@ -607,6 +613,9 @@ describe("runCliAgent spawn path", () => {
expect(input.env?.SAFE_KEEP).toBe("ok");
expect(input.env?.CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST).toBe("1");
expect(input.env?.ANTHROPIC_BASE_URL).toBe("https://override.example.com/v1");
expect(input.env?.ANTHROPIC_API_TOKEN).toBeUndefined();
expect(input.env?.ANTHROPIC_CUSTOM_HEADERS).toBeUndefined();
expect(input.env?.ANTHROPIC_OAUTH_TOKEN).toBeUndefined();
expect(input.env?.CLAUDE_CODE_USE_BEDROCK).toBeUndefined();
expect(input.env?.ANTHROPIC_AUTH_TOKEN).toBeUndefined();
expect(input.env?.CLAUDE_CODE_OAUTH_TOKEN).toBe("override-oauth-token");
@@ -619,6 +628,29 @@ describe("runCliAgent spawn path", () => {
expect(input.env?.OTEL_SDK_DISABLED).toBeUndefined();
});
it("formats CLI auth env diagnostics as key names without secret values", () => {
vi.stubEnv("ANTHROPIC_API_KEY", "sk-ant-host");
vi.stubEnv("ANTHROPIC_API_TOKEN", "token-host");
vi.stubEnv("OPENAI_API_KEY", "sk-openai-host");
const log = buildCliEnvAuthLog({
ANTHROPIC_API_TOKEN: "token-child",
CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST: "1",
OPENAI_API_KEY: "sk-openai-child",
});
expect(log).toMatch(/host=.*ANTHROPIC_API_KEY/);
expect(log).toMatch(/host=.*ANTHROPIC_API_TOKEN/);
expect(log).toMatch(/host=.*OPENAI_API_KEY/);
expect(log).toMatch(/child=.*ANTHROPIC_API_TOKEN/);
expect(log).toMatch(/child=.*CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST/);
expect(log).toMatch(/child=.*OPENAI_API_KEY/);
expect(log).toMatch(/cleared=.*ANTHROPIC_API_KEY/);
expect(log).not.toContain("sk-ant-host");
expect(log).not.toContain("token-child");
expect(log).not.toContain("sk-openai-child");
});
it("prepends bootstrap warnings to the CLI prompt body", async () => {
supervisorSpawnMock.mockResolvedValueOnce(
createManagedRun({