Skip to content

Commit b0b04bb

Browse files
CopilotlpcoxCopilot
authored
refactor: extract provider env var constants to a shared module (#5207)
* Initial plan * refactor: extract provider env var constants to a shared module * fix: use shared env constants in openai provider adapter * fix: add provider-env-constants.js to Dockerfile COPY The new shared module was missing from the Dockerfile's COPY instruction, causing 'Cannot find module ../provider-env-constants' at container startup. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Landon Cox <landon.cox@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 68b9d23 commit b0b04bb

9 files changed

Lines changed: 146 additions & 48 deletions

File tree

containers/api-proxy/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ COPY server.js logging.js metrics.js rate-limiter.js \
2727
ai-credits-pricing.js models-dev-catalog.js models.dev.catalog.json \
2828
oidc-refresh-utils.js body-transform.js body-utils.js rate-limit.js websocket-proxy.js \
2929
deprecated-header-tracker.js billing-headers.js upstream-response.js \
30-
anthropic-cache.js otel.js token-budget-log.js blocked-request-diagnostics.js ./
30+
anthropic-cache.js otel.js token-budget-log.js blocked-request-diagnostics.js \
31+
provider-env-constants.js ./
3132
COPY guards/ ./guards/
3233
COPY providers/ ./providers/
3334
COPY transforms/ ./transforms/
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
'use strict';
2+
3+
/**
4+
* Environment variable name constants for the API proxy provider adapters.
5+
*
6+
* This is the single source of truth for env var names on the container JS side.
7+
* The TypeScript equivalent lives in src/api-proxy-env-constants.ts.
8+
*
9+
* Both files must be kept in sync when adding or renaming env vars.
10+
*/
11+
12+
/** Environment variable names for the OpenAI provider adapter. */
13+
const OPENAI_ENV = /** @type {const} */ ({
14+
KEY: 'OPENAI_API_KEY',
15+
TARGET: 'OPENAI_API_TARGET',
16+
BASE_PATH: 'OPENAI_API_BASE_PATH',
17+
AUTH_HEADER: 'AWF_OPENAI_AUTH_HEADER',
18+
});
19+
20+
/** Environment variable names for the Anthropic provider adapter. */
21+
const ANTHROPIC_ENV = /** @type {const} */ ({
22+
KEY: 'ANTHROPIC_API_KEY',
23+
TARGET: 'ANTHROPIC_API_TARGET',
24+
BASE_PATH: 'ANTHROPIC_API_BASE_PATH',
25+
AUTH_HEADER: 'AWF_ANTHROPIC_AUTH_HEADER',
26+
});
27+
28+
/** Environment variable names for the Gemini provider adapter. */
29+
const GEMINI_ENV = /** @type {const} */ ({
30+
KEY: 'GEMINI_API_KEY',
31+
TARGET: 'GEMINI_API_TARGET',
32+
BASE_PATH: 'GEMINI_API_BASE_PATH',
33+
});
34+
35+
/** Environment variable names for the Copilot provider adapter. */
36+
const COPILOT_ENV = /** @type {const} */ ({
37+
GITHUB_TOKEN: 'COPILOT_GITHUB_TOKEN',
38+
PROVIDER_API_KEY: 'COPILOT_PROVIDER_API_KEY',
39+
PROVIDER_TYPE: 'COPILOT_PROVIDER_TYPE',
40+
PROVIDER_BASE_URL: 'COPILOT_PROVIDER_BASE_URL',
41+
API_TARGET: 'COPILOT_API_TARGET',
42+
API_BASE_PATH: 'COPILOT_API_BASE_PATH',
43+
});
44+
45+
module.exports = {
46+
OPENAI_ENV,
47+
ANTHROPIC_ENV,
48+
GEMINI_ENV,
49+
COPILOT_ENV,
50+
};

containers/api-proxy/providers/anthropic.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const {
2121
} = require('../proxy-utils');
2222
const { createBaseAdapterConfig, createAdapterMethods, buildProviderAdapter } = require('../adapter-factory');
2323
const { AnthropicOidcTokenProvider } = require('../anthropic-oidc-token-provider');
24+
const { ANTHROPIC_ENV } = require('../provider-env-constants');
2425
const { createProviderOidcAuth } = require('./cloud-oidc-init');
2526

2627
let makeAnthropicTransform, loadCustomTransform, EXTENDED_CACHE_BETA;
@@ -45,12 +46,12 @@ try {
4546
*/
4647
function createAnthropicAdapter(env, deps = {}) {
4748
const { apiKey, rawTarget, basePath } = createBaseAdapterConfig(env, {
48-
keyEnvVar: 'ANTHROPIC_API_KEY',
49-
targetEnvVar: 'ANTHROPIC_API_TARGET',
50-
basePathEnvVar: 'ANTHROPIC_API_BASE_PATH',
49+
keyEnvVar: ANTHROPIC_ENV.KEY,
50+
targetEnvVar: ANTHROPIC_ENV.TARGET,
51+
basePathEnvVar: ANTHROPIC_ENV.BASE_PATH,
5152
defaultTarget: 'api.anthropic.com',
5253
});
53-
const authHeaderName = validateAuthHeaderEnv('AWF_ANTHROPIC_AUTH_HEADER', env.AWF_ANTHROPIC_AUTH_HEADER, 'x-api-key');
54+
const authHeaderName = validateAuthHeaderEnv(ANTHROPIC_ENV.AUTH_HEADER, env[ANTHROPIC_ENV.AUTH_HEADER], 'x-api-key');
5455

5556
// oidcRequested tracks whether the caller asked for Anthropic OIDC, regardless
5657
// of whether the token env vars (ACTIONS_ID_TOKEN_REQUEST_*) are also present.

containers/api-proxy/providers/copilot.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const {
4040
} = require('./copilot-auth');
4141
const { createProviderOidcAuth } = require('./cloud-oidc-init');
4242
const { URL } = require('url');
43+
const { COPILOT_ENV } = require('../provider-env-constants');
4344

4445
/**
4546
* Create the GitHub Copilot provider adapter.
@@ -49,13 +50,13 @@ const { URL } = require('url');
4950
* @returns {import('./index').ProviderAdapter}
5051
*/
5152
function createCopilotAdapter(env, deps = {}) {
52-
const githubToken = stripBearerPrefix(env.COPILOT_GITHUB_TOKEN);
53+
const githubToken = stripBearerPrefix(env[COPILOT_ENV.GITHUB_TOKEN]);
5354
// resolveApiKey filters out the AWF placeholder so it is never used as a real BYOK credential.
5455
const apiKey = resolveApiKey(env);
5556
const staticAuthToken = resolveCopilotAuthToken(env);
5657
const integrationId = env.COPILOT_INTEGRATION_ID || 'agentic-workflows';
5758
const rawTarget = deriveCopilotApiTarget(env);
58-
const basePath = normalizeBasePath(env.COPILOT_API_BASE_PATH);
59+
const basePath = normalizeBasePath(env[COPILOT_ENV.API_BASE_PATH]);
5960

6061
// OIDC auth strategy (Azure OpenAI via Entra, AWS Bedrock, GCP Vertex AI) for
6162
// BYOK targets pointed at by COPILOT_PROVIDER_BASE_URL. Mirrors the OpenAI

containers/api-proxy/providers/gemini.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
const { stripGeminiKeyParam, makeUnconfiguredHealthResponse } = require('../proxy-utils');
1717
const { createBaseAdapterConfig, createAdapterMethods, buildProviderAdapter } = require('../adapter-factory');
18+
const { GEMINI_ENV } = require('../provider-env-constants');
1819

1920
/**
2021
* Create the Google Gemini provider adapter.
@@ -25,9 +26,9 @@ const { createBaseAdapterConfig, createAdapterMethods, buildProviderAdapter } =
2526
*/
2627
function createGeminiAdapter(env, deps = {}) {
2728
const { apiKey, rawTarget, basePath } = createBaseAdapterConfig(env, {
28-
keyEnvVar: 'GEMINI_API_KEY',
29-
targetEnvVar: 'GEMINI_API_TARGET',
30-
basePathEnvVar: 'GEMINI_API_BASE_PATH',
29+
keyEnvVar: GEMINI_ENV.KEY,
30+
targetEnvVar: GEMINI_ENV.TARGET,
31+
basePathEnvVar: GEMINI_ENV.BASE_PATH,
3132
defaultTarget: 'generativelanguage.googleapis.com',
3233
});
3334

containers/api-proxy/providers/openai.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const {
1818

1919
const { createBaseAdapterConfig, createAdapterMethods, buildProviderAdapter } = require('../adapter-factory');
2020
const { createProviderOidcAuth } = require('./cloud-oidc-init');
21+
const { OPENAI_ENV, COPILOT_ENV } = require('../provider-env-constants');
2122

2223
/**
2324
* Create the OpenAI provider adapter.
@@ -28,26 +29,26 @@ const { createProviderOidcAuth } = require('./cloud-oidc-init');
2829
*/
2930
function createOpenAIAdapter(env, deps = {}) {
3031
const { apiKey: openaiApiKey, rawTarget: openaiTarget, basePath: openaiBasePath } = createBaseAdapterConfig(env, {
31-
keyEnvVar: 'OPENAI_API_KEY',
32-
targetEnvVar: 'OPENAI_API_TARGET',
33-
basePathEnvVar: 'OPENAI_API_BASE_PATH',
32+
keyEnvVar: OPENAI_ENV.KEY,
33+
targetEnvVar: OPENAI_ENV.TARGET,
34+
basePathEnvVar: OPENAI_ENV.BASE_PATH,
3435
defaultTarget: 'api.openai.com',
3536
});
36-
const providerType = (env.COPILOT_PROVIDER_TYPE || '').trim().toLowerCase();
37+
const providerType = (env[COPILOT_ENV.PROVIDER_TYPE] || '').trim().toLowerCase();
3738
const copilotAzureByokEnabled = providerType === 'azure';
3839
const customAuthHeader = (() => {
39-
const header = validateAuthHeaderEnv('AWF_OPENAI_AUTH_HEADER', env.AWF_OPENAI_AUTH_HEADER);
40+
const header = validateAuthHeaderEnv(OPENAI_ENV.AUTH_HEADER, env[OPENAI_ENV.AUTH_HEADER]);
4041
if (header) return header;
4142
// Azure OpenAI BYOK uses `api-key` header instead of `Authorization: Bearer`
4243
// (but OIDC auth still requires `Authorization: Bearer` unless explicitly overridden)
4344
if (copilotAzureByokEnabled && (env.AWF_AUTH_TYPE || '').trim().toLowerCase() !== 'github-oidc') return 'api-key';
4445
return '';
4546
})();
46-
const copilotByokApiKey = (env.COPILOT_PROVIDER_API_KEY || '').trim() || undefined;
47-
const { target: copilotByokTarget, basePath: copilotByokBasePath } = parseApiTargetAndBasePath(env.COPILOT_PROVIDER_BASE_URL);
47+
const copilotByokApiKey = (env[COPILOT_ENV.PROVIDER_API_KEY] || '').trim() || undefined;
48+
const { target: copilotByokTarget, basePath: copilotByokBasePath } = parseApiTargetAndBasePath(env[COPILOT_ENV.PROVIDER_BASE_URL]);
4849

4950
const apiKey = openaiApiKey || (copilotAzureByokEnabled ? copilotByokApiKey : undefined);
50-
const explicitOpenAITarget = env.OPENAI_API_TARGET ? openaiTarget : undefined;
51+
const explicitOpenAITarget = env[OPENAI_ENV.TARGET] ? openaiTarget : undefined;
5152
const rawTarget = explicitOpenAITarget || (copilotAzureByokEnabled ? copilotByokTarget : undefined) || 'api.openai.com';
5253
const explicitBasePath = openaiBasePath || (copilotAzureByokEnabled ? copilotByokBasePath : '');
5354

src/api-proxy-env-constants.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* Environment variable name constants for the API proxy provider adapters.
3+
*
4+
* This is the single source of truth for env var names on the TypeScript host side.
5+
* The CommonJS equivalent lives in containers/api-proxy/provider-env-constants.js.
6+
*
7+
* Both files must be kept in sync when adding or renaming env vars.
8+
*/
9+
10+
/** Environment variable names for the OpenAI provider adapter. */
11+
export const OPENAI_ENV = {
12+
KEY: 'OPENAI_API_KEY',
13+
TARGET: 'OPENAI_API_TARGET',
14+
BASE_PATH: 'OPENAI_API_BASE_PATH',
15+
AUTH_HEADER: 'AWF_OPENAI_AUTH_HEADER',
16+
} as const;
17+
18+
/** Environment variable names for the Anthropic provider adapter. */
19+
export const ANTHROPIC_ENV = {
20+
KEY: 'ANTHROPIC_API_KEY',
21+
TARGET: 'ANTHROPIC_API_TARGET',
22+
BASE_PATH: 'ANTHROPIC_API_BASE_PATH',
23+
AUTH_HEADER: 'AWF_ANTHROPIC_AUTH_HEADER',
24+
} as const;
25+
26+
/** Environment variable names for the Gemini provider adapter. */
27+
export const GEMINI_ENV = {
28+
KEY: 'GEMINI_API_KEY',
29+
TARGET: 'GEMINI_API_TARGET',
30+
BASE_PATH: 'GEMINI_API_BASE_PATH',
31+
} as const;
32+
33+
/** Environment variable names for the Copilot provider adapter. */
34+
export const COPILOT_ENV = {
35+
GITHUB_TOKEN: 'COPILOT_GITHUB_TOKEN',
36+
PROVIDER_API_KEY: 'COPILOT_PROVIDER_API_KEY',
37+
PROVIDER_TYPE: 'COPILOT_PROVIDER_TYPE',
38+
PROVIDER_BASE_URL: 'COPILOT_PROVIDER_BASE_URL',
39+
API_TARGET: 'COPILOT_API_TARGET',
40+
API_BASE_PATH: 'COPILOT_API_BASE_PATH',
41+
} as const;

src/commands/build-config.ts

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { WrapperConfig, LogLevel, UpstreamProxyConfig } from '../types';
2+
import { OPENAI_ENV, ANTHROPIC_ENV, GEMINI_ENV, COPILOT_ENV } from '../api-proxy-env-constants';
23

34
/**
45
* Inputs required to assemble a {@link WrapperConfig}.
@@ -170,38 +171,38 @@ export function buildConfig(inputs: BuildConfigInputs): WrapperConfig {
170171
: undefined),
171172
maxCapturedBytes: (options.maxCapturedBytes as number | undefined) ??
172173
(process.env.AWF_MAX_BLOCKED_CAPTURE_BYTES ? Number(process.env.AWF_MAX_BLOCKED_CAPTURE_BYTES) : undefined),
173-
openaiApiKey: process.env.OPENAI_API_KEY,
174-
anthropicApiKey: process.env.ANTHROPIC_API_KEY,
175-
copilotGithubToken: process.env.COPILOT_GITHUB_TOKEN,
176-
copilotProviderApiKey: process.env.COPILOT_PROVIDER_API_KEY,
174+
openaiApiKey: process.env[OPENAI_ENV.KEY],
175+
anthropicApiKey: process.env[ANTHROPIC_ENV.KEY],
176+
copilotGithubToken: process.env[COPILOT_ENV.GITHUB_TOKEN],
177+
copilotProviderApiKey: process.env[COPILOT_ENV.PROVIDER_API_KEY],
177178
copilotProviderType:
178-
(options.copilotProviderType as string | undefined) || process.env.COPILOT_PROVIDER_TYPE,
179+
(options.copilotProviderType as string | undefined) || process.env[COPILOT_ENV.PROVIDER_TYPE],
179180
copilotProviderBaseUrl:
180-
(options.copilotProviderBaseUrl as string | undefined) || process.env.COPILOT_PROVIDER_BASE_URL,
181-
geminiApiKey: process.env.GEMINI_API_KEY,
181+
(options.copilotProviderBaseUrl as string | undefined) || process.env[COPILOT_ENV.PROVIDER_BASE_URL],
182+
geminiApiKey: process.env[GEMINI_ENV.KEY],
182183
copilotApiTarget: resolvedCopilotApiTarget,
183184
copilotApiBasePath: resolvedCopilotApiBasePath,
184185
copilotByokExtraHeaders: options.copilotByokExtraHeaders as Record<string, string> | undefined,
185186
copilotByokExtraBodyFields: options.copilotByokExtraBodyFields as Record<string, string> | undefined,
186187
copilotByokSessionId: options.copilotByokSessionId as string | undefined,
187188
openaiApiTarget:
188-
(options.openaiApiTarget as string | undefined) || process.env.OPENAI_API_TARGET,
189+
(options.openaiApiTarget as string | undefined) || process.env[OPENAI_ENV.TARGET],
189190
openaiApiBasePath:
190-
(options.openaiApiBasePath as string | undefined) || process.env.OPENAI_API_BASE_PATH,
191+
(options.openaiApiBasePath as string | undefined) || process.env[OPENAI_ENV.BASE_PATH],
191192
anthropicApiTarget:
192-
(options.anthropicApiTarget as string | undefined) || process.env.ANTHROPIC_API_TARGET,
193+
(options.anthropicApiTarget as string | undefined) || process.env[ANTHROPIC_ENV.TARGET],
193194
anthropicApiBasePath:
194-
(options.anthropicApiBasePath as string | undefined) || process.env.ANTHROPIC_API_BASE_PATH,
195+
(options.anthropicApiBasePath as string | undefined) || process.env[ANTHROPIC_ENV.BASE_PATH],
195196
openaiApiAuthHeader:
196-
(options.openaiApiAuthHeader as string | undefined) || process.env.AWF_OPENAI_AUTH_HEADER,
197+
(options.openaiApiAuthHeader as string | undefined) || process.env[OPENAI_ENV.AUTH_HEADER],
197198
anthropicApiAuthHeader:
198-
(options.anthropicApiAuthHeader as string | undefined) || process.env.AWF_ANTHROPIC_AUTH_HEADER,
199+
(options.anthropicApiAuthHeader as string | undefined) || process.env[ANTHROPIC_ENV.AUTH_HEADER],
199200
anthropicTokenUrl:
200201
(options.anthropicTokenUrl as string | undefined) || process.env.AWF_AUTH_ANTHROPIC_TOKEN_URL,
201202
geminiApiTarget:
202-
(options.geminiApiTarget as string | undefined) || process.env.GEMINI_API_TARGET,
203+
(options.geminiApiTarget as string | undefined) || process.env[GEMINI_ENV.TARGET],
203204
geminiApiBasePath:
204-
(options.geminiApiBasePath as string | undefined) || process.env.GEMINI_API_BASE_PATH,
205+
(options.geminiApiBasePath as string | undefined) || process.env[GEMINI_ENV.BASE_PATH],
205206
difcProxyHost: options.difcProxyHost as string | undefined,
206207
difcProxyCaCert: options.difcProxyCaCert as string | undefined,
207208
githubToken: process.env.GITHUB_TOKEN || process.env.GH_TOKEN,

src/services/api-proxy-service-config.ts

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { getConfigEnvValue, getLowerCaseProcessEnvValue, pickEnvVars } from '../
99
import { NetworkConfig, ImageBuildConfig } from './squid-service';
1010
import { applyHostPathPrefixToVolumes } from './host-path-prefix';
1111
import { buildContainerSecurityHardening } from './service-security';
12+
import { OPENAI_ENV, ANTHROPIC_ENV, GEMINI_ENV, COPILOT_ENV } from '../api-proxy-env-constants';
1213

1314
interface ApiProxyServiceConfigParams {
1415
config: WrapperConfig;
@@ -22,17 +23,17 @@ interface ApiProxyServiceConfigParams {
2223
* Centralizes the repetitive per-provider target/basePath conditional env generation.
2324
*/
2425
function buildProviderTargetEnv(config: WrapperConfig): Record<string, string> {
25-
const copilotProviderType = config.copilotProviderType || getConfigEnvValue(config, 'COPILOT_PROVIDER_TYPE');
26-
const copilotProviderBaseUrl = config.copilotProviderBaseUrl || getConfigEnvValue(config, 'COPILOT_PROVIDER_BASE_URL');
26+
const copilotProviderType = config.copilotProviderType || getConfigEnvValue(config, COPILOT_ENV.PROVIDER_TYPE);
27+
const copilotProviderBaseUrl = config.copilotProviderBaseUrl || getConfigEnvValue(config, COPILOT_ENV.PROVIDER_BASE_URL);
2728
const copilotProviderApiKey = config.copilotProviderApiKey;
2829

2930
const env: Record<string, string> = {};
3031

3132
const providers: Array<{ target?: string; basePath?: string; envTarget: string; envBasePath: string; stripTarget?: boolean }> = [
32-
{ target: config.copilotApiTarget, basePath: config.copilotApiBasePath, envTarget: 'COPILOT_API_TARGET', envBasePath: 'COPILOT_API_BASE_PATH', stripTarget: true },
33-
{ target: config.openaiApiTarget, basePath: config.openaiApiBasePath, envTarget: 'OPENAI_API_TARGET', envBasePath: 'OPENAI_API_BASE_PATH', stripTarget: true },
34-
{ target: config.anthropicApiTarget, basePath: config.anthropicApiBasePath, envTarget: 'ANTHROPIC_API_TARGET', envBasePath: 'ANTHROPIC_API_BASE_PATH', stripTarget: true },
35-
{ target: config.geminiApiTarget, basePath: config.geminiApiBasePath, envTarget: 'GEMINI_API_TARGET', envBasePath: 'GEMINI_API_BASE_PATH', stripTarget: true },
33+
{ target: config.copilotApiTarget, basePath: config.copilotApiBasePath, envTarget: COPILOT_ENV.API_TARGET, envBasePath: COPILOT_ENV.API_BASE_PATH, stripTarget: true },
34+
{ target: config.openaiApiTarget, basePath: config.openaiApiBasePath, envTarget: OPENAI_ENV.TARGET, envBasePath: OPENAI_ENV.BASE_PATH, stripTarget: true },
35+
{ target: config.anthropicApiTarget, basePath: config.anthropicApiBasePath, envTarget: ANTHROPIC_ENV.TARGET, envBasePath: ANTHROPIC_ENV.BASE_PATH, stripTarget: true },
36+
{ target: config.geminiApiTarget, basePath: config.geminiApiBasePath, envTarget: GEMINI_ENV.TARGET, envBasePath: GEMINI_ENV.BASE_PATH, stripTarget: true },
3637
];
3738

3839
for (const { target, basePath, envTarget, envBasePath, stripTarget } of providers) {
@@ -41,9 +42,9 @@ function buildProviderTargetEnv(config: WrapperConfig): Record<string, string> {
4142
}
4243

4344
// Copilot-specific provider passthrough
44-
if (copilotProviderType) env.COPILOT_PROVIDER_TYPE = copilotProviderType;
45-
if (copilotProviderBaseUrl) env.COPILOT_PROVIDER_BASE_URL = copilotProviderBaseUrl;
46-
if (copilotProviderApiKey) env.COPILOT_PROVIDER_API_KEY = copilotProviderApiKey;
45+
if (copilotProviderType) env[COPILOT_ENV.PROVIDER_TYPE] = copilotProviderType;
46+
if (copilotProviderBaseUrl) env[COPILOT_ENV.PROVIDER_BASE_URL] = copilotProviderBaseUrl;
47+
if (copilotProviderApiKey) env[COPILOT_ENV.PROVIDER_API_KEY] = copilotProviderApiKey;
4748

4849
// Pre-startup model validation (non-sensitive config value).
4950
// Prefer explicit requestedModel, but fall back to COPILOT_MODEL when present so
@@ -101,10 +102,10 @@ export function buildApiProxyServiceConfig(params: ApiProxyServiceConfigParams):
101102
),
102103
environment: {
103104
// Pass API keys securely to sidecar (not visible to agent)
104-
...(config.openaiApiKey && { OPENAI_API_KEY: config.openaiApiKey }),
105-
...(config.anthropicApiKey && { ANTHROPIC_API_KEY: config.anthropicApiKey }),
106-
...(config.copilotGithubToken && { COPILOT_GITHUB_TOKEN: config.copilotGithubToken }),
107-
...(config.geminiApiKey && { GEMINI_API_KEY: config.geminiApiKey }),
105+
...(config.openaiApiKey && { [OPENAI_ENV.KEY]: config.openaiApiKey }),
106+
...(config.anthropicApiKey && { [ANTHROPIC_ENV.KEY]: config.anthropicApiKey }),
107+
...(config.copilotGithubToken && { [COPILOT_ENV.GITHUB_TOKEN]: config.copilotGithubToken }),
108+
...(config.geminiApiKey && { [GEMINI_ENV.KEY]: config.geminiApiKey }),
108109
// Configurable API targets (for GHES/GHEC / custom endpoints)
109110
// Strip any scheme prefix — server.js also normalizes defensively, but
110111
// stripping here prevents a scheme-prefixed hostname from reaching the
@@ -259,8 +260,8 @@ export function buildApiProxyServiceConfig(params: ApiProxyServiceConfigParams):
259260
'AWF_ANTHROPIC_STRIP_ANSI',
260261
),
261262
// Custom auth header names for internal AI gateways
262-
...(config.openaiApiAuthHeader && { AWF_OPENAI_AUTH_HEADER: config.openaiApiAuthHeader }),
263-
...(config.anthropicApiAuthHeader && { AWF_ANTHROPIC_AUTH_HEADER: config.anthropicApiAuthHeader }),
263+
...(config.openaiApiAuthHeader && { [OPENAI_ENV.AUTH_HEADER]: config.openaiApiAuthHeader }),
264+
...(config.anthropicApiAuthHeader && { [ANTHROPIC_ENV.AUTH_HEADER]: config.anthropicApiAuthHeader }),
264265
...(config.anthropicTokenUrl && { AWF_AUTH_ANTHROPIC_TOKEN_URL: config.anthropicTokenUrl }),
265266
// NOTE: AWF_ANTHROPIC_TRANSFORM_FILE is intentionally NOT forwarded from the host.
266267
// The api-proxy container holds live API credentials; loading arbitrary host-side JS

0 commit comments

Comments
 (0)