Skip to content

Commit 6a9fcf9

Browse files
authored
fix: unblock Smoke Gemini — exclude MCP host env leak, allow api-proxy IP through Squid (#2986)
* Initial plan * fix: allow api-proxy IP through Squid, exclude MCP host env * fix: tighten apiProxyIp IPv4 validation to reject invalid octets * fix: validate apiProxyPorts, sync policy manifest, add api-proxy tests --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent 2701fc3 commit 6a9fcf9

7 files changed

Lines changed: 235 additions & 10 deletions

File tree

.github/workflows/smoke-gemini.lock.yml

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.github/workflows/smoke-gemini.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ network:
1818
allowed:
1919
- defaults
2020
- github
21+
- generativelanguage.googleapis.com
22+
- aiplatform.googleapis.com
2123
tools:
2224
bash:
2325
- "*"

src/container-lifecycle.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as fs from 'fs';
22
import * as path from 'path';
33
import * as yaml from 'js-yaml';
44
import execa from 'execa';
5-
import { WrapperConfig, BlockedTarget } from './types';
5+
import { WrapperConfig, BlockedTarget, API_PROXY_PORTS } from './types';
66
import { logger } from './logger';
77
import { generateSquidConfig, generatePolicyManifest } from './squid-config';
88
import { parseDomainWithProtocol, isWildcardPattern, wildcardToRegex } from './domain-patterns';
@@ -252,6 +252,13 @@ export async function writeConfigs(config: WrapperConfig): Promise<void> {
252252
enableDlp: config.enableDlp,
253253
dnsServers: config.dnsServers,
254254
upstreamProxy: config.upstreamProxy,
255+
// Allow the api-proxy sidecar IP through Squid before the raw-IP deny rule.
256+
// Some HTTP clients (e.g., Node.js fetch / undici ProxyAgent) route requests
257+
// to the api-proxy via HTTP_PROXY without honouring NO_PROXY for raw IPs.
258+
...(config.enableApiProxy && networkConfig.proxyIp ? {
259+
apiProxyIp: networkConfig.proxyIp,
260+
apiProxyPorts: Object.values(API_PROXY_PORTS),
261+
} : {}),
255262
});
256263
const squidConfigPath = path.join(config.workDir, 'squid.conf');
257264
fs.writeFileSync(squidConfigPath, squidConfig, { mode: 0o644 });
@@ -297,6 +304,9 @@ export async function writeConfigs(config: WrapperConfig): Promise<void> {
297304
allowHostPorts: config.allowHostPorts,
298305
enableDlp: config.enableDlp,
299306
dnsServers: config.dnsServers,
307+
...(config.enableApiProxy && networkConfig.proxyIp ? {
308+
apiProxyIp: networkConfig.proxyIp,
309+
} : {}),
300310
});
301311
fs.writeFileSync(
302312
path.join(auditDir, 'policy-manifest.json'),

src/services/agent-environment.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ export function buildAgentEnvironment(params: AgentEnvironmentParams): Record<st
6161
// via --env-all; they are set explicitly by generateDockerCompose when needed.
6262
'AWF_PREFLIGHT_BINARY',
6363
'AWF_GEMINI_ENABLED',
64+
// Host-side MCP gateway domain (always "localhost" on the runner) must not leak
65+
// into the agent container. Inside the container, MCP CLI wrappers must use
66+
// MCP_GATEWAY_DOMAIN (host.docker.internal) to reach the gateway — not this
67+
// host-only alias. Leaking MCP_GATEWAY_HOST_DOMAIN=localhost causes some HTTP
68+
// clients to route MCP gateway requests through HTTP_PROXY to Squid, which then
69+
// blocks "localhost" because it is not in the domain allow-list.
70+
'MCP_GATEWAY_HOST_DOMAIN',
6471
]);
6572

6673
// When api-proxy is enabled, exclude API keys from agent environment

0 commit comments

Comments
 (0)