Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions src/docker-manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2025,6 +2025,50 @@ describe('docker-manager', () => {
}
});

it('should not leak GITHUB_API_URL to agent when api-proxy is enabled with envAll', () => {
// When api-proxy is enabled, GITHUB_API_URL must be excluded so the Copilot CLI
// routes token exchange through COPILOT_API_URL → api-proxy (not directly to api.github.com
// with the placeholder COPILOT_GITHUB_TOKEN, which would cause a 401).
// See: github/gh-aw#20875

Copilot AI Mar 24, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test comment references github/gh-aw#20875, which doesn’t match the issue-link style used elsewhere in this repo (often gh-aw-firewall issue #... or a full URL). Consider updating to a consistent, resolvable link so future readers can easily find the context.

Suggested change
// See: github/gh-aw#20875
// See: https://github.com/github/gh-aw/issues/20875

Copilot uses AI. Check for mistakes.
const origUrl = process.env.GITHUB_API_URL;
process.env.GITHUB_API_URL = 'https://api.github.com';
try {
const configWithProxy = { ...mockConfig, enableApiProxy: true, copilotGithubToken: 'ghp_test_token', envAll: true };
const result = generateDockerCompose(configWithProxy, mockNetworkConfigWithProxy);
const agent = result.services.agent;
const env = agent.environment as Record<string, string>;
// GITHUB_API_URL should NOT be passed to agent when api-proxy is enabled
expect(env.GITHUB_API_URL).toBeUndefined();
// COPILOT_API_URL should be set to route through the api-proxy
expect(env.COPILOT_API_URL).toBe('http://172.30.0.30:10002');
} finally {
if (origUrl !== undefined) {
process.env.GITHUB_API_URL = origUrl;
} else {
delete process.env.GITHUB_API_URL;
}
}
});

it('should pass GITHUB_API_URL to agent when api-proxy is NOT enabled with envAll', () => {
const origUrl = process.env.GITHUB_API_URL;
process.env.GITHUB_API_URL = 'https://api.github.com';
try {
const configNoProxy = { ...mockConfig, enableApiProxy: false, envAll: true };
const result = generateDockerCompose(configNoProxy, mockNetworkConfig);
const agent = result.services.agent;
const env = agent.environment as Record<string, string>;
// When api-proxy is NOT enabled, GITHUB_API_URL should be passed through
expect(env.GITHUB_API_URL).toBe('https://api.github.com');
} finally {
if (origUrl !== undefined) {
process.env.GITHUB_API_URL = origUrl;
} else {
delete process.env.GITHUB_API_URL;
}
}
});

it('should set AWF_RATE_LIMIT env vars when rateLimitConfig is provided', () => {
const configWithRateLimit = {
...mockConfig,
Expand Down
22 changes: 14 additions & 8 deletions src/docker-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,12 @@ export function generateDockerCompose(
EXCLUDED_ENV_VARS.add('ANTHROPIC_API_KEY');
EXCLUDED_ENV_VARS.add('CLAUDE_API_KEY');
// COPILOT_GITHUB_TOKEN gets a placeholder (not excluded), protected by one-shot-token
// GITHUB_API_URL must be excluded so the Copilot CLI routes ALL requests (including
// token exchange) through COPILOT_API_URL → api-proxy, not directly to api.github.com.
// If GITHUB_API_URL is present, the CLI may call api.github.com/copilot_internal/v2/token
Comment on lines 456 to +460

Copilot AI Mar 24, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The enableApiProxy exclusion list is described as excluding “API keys”, but it now also excludes GITHUB_API_URL for routing/behavior reasons. Consider tweaking the nearby comment to reflect that this block excludes both sensitive credentials and env vars that would interfere with api-proxy routing.

This issue also appears in the following locations of the same file:

  • line 458
  • line 593

Copilot uses AI. Check for mistakes.
// with the placeholder COPILOT_GITHUB_TOKEN (bypassing the api-proxy injection), causing 401.
// See: github/gh-aw#20875
EXCLUDED_ENV_VARS.add('GITHUB_API_URL');
}

// Start with required/overridden environment variables
Expand Down Expand Up @@ -584,7 +590,14 @@ export function generateDockerCompose(
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;
// GITHUB_API_URL — only pass when api-proxy is NOT enabled.
// On GHES, workflows set GITHUB_API_URL to the GHES API endpoint (e.g., https://api.ghes-host).
// When api-proxy is enabled, Copilot CLI must use COPILOT_API_URL (pointing to the proxy)
// instead of GITHUB_API_URL, because the proxy correctly routes Copilot API requests to
// api.enterprise.githubcopilot.com (not the GHES API which lacks Copilot endpoints).
// GITHUB_API_URL is also excluded via EXCLUDED_ENV_VARS for the --env-all path.
// See: github/gh-aw#20875
if (process.env.GITHUB_API_URL && !config.enableApiProxy) environment.GITHUB_API_URL = process.env.GITHUB_API_URL;

// Auto-inject GH_HOST when GITHUB_SERVER_URL points to a GHES/GHEC instance
// This ensures gh CLI inside the agent container targets the correct GitHub instance
Expand All @@ -594,13 +607,6 @@ export function generateDockerCompose(
environment.GH_HOST = ghHost;
logger.debug(`Auto-injected GH_HOST=${ghHost} from GITHUB_SERVER_URL`);
}
// GITHUB_API_URL — only pass when api-proxy is NOT enabled.
// On GHES, workflows set GITHUB_API_URL to the GHES API endpoint (e.g., https://api.ghes-host).
// When api-proxy is enabled, Copilot CLI must use COPILOT_API_URL (pointing to the proxy)
// instead of GITHUB_API_URL, because the proxy correctly routes Copilot API requests to
// api.enterprise.githubcopilot.com (not the GHES API which lacks Copilot endpoints).
// See: github/gh-aw#20875
if (process.env.GITHUB_API_URL && !config.enableApiProxy) environment.GITHUB_API_URL = process.env.GITHUB_API_URL;
}

// Forward one-shot-token debug flag if set (used for testing/debugging)
Expand Down
Loading