fix: respect web search SecretRef credentials

This commit is contained in:
Peter Steinberger
2026-04-18 18:57:42 +01:00
parent 438799e929
commit 7474b52584
3 changed files with 88 additions and 6 deletions

View File

@@ -78,8 +78,8 @@ describe("xai web search config resolution", () => {
expect(resolveXaiWebSearchModel(searchConfig)).toBe("grok-4-fast");
});
it("treats unresolved non-env SecretRefs as missing credentials instead of throwing", async () => {
await withEnvAsync({ XAI_API_KEY: undefined }, async () => {
it("treats unresolved non-env SecretRefs as missing credentials instead of using env fallback", async () => {
await withEnvAsync({ XAI_API_KEY: "ambient-xai-test-key" }, async () => {
const provider = createXaiWebSearchProvider();
const maybeTool = provider.createTool({
config: {

View File

@@ -0,0 +1,80 @@
import { describe, expect, it } from "vitest";
import { withEnv } from "../../test-utils/env.js";
import { resolveWebSearchProviderCredential } from "./web-search-provider-credentials.js";
describe("resolveWebSearchProviderCredential", () => {
it("uses configured literal credentials before ambient env fallback", () => {
withEnv({ TEST_WEB_SEARCH_KEY: "ambient-test-value" }, () => {
expect(
resolveWebSearchProviderCredential({
credentialValue: "configured-test-value",
path: "tools.web.search.provider.apiKey",
envVars: ["TEST_WEB_SEARCH_KEY"],
}),
).toBe("configured-test-value");
});
});
it("resolves configured env SecretRefs", () => {
withEnv({ TEST_WEB_SEARCH_REF_KEY: "ref-test-value" }, () => {
expect(
resolveWebSearchProviderCredential({
credentialValue: {
source: "env",
provider: "default",
id: "TEST_WEB_SEARCH_REF_KEY",
},
path: "tools.web.search.provider.apiKey",
envVars: ["TEST_WEB_SEARCH_KEY"],
}),
).toBe("ref-test-value");
});
});
it("does not override missing env SecretRefs with ambient env fallback", () => {
withEnv(
{ TEST_WEB_SEARCH_REF_KEY: undefined, TEST_WEB_SEARCH_KEY: "ambient-test-value" },
() => {
expect(
resolveWebSearchProviderCredential({
credentialValue: {
source: "env",
provider: "default",
id: "TEST_WEB_SEARCH_REF_KEY",
},
path: "tools.web.search.provider.apiKey",
envVars: ["TEST_WEB_SEARCH_KEY"],
}),
).toBeUndefined();
},
);
});
it("does not override non-env SecretRefs with ambient env fallback", () => {
withEnv({ TEST_WEB_SEARCH_KEY: "ambient-test-value" }, () => {
expect(
resolveWebSearchProviderCredential({
credentialValue: {
source: "file",
provider: "vault",
id: "/providers/web-search/api-key",
},
path: "tools.web.search.provider.apiKey",
envVars: ["TEST_WEB_SEARCH_KEY"],
}),
).toBeUndefined();
});
});
it("falls back to ambient env when no credential is configured", () => {
withEnv({ TEST_WEB_SEARCH_KEY: "ambient-test-value" }, () => {
expect(
resolveWebSearchProviderCredential({
credentialValue: undefined,
path: "tools.web.search.provider.apiKey",
envVars: ["TEST_WEB_SEARCH_KEY"],
}),
).toBe("ambient-test-value");
});
});
});

View File

@@ -12,14 +12,16 @@ export function resolveWebSearchProviderCredential(params: {
return fromConfig;
}
const credentialRef = resolveSecretInputRef({
value: params.credentialValue,
}).ref;
if (credentialRef?.source === "env") {
const credentialRef = resolveSecretInputRef({ value: params.credentialValue }).ref;
if (credentialRef) {
if (credentialRef.source !== "env") {
return undefined;
}
const fromEnvRef = normalizeSecretInput(process.env[credentialRef.id]);
if (fromEnvRef) {
return fromEnvRef;
}
return undefined;
}
for (const envVar of params.envVars) {