Skip to content

[awf] Agent container: verify self-hosted runner compatibility when HOME != /home/runner #2109

@lpcox

Description

@lpcox

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/runnersrc/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:

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

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

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

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

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

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

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

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

Metadata

Metadata

Assignees

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