feat(media): add request transport overrides (#59848)

* style(providers): normalize request policy formatting

* style(providers): normalize request policy formatting

* feat(media): add request transport overrides

* fix(secrets): resolve media request secret refs

* fix(secrets): cover shared media request refs

* fix(secrets): scope media request ref activity

* fix(media): align request ref gating
This commit is contained in:
Vincent Koc
2026-04-03 17:35:26 +09:00
committed by GitHub
parent 9e47c1a2c5
commit 23719dd513
19 changed files with 9359 additions and 24 deletions

View File

@@ -1,9 +1,11 @@
import { describe, expect, it } from "vitest";
import {
buildProviderRequestDispatcherPolicy,
mergeProviderRequestOverrides,
resolveProviderRequestPolicyConfig,
resolveProviderRequestConfig,
resolveProviderRequestHeaders,
sanitizeConfiguredProviderRequest,
sanitizeRuntimeProviderRequestOverrides,
} from "./provider-request-config.js";
@@ -244,6 +246,108 @@ describe("provider request config", () => {
).toThrow(/runtime auth request overrides do not allow proxy or tls/i);
});
it("sanitizes configured request overrides into runtime transport overrides", () => {
expect(
sanitizeConfiguredProviderRequest({
headers: {
"X-Tenant": "acme",
},
auth: {
mode: "authorization-bearer",
token: "secret",
},
proxy: {
mode: "explicit-proxy",
url: "http://proxy.internal:8443",
tls: {
ca: "proxy-ca",
},
},
tls: {
cert: "client-cert",
key: "client-key",
serverName: "gateway.internal",
},
}),
).toEqual({
headers: {
"X-Tenant": "acme",
},
auth: {
mode: "authorization-bearer",
token: "secret",
},
proxy: {
mode: "explicit-proxy",
url: "http://proxy.internal:8443",
tls: {
ca: "proxy-ca",
},
},
tls: {
cert: "client-cert",
key: "client-key",
serverName: "gateway.internal",
},
});
});
it("fails fast when configured request overrides still contain unresolved SecretRefs", () => {
expect(() =>
sanitizeConfiguredProviderRequest({
headers: {
"X-Tenant": { source: "env", provider: "default", id: "MEDIA_AUDIO_TENANT" },
},
auth: {
mode: "authorization-bearer",
token: { source: "env", provider: "default", id: "MEDIA_AUDIO_TOKEN" },
},
tls: {
cert: { source: "env", provider: "default", id: "MEDIA_AUDIO_CERT" },
},
}),
).toThrow(/request\.(headers\.X-Tenant|auth\.token|tls\.cert): unresolved SecretRef/i);
});
it("merges configured request overrides with later entries winning", () => {
expect(
mergeProviderRequestOverrides(
{
headers: {
"X-Provider": "1",
"X-Shared": "provider",
},
auth: {
mode: "authorization-bearer",
token: "provider-token",
},
},
{
headers: {
"X-Entry": "2",
"X-Shared": "entry",
},
auth: {
mode: "header",
headerName: "api-key",
value: "entry-key",
},
},
),
).toEqual({
headers: {
"X-Provider": "1",
"X-Shared": "entry",
"X-Entry": "2",
},
auth: {
mode: "header",
headerName: "api-key",
value: "entry-key",
},
});
});
it("lets defaults override caller headers when requested", () => {
const resolved = resolveProviderRequestHeaders({
provider: "openai",

View File

@@ -1,5 +1,7 @@
import type { Api } from "@mariozechner/pi-ai";
import type { ModelDefinitionConfig } from "../config/types.js";
import type { ConfiguredProviderRequest } from "../config/types.provider-request.js";
import { assertSecretInputResolved } from "../config/types.secrets.js";
import type { PinnedDispatcherPolicy } from "../infra/net/ssrf.js";
import type {
ProviderRequestCapabilities,
@@ -158,6 +160,169 @@ type ResolveProviderRequestPolicyConfigParams = {
request?: ProviderRequestTransportOverrides;
};
function sanitizeConfiguredRequestString(value: unknown, path: string): string | undefined {
if (typeof value !== "string") {
// Config transport overrides are sanitized after secrets runtime resolution.
// Fail closed if a raw SecretRef leaks into this path instead of silently dropping it.
assertSecretInputResolved({ value, path });
return undefined;
}
const trimmed = value.trim();
return trimmed ? trimmed : undefined;
}
export function sanitizeConfiguredProviderRequest(
request: ConfiguredProviderRequest | ProviderRequestTransportOverrides | undefined,
): ProviderRequestTransportOverrides | undefined {
if (!request || typeof request !== "object" || Array.isArray(request)) {
return undefined;
}
let headers: Record<string, string> | undefined;
if (request.headers && typeof request.headers === "object" && !Array.isArray(request.headers)) {
const nextHeaders: Record<string, string> = {};
for (const [key, value] of Object.entries(request.headers)) {
const sanitized = sanitizeConfiguredRequestString(value, `request.headers.${key}`);
if (sanitized) {
nextHeaders[key] = sanitized;
}
}
if (Object.keys(nextHeaders).length > 0) {
headers = nextHeaders;
}
}
let auth: ProviderRequestAuthOverride | undefined;
const rawAuth = request.auth;
if (rawAuth && typeof rawAuth === "object" && !Array.isArray(rawAuth)) {
if (rawAuth.mode === "provider-default") {
auth = { mode: "provider-default" };
} else if (rawAuth.mode === "authorization-bearer") {
const token = sanitizeConfiguredRequestString(rawAuth.token, "request.auth.token");
if (token) {
auth = { mode: "authorization-bearer", token };
}
} else if (rawAuth.mode === "header") {
const headerName = sanitizeConfiguredRequestString(
rawAuth.headerName,
"request.auth.headerName",
);
const value = sanitizeConfiguredRequestString(rawAuth.value, "request.auth.value");
const prefix = sanitizeConfiguredRequestString(rawAuth.prefix, "request.auth.prefix");
if (headerName && value) {
auth = {
mode: "header",
headerName,
value,
...(prefix ? { prefix } : {}),
};
}
}
}
const sanitizeTls = (
tls: unknown,
pathPrefix: "request.tls" | "request.proxy.tls",
): ProviderRequestTlsOverride | undefined => {
if (!tls || typeof tls !== "object" || Array.isArray(tls)) {
return undefined;
}
const rawTls = tls as Record<string, unknown>;
const next: ProviderRequestTlsOverride = {};
const ca = sanitizeConfiguredRequestString(rawTls.ca, `${pathPrefix}.ca`);
const cert = sanitizeConfiguredRequestString(rawTls.cert, `${pathPrefix}.cert`);
const key = sanitizeConfiguredRequestString(rawTls.key, `${pathPrefix}.key`);
const passphrase = sanitizeConfiguredRequestString(
rawTls.passphrase,
`${pathPrefix}.passphrase`,
);
const serverName = sanitizeConfiguredRequestString(
rawTls.serverName,
`${pathPrefix}.serverName`,
);
if (ca) {
next.ca = ca;
}
if (cert) {
next.cert = cert;
}
if (key) {
next.key = key;
}
if (passphrase) {
next.passphrase = passphrase;
}
if (serverName) {
next.serverName = serverName;
}
if (rawTls.insecureSkipVerify === true) {
next.insecureSkipVerify = true;
} else if (rawTls.insecureSkipVerify === false) {
next.insecureSkipVerify = false;
}
return Object.keys(next).length > 0 ? next : undefined;
};
let proxy: ProviderRequestProxyOverride | undefined;
const rawProxy = request.proxy;
if (rawProxy && typeof rawProxy === "object" && !Array.isArray(rawProxy)) {
const tls = sanitizeTls(rawProxy.tls, "request.proxy.tls");
if (rawProxy.mode === "env-proxy") {
proxy = {
mode: "env-proxy",
...(tls ? { tls } : {}),
};
} else if (rawProxy.mode === "explicit-proxy") {
const url = sanitizeConfiguredRequestString(rawProxy.url, "request.proxy.url");
if (url) {
proxy = {
mode: "explicit-proxy",
url,
...(tls ? { tls } : {}),
};
}
}
}
const tls = sanitizeTls(request.tls, "request.tls");
if (!headers && !auth && !proxy && !tls) {
return undefined;
}
return {
...(headers ? { headers } : {}),
...(auth ? { auth } : {}),
...(proxy ? { proxy } : {}),
...(tls ? { tls } : {}),
};
}
export function mergeProviderRequestOverrides(
...overrides: Array<ProviderRequestTransportOverrides | undefined>
): ProviderRequestTransportOverrides | undefined {
let merged: ProviderRequestTransportOverrides | undefined;
for (const current of overrides) {
if (!current) {
continue;
}
merged = {
...merged,
...(current.headers
? {
headers: {
...merged?.headers,
...current.headers,
},
}
: {}),
...(current.auth ? { auth: current.auth } : {}),
...(current.proxy ? { proxy: current.proxy } : {}),
...(current.tls ? { tls: current.tls } : {}),
};
}
return merged;
}
export function normalizeBaseUrl(baseUrl: string | undefined, fallback: string): string;
export function normalizeBaseUrl(
baseUrl: string | undefined,