-
Notifications
You must be signed in to change notification settings - Fork 11
feat(proxy): make copilot api target configurable for enterprise envi… #1063
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -46,12 +46,37 @@ const OPENAI_API_KEY = process.env.OPENAI_API_KEY; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const COPILOT_GITHUB_TOKEN = process.env.COPILOT_GITHUB_TOKEN; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Configurable Copilot API target host (supports GHES/GHEC / custom endpoints) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Priority: COPILOT_API_TARGET env var > auto-derive from GITHUB_SERVER_URL > default | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function deriveCopilotApiTarget() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (process.env.COPILOT_API_TARGET) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return process.env.COPILOT_API_TARGET; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+52
to
+53
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (process.env.COPILOT_API_TARGET) { | |
| return process.env.COPILOT_API_TARGET; | |
| const envTarget = process.env.COPILOT_API_TARGET; | |
| if (envTarget) { | |
| const trimmed = envTarget.trim(); | |
| if (trimmed) { | |
| // If a full URL is provided (e.g., https://api.githubcopilot.com), | |
| // parse it and extract the hostname so it can be safely used in | |
| // https.request({ hostname }) and as a URL base. | |
| if (trimmed.startsWith('http://') || trimmed.startsWith('https://')) { | |
| try { | |
| const url = new URL(trimmed); | |
| if (url.hostname) { | |
| return url.hostname; | |
| } | |
| } catch { | |
| // Invalid URL — fall through to serverUrl/default handling below. | |
| } | |
| } else { | |
| // Treat as a bare hostname. Reject obviously invalid forms that would | |
| // break https.request/new URL usage (paths or whitespace). | |
| if (!/[\/\s]/.test(trimmed)) { | |
| return trimmed; | |
| } | |
| // If invalid, fall through to serverUrl/default handling. | |
| } | |
| } |
Copilot
AI
Feb 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add test coverage for the new Copilot target selection logic: (1) COPILOT_API_TARGET override wins, and (2) non-github.com GITHUB_SERVER_URL causes the enterprise target to be used. Without a test, regressions here are easy to miss.
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -784,6 +784,12 @@ program | |||||||||||
| ' Supports OpenAI (Codex) and Anthropic (Claude) APIs.', | ||||||||||||
| false | ||||||||||||
| ) | ||||||||||||
| .option( | ||||||||||||
| '--copilot-api-target <host>', | ||||||||||||
| 'Target hostname for GitHub Copilot API requests in the api-proxy sidecar.\n' + | ||||||||||||
| ' Defaults to api.githubcopilot.com. Useful for GHES deployments.\n' + | ||||||||||||
| ' Can also be set via COPILOT_API_TARGET env var.', | ||||||||||||
|
Comment on lines
+790
to
+791
|
||||||||||||
| ' Defaults to api.githubcopilot.com. Useful for GHES deployments.\n' + | |
| ' Can also be set via COPILOT_API_TARGET env var.', | |
| ' Defaults to api.githubcopilot.com for GitHub.com.\n' + | |
| ' When GITHUB_SERVER_URL is set to a non-github.com host, defaults to api.enterprise.githubcopilot.com.\n' + | |
| ' This flag or the COPILOT_API_TARGET env var override the default.', |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -444,6 +444,9 @@ export function generateDockerCompose( | |
| if (process.env.USER) environment.USER = process.env.USER; | ||
| if (process.env.TERM) environment.TERM = process.env.TERM; | ||
| if (process.env.XDG_CONFIG_HOME) environment.XDG_CONFIG_HOME = process.env.XDG_CONFIG_HOME; | ||
| // Enterprise environment variables — needed for GHEC/GHES Copilot authentication | ||
| if (process.env.GITHUB_SERVER_URL) environment.GITHUB_SERVER_URL = process.env.GITHUB_SERVER_URL; | ||
| if (process.env.GITHUB_API_URL) environment.GITHUB_API_URL = process.env.GITHUB_API_URL; | ||
| } | ||
|
|
||
| // Additional environment variables from --env flags (these override everything) | ||
|
|
@@ -977,6 +980,10 @@ export function generateDockerCompose( | |
| ...(config.openaiApiKey && { OPENAI_API_KEY: config.openaiApiKey }), | ||
| ...(config.anthropicApiKey && { ANTHROPIC_API_KEY: config.anthropicApiKey }), | ||
| ...(config.copilotGithubToken && { COPILOT_GITHUB_TOKEN: config.copilotGithubToken }), | ||
| // Configurable Copilot API target (for GHES/GHEC support) | ||
| ...(config.copilotApiTarget && { COPILOT_API_TARGET: config.copilotApiTarget }), | ||
| // Forward GITHUB_SERVER_URL so api-proxy can auto-derive enterprise endpoints | ||
| ...(process.env.GITHUB_SERVER_URL && { GITHUB_SERVER_URL: process.env.GITHUB_SERVER_URL }), | ||
| // Route through Squid to respect domain whitelisting | ||
|
Comment on lines
+983
to
987
|
||
| HTTP_PROXY: `http://${networkConfig.squidIp}:${SQUID_PORT}`, | ||
| HTTPS_PROXY: `http://${networkConfig.squidIp}:${SQUID_PORT}`, | ||
|
|
@@ -1050,6 +1057,9 @@ export function generateDockerCompose( | |
| if (config.copilotGithubToken) { | ||
| environment.COPILOT_API_URL = `http://${networkConfig.proxyIp}:${API_PROXY_PORTS.COPILOT}`; | ||
| logger.debug(`GitHub Copilot API will be proxied through sidecar at http://${networkConfig.proxyIp}:${API_PROXY_PORTS.COPILOT}`); | ||
| if (config.copilotApiTarget) { | ||
| logger.debug(`Copilot API target overridden to: ${config.copilotApiTarget}`); | ||
| } | ||
|
|
||
| // Set placeholder token for GitHub Copilot CLI compatibility | ||
| // Real authentication happens via COPILOT_API_URL pointing to api-proxy | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -472,6 +472,28 @@ export interface WrapperConfig { | |
| * @default undefined | ||
| */ | ||
| copilotGithubToken?: string; | ||
|
|
||
| /** | ||
| * Target hostname for GitHub Copilot API requests (used by API proxy sidecar) | ||
| * | ||
| * When enableApiProxy is true, this hostname is passed to the Node.js sidecar | ||
| * as `COPILOT_API_TARGET`. The proxy will forward Copilot API requests to this host | ||
| * instead of the default `api.githubcopilot.com`. | ||
| * | ||
| * Useful for GitHub Enterprise Server (GHES) deployments where the Copilot API | ||
| * endpoint differs from the public default. | ||
| * | ||
| * Can be set via: | ||
| * - CLI flag: `--copilot-api-target <host>` | ||
| * - Environment variable: `COPILOT_API_TARGET` | ||
| * | ||
| * @default 'api.githubcopilot.com' | ||
| * @example | ||
|
Comment on lines
+487
to
+491
|
||
| * ```bash | ||
| * awf --enable-api-proxy --copilot-api-target api.github.mycompany.com -- command | ||
| * ``` | ||
| */ | ||
| copilotApiTarget?: string; | ||
| } | ||
|
|
||
| /** | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
README says the default target is always
api.githubcopilot.com, but the proxy now auto-derivesapi.enterprise.githubcopilot.comwhenGITHUB_SERVER_URLis set to a non-github.com host. Please update this description to match the implemented precedence (explicitCOPILOT_API_TARGET> derived fromGITHUB_SERVER_URL> public default).