-
Notifications
You must be signed in to change notification settings - Fork 325
MCP safe-output tools not accessible to Codex in AWF chroot on self-hosted runners (file permission issue) #21432
Description
Bug: MCP safe-output tools not invoked when Codex runs inside AWF chroot on self-hosted runners
Summary
When using the Codex engine with the AWF sandbox enabled on self-hosted runners running as root, Codex never invokes MCP safe-output tools (add_comment, add_labels, noop). The workflow completes successfully with exit code 0 but no comment or label is posted to the PR.
Evidence
- gh-aw v0.58.0 +
sandbox.agent: false(no AWF chroot): Codex runs as root on the host → reads MCP config → c 8000 allsadd_comment→ works correctly - gh-aw v0.60.0 + sandbox enabled (AWF chroot): Codex runs as
ec2-user(UID 1000) inside chroot → can't read root-owned MCP config → MCP tools invisible → no tool calls → no output
Root Cause
The AWF chroot drops privileges to a non-root host user (e.g. ec2-user, UID 1000) before executing Codex. However, the following files are created by root during compiler-generated setup steps and are not readable by the chroot user:
-
/tmp/gh-aw/mcp-config/config.toml(GH_AW_MCP_CONFIG) — Codex reads this to discover MCP servers. When unreadable, Codex has no knowledge ofadd_comment/add_labels/nooptools and falls back to built-in tools only (exec_command, file reads, etc.). -
/opt/gh-aw/safeoutputs/outputs.jsonl(GH_AW_SAFE_OUTPUTS) — Even if Codex could call tools, the output file path is under root-owned/opt/gh-aw/.
These files are created after any user-defined steps: run (e.g. Write Safe Outputs Config, Start Safe Outputs MCP HTTP Server), so workflow-level chmod workarounds cannot fix them.
The MCP gateway tools/list responses seen in gateway logs come from the gateway's own startup (running as root on the host), not from Codex inside the chroot. Codex inside the chroot never connects to the MCP gateway because it cannot read the config file.
Why This Only Affects Self-Hosted Runners
On GitHub-hosted runners, the runner user has broader filesystem permissions. On self-hosted runners configured to run as root (common pattern for AWS EC2 runners), the AWF chroot drops to a non-root user that cannot read root-owned files under /tmp/gh-aw/ and /opt/gh-aw/.
Observed Symptoms
# MCP gateway ingestion step:
Error reading agent output file: ENOENT: no such file or directory, open '/tmp/gh-aw/agent_output.json'
No agent output available - nothing to process
# Safe outputs step:
Output file does not exist: /opt/gh-aw/safeoutputs/outputs.jsonl
No agent output available - nothing to process
Workflow job exits with code 0 (success) but the conclusion job logs:
No no-op message found, skipping
Agentic Implementation Plan
File to modify: containers/agent/entrypoint.sh
Before the capsh --user=${HOST_USER} privilege drop, add a chmod to make gh-aw files accessible to the chroot user. Insert after the DNS configuration section (~line 430) and before the chroot /host /bin/bash -c "..." block:
# Ensure gh-aw temp files are accessible by the chroot user (UID: )
# These files are created by root during setup steps and must be readable
# by the non-root chroot user for MCP config discovery and safe-output writing.
echo "[entrypoint] Setting gh-aw directory permissions for chroot user..."
chmod -R a+rX /host/tmp/gh-aw 2>/dev/null || true
chmod -R a+rwX /host/tmp/gh-aw/mcp-config 2>/dev/null || true
chmod -R a+rwX /host/opt/gh-aw/safeoutputs 2>/dev/null || trueThis mirrors how the entrypoint already handles awfuser home directory ownership:
chown -R awfuser:awfuser /home/awfuser 2>/dev/null || trueTests to add in src/docker-manager.test.ts or a new integration test:
- Verify that a workflow using Codex engine on a self-hosted runner (simulated with a non-root chroot user) can invoke MCP safe-output tools after the permission fix
Environment
- gh-aw CLI: v0.60.0
- AWF: v0.24.2
- Engine: codex (
@openai/codexv0.115.0) - Model: gpt-5.3-codex (via internal OpenAI-compatible LLM router using
--openai-api-target) - Runner: Self-hosted (Amazon Linux 2023), runner service runs as
root, AWF chroot drops toec2-user(UID 1000)
Related
- Issue API proxy does not forward to custom OPENAI_BASE_URL / ANTHROPIC_BASE_URL endpoints (e.g., internal LLM routers) #20590 — custom API target support (resolved in gh-aw-firewall v0.24.0)
- gh-aw-firewall PR Add "imports" field to frontmatter for importing workflow specifications #1249 —
--openai-api-target/--anthropic-api-targetflags (merged)