fix: share mcpg network namespace to fix TLS hostname verification#1778
fix: share mcpg network namespace to fix TLS hostname verification#1778
Conversation
✅ Coverage Check PassedOverall Coverage
📁 Per-file Coverage Changes (1 files)
Coverage comparison generated by |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
This PR refactors the CLI proxy sidecar into a two-container setup (mcpg proxy + HTTP exec server) to avoid brittle mcpg binary extraction and to fix the release build failure caused by an incorrect mcpg binary path.
Changes:
- Split CLI proxy into
cli-proxy-mcpg(runs officialgh-aw-mcpgimage) +cli-proxy(Node.js server +ghCLI) with a shared named volume for TLS certs. - Update compose generation + tests to model the two-service dependency chain and token isolation.
- Update predownload + CLI options to pull/parameterize the mcpg image, plus CI/test cleanup to remove the new container.
Show a summary per file
| File | Description |
|---|---|
src/docker-manager.ts |
Generates an additional cli-proxy-mcpg service, shared TLS volume, and revised dependency wiring for CLI proxy. |
containers/cli-proxy/entrypoint.sh |
Stops starting mcpg in-process; waits for shared TLS certs and configures gh to target mcpg service. |
containers/cli-proxy/Dockerfile |
Removes multi-stage mcpg extraction; leaves HTTP server + gh CLI only. |
src/commands/predownload.ts |
Adds mcpg image resolution/pull when CLI proxy is enabled. |
src/cli.ts |
Updates help text and wires mcpg image option through predownload subcommand. |
src/types.ts |
Updates JSDoc to reflect mcpg as a separate container image. |
src/docker-manager.test.ts |
Updates tests to assert two-service architecture and token placement. |
src/commands/predownload.test.ts |
Extends tests to verify mcpg image is included/pulled. |
scripts/ci/cleanup.sh |
Ensures new mcpg container is removed during CI cleanup. |
tests/fixtures/cleanup.ts |
Ensures new mcpg container is removed in test cleanup fixture. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (1)
containers/cli-proxy/entrypoint.sh:41
NODE_EXTRA_CA_CERTSonly affects Node.js TLS; theghCLI is a Go binary and will not use this environment variable. To ensureghtrusts the mcpg proxy’s self-signed CA, also set a CA path that Go honors (e.g.,SSL_CERT_FILE/SSL_CERT_DIR) or install the CA into the container’s system trust store before starting the server.
# Configure gh CLI to route through the mcpg proxy (TLS, self-signed CA)
export GH_HOST="${MCPG_HOST}:${MCPG_PORT}"
export NODE_EXTRA_CA_CERTS="/tmp/proxy-tls/ca.crt"
export GH_REPO="${GH_REPO:-$GITHUB_REPOSITORY}"
- Files reviewed: 10/10 changed files
- Comments generated: 2
|
|
||
| # Configure gh CLI to route through the mcpg proxy (TLS, self-signed CA) | ||
| export GH_HOST="localhost:18443" | ||
| export GH_HOST="${MCPG_HOST}:${MCPG_PORT}" | ||
| export NODE_EXTRA_CA_CERTS="/tmp/proxy-tls/ca.crt" | ||
| export GH_REPO="${GH_REPO:-$GITHUB_REPOSITORY}" |
There was a problem hiding this comment.
The mcpg container healthcheck validates https://localhost:${MCPG_PORT} with the generated cert, but the CLI proxy configures GH_HOST to ${MCPG_HOST}:${MCPG_PORT} (typically an IP like 172.30.0.51). If the mcpg server cert is issued only for localhost (common for self-signed startup certs), gh will fail TLS hostname verification when connecting via IP. Consider aligning the hostname used by clients and healthchecks (e.g., use the service DNS name) and/or configuring mcpg to generate a cert whose SAN covers the chosen hostname.
This issue also appears on line 38 of the same file.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Security Review — PR #1778Reviewed the architectural split of Finding 1 — mcpg now listens on all interfaces (was loopback-only)File: Before (old entrypoint.sh): mcpg proxy \
--listen 127.0.0.1:18443 \
...After (new docker-manager.ts): '--listen', `0.0.0.0:${mcpgPort}`,Why this matters: In the old architecture, mcpg was a child process inside the The The TLS self-signed cert provides a partial barrier (the agent container does not have Suggested mitigation: Bind mcpg to Finding 2 — Fail-close GH_TOKEN enforcement removedFile: Removed in this PR: if [ -z "$GH_TOKEN" ]; then
echo "[cli-proxy] ERROR: GH_TOKEN not set - refusing to start without mcpg DIFC enforcement"
exit 1
fiWhy this matters: This was an explicit fail-close guard: if In ...(config.githubToken && { GH_TOKEN: config.githubToken }),If Suggested mitigation: Either add an equivalent fail-close check in the No issues found in
|
|
@copilot apply changes based on the comments in this thread |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
🏗️ Build Test Suite Results
Overall: 8/8 ecosystems passed — ✅ PASS
|
Address security review findings from #1778: 1. Bind mcpg to its assigned IP (172.30.0.51) instead of 0.0.0.0 so the agent container cannot reach mcpg directly. Previously mcpg listened on all interfaces, making it reachable from any container on awf-net. 2. Add fail-close guard: generateDockerCompose now throws if enableCliProxy is set but githubToken is absent. mcpg requires a token to enforce DIFC policies — running without one would bypass integrity checks. 3. Use mcpg IP in healthcheck (not localhost) for TLS hostname consistency with how cli-proxy connects via GH_HOST. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Security Review — PR #1778Reviewed the split of 🔍 Finding:
|
| Change | Assessment |
|---|---|
GH_TOKEN moved from cli-proxy to cli-proxy-mcpg only |
Improvement — tighter credential scoping |
mcpg listening on 0.0.0.0:18443 (vs. in-process 127.0.0.1:18443) |
Acceptable — agent's filter chain has a default TCP DROP; 172.30.0.51 has no explicit ACCEPT, so agent→mcpg is blocked |
cli-proxy waits for shared TLS cert volume instead of locally-generated cert |
Acceptable — exits with code 1 if cert not present within 30 s |
Removal of GH_TOKEN check from cli-proxy entrypoint |
Acceptable — responsibility correctly shifted to cli-proxy-mcpg's own startup enforcement |
cli-proxy-tls named volume sharing TLS certs between mcpg and cli-proxy |
Acceptable — read-write in mcpg, read-only in cli-proxy (:ro) |
MCPG_HOST fallback to localhost in entrypoint |
Low risk — fails functionally (no listener), not a bypass |
No changes to setup-iptables.sh, src/host-iptables.ts, src/squid-config.ts, seccomp profile, or capability drops |
No regression |
Bottom line: The architectural direction is sound and the GH_TOKEN isolation improvement is a genuine security win. The one concrete gap worth addressing before merge is restoring HTTP_PROXY/HTTPS_PROXY on the cli-proxy container to preserve the defense-in-depth property that all sidecar containers route outbound traffic through Squid.
Generated by Security Guard for issue #1778 · ● 187.5K · ◷
413d75d to
1e3f99e
Compare
Applied in 413d75d. The mcpg self-signed TLS cert only covers Key changes:
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Agent-Logs-Url: https://github.com/github/gh-aw-firewall/sessions/1831b666-eb93-4772-9455-4604a64bfd24 Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
|
Smoke Test Results
Overall: PASS
|
🔬 Smoke Test Results
Overall: PASS PR by @lpcox · Assignees: none
|
This comment has been minimized.
This comment has been minimized.
Smoke Test: GitHub Actions Services Connectivity ✅All checks passed:
|
Chroot Version Comparison Results
Overall: ❌ Not all tests passed — Python and Node.js versions differ between host and chroot environments.
|
|
Smoke test results:
|
mcpg's
GenerateSelfSignedTLSgenerates certs with SANs forlocalhostand127.0.0.1only (source). The previous architecture had cli-proxy connecting to mcpg via its Docker network IP (172.30.0.51), which fails TLS hostname verification since that IP isn't in the cert's SANs.Fix:
network_mode: service:cli-proxy-mcpgcli-proxy now shares mcpg's network namespace.
localhostin cli-proxy resolves to mcpg, matching the cert's SAN.src/docker-manager.tsnetwork_mode: 'service:cli-proxy-mcpg'instead of its ownnetworksconfig127.0.0.1:18443(more restrictive than the Docker IP — only reachable from shared namespace)localhost(runs inside mcpg container, cert matches)AWF_CLI_PROXY_IPandAWF_CLI_PROXY_URLpoint to mcpg's IP since cli-proxy shares itAWF_MCPG_HOSTfrom cli-proxy env (no longer needed)containers/cli-proxy/entrypoint.shGH_HOST=localhost:${MCPG_PORT}— TLS hostname verification passessrc/types.tsDockerService.networksmade optional, addednetwork_modefield (mutually exclusive per Docker Compose spec)