Problem
github/gh-aw issue #27260 reports that self-hosted Linux runners with a non-standard service account (home directory ≠ /home/runner) cannot use gh-aw without compatibility shims. The root cause in gh-aw is that setup scripts and workflow generation hardcode /home/runner/.copilot and runner:runner ownership. This tracking issue covers the AWF firewall (gh-aw-firewall) side of the same problem.
Context
Root Cause
The AWF firewall largely avoids hardcoding /home/runner — src/docker-manager.ts uses getRealUserHome() (line 209) which reads process.env.HOME || '/root', and XDG_CONFIG_HOME is forwarded from the host environment (line 938). However, several gaps remain:
-
~/.copilot mount always happens (src/docker-manager.ts:1167): The .copilot directory is bind-mounted from effectiveHome/.copilot on the host. If gh-aw setup scripts have already written GH_AW_MCP_CONFIG pointing to /home/runner/.copilot/mcp-config.json but the actual user home is /home/svc-agent, the mount source may not exist, causing a silent failure or Docker error.
-
emptyHomeDir volume path (src/docker-manager.ts:1157): The empty writable home volume is mounted at /host\$\{effectiveHome}. If the chroot expects a specific path hierarchy that doesn't exist in the container, tool invocations may fail.
-
containers/agent/entrypoint.sh UID/GID remapping: The entrypoint remaps to the host UID/GID but the home directory path it uses inside the chroot must match the effective home. This needs verification against non-/home/runner layouts.
-
Missing pre-mount existence check: src/docker-manager.ts does not verify that effectiveHome/.copilot exists before mounting it. On a fresh self-hosted runner that hasn't run Copilot CLI yet, this directory may not exist, causing docker compose up to fail.
Proposed Solution
-
Add existence check before ~/.copilot bind-mount in src/docker-manager.ts around line 1164–1167: use fs.existsSync(effectiveHome + '/.copilot') and skip the bind-mount (or create the directory) if it doesn't exist.
-
Add an integration test that runs AWF with HOME=/tmp/test-runner-home (a directory with no pre-existing .copilot) to confirm startup does not fail and tools can still write to the home volume.
-
Document in docs/environment.md that AWF derives the runner home from $HOME at runtime, and that self-hosted runners with non-standard home paths are supported as long as $HOME is set correctly before invoking awf.
-
Coordinate with gh-aw so that when gh-aw fixes GH_AW_MCP_CONFIG to use a runtime-derived path, the firewall's XDG_CONFIG_HOME forwarding (line 938) and .copilot mount source (line 1167) automatically pick up the corrected value without further changes.
Acceptance Criteria
- AWF starts successfully when
HOME is set to a non-/home/runner path on the host
- No Docker bind-mount errors when
~/.copilot does not yet exist on a fresh self-hosted runner
docs/environment.md notes self-hosted runner support
Generated by Firewall Issue Dispatcher · ● 565.2K · ◷
Problem
github/gh-awissue #27260 reports that self-hosted Linux runners with a non-standard service account (home directory ≠/home/runner) cannot usegh-awwithout compatibility shims. The root cause ingh-awis that setup scripts and workflow generation hardcode/home/runner/.copilotandrunner:runnerownership. This tracking issue covers the AWF firewall (gh-aw-firewall) side of the same problem.Context
src/docker-manager.ts,containers/agent/entrypoint.shRoot Cause
The AWF firewall largely avoids hardcoding
/home/runner—src/docker-manager.tsusesgetRealUserHome()(line 209) which readsprocess.env.HOME || '/root', andXDG_CONFIG_HOMEis forwarded from the host environment (line 938). However, several gaps remain:~/.copilotmount always happens (src/docker-manager.ts:1167): The.copilotdirectory is bind-mounted fromeffectiveHome/.copiloton the host. Ifgh-awsetup scripts have already writtenGH_AW_MCP_CONFIGpointing to/home/runner/.copilot/mcp-config.jsonbut the actual user home is/home/svc-agent, the mount source may not exist, causing a silent failure or Docker error.emptyHomeDirvolume path (src/docker-manager.ts:1157): The empty writable home volume is mounted at/host\$\{effectiveHome}. If the chroot expects a specific path hierarchy that doesn't exist in the container, tool invocations may fail.containers/agent/entrypoint.shUID/GID remapping: The entrypoint remaps to the host UID/GID but the home directory path it uses inside the chroot must match the effective home. This needs verification against non-/home/runnerlayouts.Missing pre-mount existence check:
src/docker-manager.tsdoes not verify thateffectiveHome/.copilotexists before mounting it. On a fresh self-hosted runner that hasn't run Copilot CLI yet, this directory may not exist, causingdocker compose upto fail.Proposed Solution
Add existence check before
~/.copilotbind-mount insrc/docker-manager.tsaround line 1164–1167: usefs.existsSync(effectiveHome + '/.copilot')and skip the bind-mount (or create the directory) if it doesn't exist.Add an integration test that runs AWF with
HOME=/tmp/test-runner-home(a directory with no pre-existing.copilot) to confirm startup does not fail and tools can still write to the home volume.Document in
docs/environment.mdthat AWF derives the runner home from$HOMEat runtime, and that self-hosted runners with non-standard home paths are supported as long as$HOMEis set correctly before invokingawf.Coordinate with
gh-awso that whengh-awfixesGH_AW_MCP_CONFIGto use a runtime-derived path, the firewall'sXDG_CONFIG_HOMEforwarding (line 938) and.copilotmount source (line 1167) automatically pick up the corrected value without further changes.Acceptance Criteria
HOMEis set to a non-/home/runnerpath on the host~/.copilotdoes not yet exist on a fresh self-hosted runnerdocs/environment.mdnotes self-hosted runner support