From 318e91ce3acbec3b0bfc91022a75a0d5bda0651d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Jul 2026 23:34:25 +0000 Subject: [PATCH 1/2] Initial plan From 369c6925dbf6e723011f3c0909952d4cc7fe7aa1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Jul 2026 23:43:07 +0000 Subject: [PATCH 2/2] refactor(api-proxy): dedupe provider auth headers --- containers/api-proxy/providers/anthropic.js | 26 ++++++++++----------- containers/api-proxy/providers/gemini.js | 7 +++--- containers/api-proxy/providers/openai.js | 20 ++++++---------- 3 files changed, 23 insertions(+), 30 deletions(-) diff --git a/containers/api-proxy/providers/anthropic.js b/containers/api-proxy/providers/anthropic.js index 221c1be8f..d289b56e1 100644 --- a/containers/api-proxy/providers/anthropic.js +++ b/containers/api-proxy/providers/anthropic.js @@ -116,6 +116,14 @@ function createAnthropicAdapter(env, deps = {}) { // Build the composed transform once at construction time to avoid // re-allocating the wrapper function on every request. const composedBodyTransform = composeBodyTransforms(depsBodyTransform, optimisationsTransform); + const buildOidcBearerAuthHeaders = (token) => ({ 'Authorization': 'Bearer ' + token }); + const buildStaticAuthHeaders = () => ({ [authHeaderName]: apiKey }); + const resolveAuthHeadersForValidationAndModels = () => resolveAuthHeadersWithFallback({ + oidcProvider, + awsOidcProvider: null, + buildOidcHeaders: buildOidcBearerAuthHeaders, + staticHeaders: buildStaticAuthHeaders(), + }); const adapterMethods = createAdapterMethods({ apiKey, rawTarget, @@ -127,12 +135,7 @@ function createAnthropicAdapter(env, deps = {}) { validationMethod: 'POST', validationBody: '{}', validationHeaders: () => ({ - ...resolveAuthHeadersWithFallback({ - oidcProvider, - awsOidcProvider: null, - buildOidcHeaders: (token) => ({ 'Authorization': `Bearer ${token}` }), - staticHeaders: { [authHeaderName]: apiKey }, - }), + ...resolveAuthHeadersForValidationAndModels(), 'anthropic-version': '2023-06-01', 'content-type': 'application/json', }), @@ -145,12 +148,7 @@ function createAnthropicAdapter(env, deps = {}) { skipModelsFetch: () => oidcConfigured && !oidcProvider?.isReady(), modelsPath: '/v1/models', modelsFetchHeaders: () => ({ - ...resolveAuthHeadersWithFallback({ - oidcProvider, - awsOidcProvider: null, - buildOidcHeaders: (token) => ({ 'Authorization': `Bearer ${token}` }), - staticHeaders: { [authHeaderName]: apiKey }, - }), + ...resolveAuthHeadersForValidationAndModels(), 'anthropic-version': '2023-06-01', }), reflectionConfigured: !!apiKey || oidcRequested, @@ -176,7 +174,7 @@ function createAnthropicAdapter(env, deps = {}) { const oidcHeaders = resolveOidcAuthHeaders({ oidcProvider, awsOidcProvider: null, - buildOidcHeaders: (token) => ({ 'Authorization': 'Bearer ' + token }), + buildOidcHeaders: buildOidcBearerAuthHeaders, }); // oidcHeaders === null → OIDC not configured; fall through to static key. @@ -187,7 +185,7 @@ function createAnthropicAdapter(env, deps = {}) { return {}; } - const headers = oidcHeaders !== null ? { ...oidcHeaders } : { [authHeaderName]: apiKey }; + const headers = oidcHeaders !== null ? { ...oidcHeaders } : buildStaticAuthHeaders(); if (!req.headers['anthropic-version']) { headers['anthropic-version'] = '2023-06-01'; diff --git a/containers/api-proxy/providers/gemini.js b/containers/api-proxy/providers/gemini.js index a5fbc409c..6a49bec4c 100644 --- a/containers/api-proxy/providers/gemini.js +++ b/containers/api-proxy/providers/gemini.js @@ -31,6 +31,7 @@ function createGeminiAdapter(env, deps = {}) { basePathEnvVar: GEMINI_ENV.BASE_PATH, defaultTarget: 'generativelanguage.googleapis.com', }); + const buildAuthHeaders = () => ({ 'x-goog-api-key': apiKey }); const adapterMethods = createAdapterMethods({ apiKey, @@ -40,9 +41,9 @@ function createGeminiAdapter(env, deps = {}) { port: 10003, defaultTarget: 'generativelanguage.googleapis.com', validationPath: '/v1beta/models', - validationHeaders: () => ({ 'x-goog-api-key': apiKey }), + validationHeaders: buildAuthHeaders, modelsPath: '/v1beta/models', - modelsFetchHeaders: () => ({ 'x-goog-api-key': apiKey }), + modelsFetchHeaders: buildAuthHeaders, }); return buildProviderAdapter({ @@ -51,7 +52,7 @@ function createGeminiAdapter(env, deps = {}) { isManagementPort: false, adapterMethods, getAuthHeaders() { - return { 'x-goog-api-key': apiKey }; + return buildAuthHeaders(); }, bodyTransform, isEnabled() { return !!apiKey; }, diff --git a/containers/api-proxy/providers/openai.js b/containers/api-proxy/providers/openai.js index 08e49cccb..94f0da559 100644 --- a/containers/api-proxy/providers/openai.js +++ b/containers/api-proxy/providers/openai.js @@ -70,17 +70,13 @@ function createOpenAIAdapter(env, deps = {}) { skipModelsFetch, resolveAuthHeaders, } = createProviderOidcAuth(env, { staticAuthToken: apiKey }); - /** - * Build a static-key auth header object. - * When AWF_OPENAI_AUTH_HEADER is set, uses that header name with the raw key. - * Otherwise uses the standard `Authorization: Bearer ` format. - */ - function buildStaticAuthHeaders(key) { + function buildTokenAuthHeaders(key) { if (customAuthHeader) { return { [customAuthHeader]: key }; } - return { 'Authorization': `Bearer ${key}` }; + return { 'Authorization': 'Bearer ' + key }; } + const buildStaticAuthHeaders = () => buildTokenAuthHeaders(apiKey); const adapterMethods = createAdapterMethods({ apiKey, @@ -90,11 +86,11 @@ function createOpenAIAdapter(env, deps = {}) { port: 10000, defaultTarget: 'api.openai.com', validationPath: '/v1/models', - validationHeaders: () => buildStaticAuthHeaders(apiKey), + validationHeaders: buildStaticAuthHeaders, validationSkip, skipModelsFetch, modelsPath: '/v1/models', - modelsFetchHeaders: () => buildStaticAuthHeaders(apiKey), + modelsFetchHeaders: buildStaticAuthHeaders, reflectionConfigured: !!apiKey || oidcConfigured, reflectionModelsPath: '/v1/models', reflectionExtra: () => ({ @@ -109,10 +105,8 @@ function createOpenAIAdapter(env, deps = {}) { adapterMethods, getAuthHeaders() { return resolveAuthHeaders( - (token) => (customAuthHeader - ? { [customAuthHeader]: token } - : { 'Authorization': ['Bearer', token].join(' ') }), - buildStaticAuthHeaders(apiKey), + buildTokenAuthHeaders, + buildStaticAuthHeaders(), ); }, bodyTransform,