Problem
When the DIFC proxy starts (start_difc_proxy.sh), it writes GH_HOST=localhost:18443 to $GITHUB_ENV. This is a global mutation that persists across all subsequent steps in the job. This causes several problems:
1. GHE host value is lost after proxy stops
On GHES/GHEC runners, configure_gh_for_ghe.sh sets GH_HOST=myorg.ghe.com in $GITHUB_ENV. When the DIFC proxy starts, it overwrites this with localhost:18443. When stop_difc_proxy.sh runs, it only clears GH_HOST if the value equals localhost:18443 — it writes an empty value, not the original GHE hostname. All subsequent steps (including AWF/agent execution) see an empty GH_HOST and fall back to github.com, which is wrong for enterprise deployments.
2. Whack-a-mole for gh CLI commands that depend on GH_HOST
GH_HOST=localhost:18443 breaks any gh CLI command that resolves the repository from git remotes (e.g., gh pr checkout, gh pr list, gh repo view) because localhost:18443 does not match any git remote URL. This has required successive workarounds:
Each new gh command usage in a proxied context risks hitting the same problem and needing a new workaround.
3. AWF env leakage
When AWF runs with --env-all, the proxy-rewritten GH_HOST=localhost:18443 can leak into the agent container. AWF has its own mitigation (extractGhHostFromServerUrl() in docker-manager.ts), but this is defense-in-depth for a problem that should not exist.
Root cause
start_difc_proxy.sh mutates shared global state ($GITHUB_ENV) to route traffic through the proxy. This is the wrong scope — only the steps that need the proxy should see the proxy address.
Proposed solution: step-scoped env: blocks
Instead of writing GH_HOST to $GITHUB_ENV, the compiler should emit step-level env: blocks on each step that needs proxy routing. GitHub Actions step-level env: takes precedence over $GITHUB_ENV values but does not mutate them.
Before (current)
- name: Start DIFC proxy
run: bash start_difc_proxy.sh
# writes GH_HOST=localhost:18443 to $GITHUB_ENV (GLOBAL)
- name: Set GH_REPO for proxied steps
run: echo "GH_REPO=${GITHUB_REPOSITORY}" >> "$GITHUB_ENV"
- name: Custom user step
run: gh pr list # sees GH_HOST=localhost:18443 from GITHUB_ENV
- name: Stop DIFC proxy
run: bash stop_difc_proxy.sh
# tries to clear GH_HOST, loses GHE value
After (proposed)
- name: Start DIFC proxy
run: bash start_difc_proxy.sh
# starts the proxy container but does NOT write GH_HOST to $GITHUB_ENV
- name: Custom user step
env:
GH_HOST: localhost:18443
GH_REPO: ${{ github.repository }}
GITHUB_API_URL: https://localhost:18443/api/v3
GITHUB_GRAPHQL_URL: https://localhost:18443/api/graphql
NODE_EXTRA_CA_CERTS: /tmp/gh-aw/proxy-logs/proxy-tls/ca.crt
run: gh pr list # sees proxy address from step-level env
- name: Stop DIFC proxy
run: bash stop_difc_proxy.sh
# only stops the container, no env restore needed
Changes required
-
start_difc_proxy.sh: Remove the lines that write GH_HOST, GITHUB_API_URL, GITHUB_GRAPHQL_URL, NODE_EXTRA_CA_CERTS, and GH_REPO to $GITHUB_ENV. Keep the container start, health check, CA cert installation, and git remote add proxy logic.
-
stop_difc_proxy.sh: Remove all the $GITHUB_ENV restore/clear logic (the GH_HOST, GITHUB_API_URL, GITHUB_GRAPHQL_URL, NODE_EXTRA_CA_CERTS lines). Keep the container stop and CA cert removal.
-
compiler_difc_proxy.go: In the compiler, when emitting custom user steps that run between proxy start and proxy stop, inject a step-level env: block with the proxy routing variables. This is where generateSetGHRepoAfterDIFCProxyStep() currently lives — that standalone step can be removed since GH_REPO moves into the per-step env block.
-
compiler_yaml_main_job.go: Update step generation to pass proxy env vars to custom steps when DIFC proxy is active.
Benefits
- GHE works correctly:
GH_HOST=myorg.ghe.com in $GITHUB_ENV is never overwritten. Steps that do not need the proxy see the correct enterprise host.
- No save/restore logic:
GH_AW_ORIGINAL_GITHUB_API_URL / GH_AW_ORIGINAL_GITHUB_GRAPHQL_URL save/restore pattern can be removed entirely.
- No GH_REPO workaround step: The
Set GH_REPO for proxied steps step is eliminated.
- New gh commands just work: Any new
gh command in a non-proxied step automatically sees the correct GH_HOST — no per-command workarounds needed.
- AWF env leakage eliminated: The proxy address never enters
$GITHUB_ENV, so --env-all cannot leak it.
Scope
This covers the pre-agent DIFC proxy (start_difc_proxy.sh / stop_difc_proxy.sh). The CLI proxy (start_cli_proxy.sh) is unaffected — it already does not modify $GITHUB_ENV (comment: "does NOT modify GH_HOST or GITHUB_ENV").
Related
Problem
When the DIFC proxy starts (
start_difc_proxy.sh), it writesGH_HOST=localhost:18443to$GITHUB_ENV. This is a global mutation that persists across all subsequent steps in the job. This causes several problems:1. GHE host value is lost after proxy stops
On GHES/GHEC runners,
configure_gh_for_ghe.shsetsGH_HOST=myorg.ghe.comin$GITHUB_ENV. When the DIFC proxy starts, it overwrites this withlocalhost:18443. Whenstop_difc_proxy.shruns, it only clearsGH_HOSTif the value equalslocalhost:18443— it writes an empty value, not the original GHE hostname. All subsequent steps (including AWF/agent execution) see an emptyGH_HOSTand fall back togithub.com, which is wrong for enterprise deployments.2. Whack-a-mole for gh CLI commands that depend on GH_HOST
GH_HOST=localhost:18443breaks anyghCLI command that resolves the repository from git remotes (e.g.,gh pr checkout,gh pr list,gh repo view) becauselocalhost:18443does not match any git remote URL. This has required successive workarounds:getGhEnvBypassingIntegrityFilteringForGitOps()— per-callGH_HOSToverride (removed in Replacegh pr checkoutwithgit fetch refs/pullto avoid GH_HOST issues #26136)generateSetGHRepoAfterDIFCProxyStep()— setsGH_REPOsoghdoes not need to match remotesgh pr checkoutwithgit fetch refs/pullto avoid GH_HOST issues #26136 — replacedgh pr checkoutwithgit fetch refs/pull/N/headto avoidghCLI entirelyEach new
ghcommand usage in a proxied context risks hitting the same problem and needing a new workaround.3. AWF env leakage
When AWF runs with
--env-all, the proxy-rewrittenGH_HOST=localhost:18443can leak into the agent container. AWF has its own mitigation (extractGhHostFromServerUrl()indocker-manager.ts), but this is defense-in-depth for a problem that should not exist.Root cause
start_difc_proxy.shmutates shared global state ($GITHUB_ENV) to route traffic through the proxy. This is the wrong scope — only the steps that need the proxy should see the proxy address.Proposed solution: step-scoped
env:blocksInstead of writing
GH_HOSTto$GITHUB_ENV, the compiler should emit step-levelenv:blocks on each step that needs proxy routing. GitHub Actions step-levelenv:takes precedence over$GITHUB_ENVvalues but does not mutate them.Before (current)
After (proposed)
Changes required
start_difc_proxy.sh: Remove the lines that writeGH_HOST,GITHUB_API_URL,GITHUB_GRAPHQL_URL,NODE_EXTRA_CA_CERTS, andGH_REPOto$GITHUB_ENV. Keep the container start, health check, CA cert installation, andgit remote add proxylogic.stop_difc_proxy.sh: Remove all the$GITHUB_ENVrestore/clear logic (theGH_HOST,GITHUB_API_URL,GITHUB_GRAPHQL_URL,NODE_EXTRA_CA_CERTSlines). Keep the container stop and CA cert removal.compiler_difc_proxy.go: In the compiler, when emitting custom user steps that run between proxy start and proxy stop, inject a step-levelenv:block with the proxy routing variables. This is wheregenerateSetGHRepoAfterDIFCProxyStep()currently lives — that standalone step can be removed sinceGH_REPOmoves into the per-step env block.compiler_yaml_main_job.go: Update step generation to pass proxy env vars to custom steps when DIFC proxy is active.Benefits
GH_HOST=myorg.ghe.comin$GITHUB_ENVis never overwritten. Steps that do not need the proxy see the correct enterprise host.GH_AW_ORIGINAL_GITHUB_API_URL/GH_AW_ORIGINAL_GITHUB_GRAPHQL_URLsave/restore pattern can be removed entirely.Set GH_REPO for proxied stepsstep is eliminated.ghcommand in a non-proxied step automatically sees the correctGH_HOST— no per-command workarounds needed.$GITHUB_ENV, so--env-allcannot leak it.Scope
This covers the pre-agent DIFC proxy (
start_difc_proxy.sh/stop_difc_proxy.sh). The CLI proxy (start_cli_proxy.sh) is unaffected — it already does not modify$GITHUB_ENV(comment: "does NOT modify GH_HOST or GITHUB_ENV").Related
gh pr checkoutwithgit fetch refs/pullto avoid GH_HOST issues #26136 — Replacegh pr checkoutwithgit fetch refs/pull(merged, worked around the symptom)