Skip to content

DIFC proxy should use step-scoped env for GH_HOST instead of mutating GITHUB_ENV #26314

@lpcox

Description

@lpcox

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

  1. 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.

  2. 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.

  3. 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.

  4. 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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions