Skip to content

[WIP] Fix permissions for gh-aw config files in self-hosted runners#1520

Closed
Copilot wants to merge 1 commit intomainfrom
copilot/fix-gh-aw-config-file-permissions
Closed

[WIP] Fix permissions for gh-aw config files in self-hosted runners#1520
Copilot wants to merge 1 commit intomainfrom
copilot/fix-gh-aw-config-file-permissions

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 31, 2026

Thanks for asking me to work on this. I will get started on it and keep this PR's description up to date as I form a plan and make progress.


This section details on the original issue you should resolve

<issue_title>agent-container: root-owned gh-aw config files unreadable by chroot user on self-hosted runners; chmod before privilege drop in
[Content truncated due to length]</issue_title>
<issue_description>## Problem

On self-hosted runners where the GitHub Actions runner service runs as root, AWF drops privileges to the non-root host user (e.g., ec2-user, UID 1000) before executing the agent command. The following files are created by root after the runner user's pre-steps and are therefore not readable by the chroot user:

  • /tmp/gh-aw/mcp-config/config.toml ($GH_AW_MCP_CONFIG) — MCP server discovery config; without read access, the agent has no knowledge of add_comment/noop/other safe-output tools.
  • /opt/gh-aw/safeoutputs/outputs.jsonl ($GH_AW_SAFE_OUTPUTS) — Safe-output write target; without write access, tool calls produce no output.

The agent completes with exit code 0, but no comments, labels, or safe-output actions are posted to the PR. The "Process Safe Outputs" step reports Output file does not exist: /opt/gh-aw/safeoutputs/outputs.jsonl.

Context

Original report: github/gh-aw#21432

Confirmed:

  • Without AWF chroot (sandbox.agent: false): Codex runs as root, reads MCP config, posts comment — ✅ works.
  • With AWF chroot (v0.60.0+): Codex runs as ec2-user (UID 1000), cannot read root-owned files — ❌ fails silently.

On GitHub-hosted runners this is typically not an issue because the runner user owns /tmp and /opt.

Root Cause

In containers/agent/entrypoint.sh, the privilege drop via capsh --user=${HOST_USER} happens before the agent command runs, but the gh-aw setup steps (running as root on the host) create the MCP config and safe-outputs files after the Docker container is already started and chroot is prepared. The entrypoint does not chmod these paths.

The entrypoint already does similar ownership fixes for the agent home:

chown -R awfuser:awfuser /home/awfuser 2>/dev/null || true

The same pattern needs to be applied to gh-aw runtime files.

Proposed Solution

In containers/agent/entrypoint.sh, add a permission fix block after the DNS configuration section and before the capsh/chroot block. Insert approximately after line 430 (before privilege drop):

# Make gh-aw runtime files readable/writable by the chroot user.
# These files are created by root during workflow setup steps.
# Required for MCP tool discovery (config.toml) and safe-output writing (outputs.jsonl).
for gh_aw_dir in /host/tmp/gh-aw /host/opt/gh-aw/safeoutputs; do
  if [ -d "$gh_aw_dir" ]; then
    echo "[entrypoint] Setting permissions on $gh_aw_dir for chroot user (UID: ${HOST_UID})"
    chmod -R a+rX "$gh_aw_dir" 2>/dev/null || true
    # safeoutputs dir needs write access for the agent to record tool calls
    chmod -R a+rwX "$gh_aw_dir" 2>/dev/null || true
  fi
done
if [ -f /host/tmp/gh-aw/mcp-config/config.toml ]; then
  chmod a+r /host/tmp/gh-aw/mcp-config/config.toml 2>/dev/null || true
fi

Additionally, apply chmod a+rX recursively to the entire /host/tmp/gh-aw/ tree so that any other path-based configs added in the future are automatically accessible.

Add integration test in tests/ simulating a non-root chroot user reading /tmp/gh-aw/mcp-config/config.toml created by root, verifying the entrypoint permission fix resolves the EACCES error.

Generated by AWF Issue Auditor ·

<agent_instructions>Create a PR that address this issue.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants