fix: carry provider capability in dedicated header

This commit is contained in:
2026-07-11 15:02:51 +08:00
parent 63c86322de
commit 3087132083
5 changed files with 23 additions and 7 deletions
+17 -3
View File
@@ -20,6 +20,7 @@ const REPLACED_REQUEST_HEADERS = new Set([
"content-length",
"host",
"x-api-key",
"x-cph-run-capability",
]);
export interface ProviderUpstreamCredential {
@@ -44,6 +45,7 @@ export interface ProviderProxyDiagnostic {
readonly authShape?: {
readonly bearerLength: number;
readonly apiKeyLength: number;
readonly customCapabilityLength: number;
readonly expectedLength: number;
};
}
@@ -87,6 +89,7 @@ export async function openProviderProxyLease(
ANTHROPIC_BASE_URL: `http://127.0.0.1:${address.port}`,
ANTHROPIC_AUTH_TOKEN: capability,
ANTHROPIC_API_KEY: capability,
ANTHROPIC_CUSTOM_HEADERS: `X-CPH-Run-Capability: ${capability}`,
},
sensitiveValues: [capability],
async close(): Promise<void> {
@@ -107,7 +110,12 @@ async function forwardProviderRequest(
upstream: ProviderUpstreamCredential,
options: ProviderProxyOptions,
): Promise<void> {
if (!authorized(request.headers.authorization, header(request.headers["x-api-key"]), capability)) {
if (!authorized(
request.headers.authorization,
header(request.headers["x-api-key"]),
header(request.headers["x-cph-run-capability"]),
capability,
)) {
options.onDiagnostic?.({
code: "provider_proxy_unauthorized",
category: "authorization",
@@ -116,6 +124,7 @@ async function forwardProviderRequest(
? request.headers.authorization.length - "Bearer ".length
: 0,
apiKeyLength: header(request.headers["x-api-key"])?.length ?? 0,
customCapabilityLength: header(request.headers["x-cph-run-capability"])?.length ?? 0,
expectedLength: capability.length,
},
});
@@ -183,11 +192,16 @@ async function forwardProviderRequest(
function authorized(
authorization: string | undefined,
apiKey: string | undefined,
customCapability: string | undefined,
capability: string,
): boolean {
const value = authorization?.startsWith("Bearer ")
const bearer = authorization?.startsWith("Bearer ")
? authorization.slice("Bearer ".length)
: apiKey;
: undefined;
return [bearer, apiKey, customCapability].some((value) => matchesCapability(value, capability));
}
function matchesCapability(value: string | undefined, capability: string): boolean {
if (value === undefined) return false;
const supplied = Buffer.from(value);
const expected = Buffer.from(capability);