fix: relax gh-aw handoff permissions after AWF exits - #9029
Conversation
…n host-side steps Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Cleanup is skipped after failed commands, and permission widening can expose sensitive files beyond the intended handoff directory.
Review effort: Balanced
Findings: 1
Open (3)
What changed in this PR
Adds post-agent permission repair for /tmp/gh-aw to prevent host-side EACCES failures.
Changes:
- Adds group-permission cleanup and a relaxed umask.
- Adds shell coverage for permission repair.
- Documents UID/GID behavior and mitigation.
| File | Description |
|---|---|
containers/agent/entrypoint.sh |
Adds shared-directory permission handling. |
tests/entrypoint-phase-functions.test.sh |
Tests the new helper and wiring. |
docs/environment.md |
Documents shared-path permissions. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
@copilot address review feedback |
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Addressed the review feedback in |
|
✅ Copilot review passed with no inline comments. @copilot Add the |
Documentation PreviewDocumentation has been built for this PR. To view locally:
Built from commit e886d19 |
|
❌ Smoke Gemini reports failed. Facets need polishing... Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "play.googleapis.com"See Network Configuration for more information.
|
|
✅ Smoke Claude passed Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "api.anthropic.com"See Network Configuration for more information.
|
|
✅ Security Guard completed successfully! PR #9029 security review complete. Change: Added permission relaxation for gh-aw handoff directories in containers/agent/entrypoint.sh. The modification adds group-write permissions to specific whitelisted directories (/tmp/gh-aw/memory-validation) after agent exit. Security assessment: PASS. The implementation includes proper controls: symlink detection, directory validation, explicit allowlist (GH_AW_HOST_HANDOFF_DIRS), scope limitation to group-write only, and clear logging. This is a deliberate, scoped adjustment for post-agent inter-process coordination on multi-user runners, not a security regression.
|
|
🛡️ Smoke Copilot Network Isolation confirmed the egress allowlist is enforced. ✅ Warning Firewall blocked 2 domainsThe following domains were blocked by the firewall during workflow execution:
[!TIP] tools:
github:
mode: gh-proxySee GitHub Tools for more information on To allow these domains, add them to the network:
allowed:
- defaults
- "api.github.com"
- "example.com"See Network Configuration for more information.
|
Smoke Test: Claude Engine Validation
Overall result: PASS Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "api.anthropic.com"See Network Configuration for more information.
|
Smoke Test: Cloud Hypervisor + Copilot
All checks passed ✅ Warning Firewall blocked 2 domainsThe following domains were blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "example.com"
- "github.com"See Network Configuration for more information.
|
|
EGRESS_RESULT allow=pass deny=pass ✅ Allowed domain (github.com) reachable: Overall: PASS
Warning Firewall blocked 2 domainsThe following domains were blocked by the firewall during workflow execution:
[!TIP] tools:
github:
mode: gh-proxySee GitHub Tools for more information on To allow these domains, add them to the network:
allowed:
- defaults
- "api.github.com"
- "example.com"See Network Configuration for more information.
|
|
Smoke Test: Copilot Engine —
Overall: PASS
|
|
Smoke Test: GitHub Actions Services Connectivity
Overall: PASS
|
Smoke Test Results: Copilot BYOK (Direct)✅ GitHub MCP: PR connectivity verified Status: PASS — Running in direct BYOK mode via
|
🏗️ Build Test Suite Results
Overall: 8/8 ecosystems passed — PASS Note: Java (Maven) initially failed with All 18 test projects across 8 language ecosystems built/installed and passed their test suites successfully. Warning Firewall blocked 8 domainsThe following domains were blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "api.nuget.org"
- "bun.sh"
- "dc.services.visualstudio.com"
- "deno.land"
- "dl.deno.land"
- "github.com"
- "releaseassets.githubusercontent.com"
- "repo.maven.apache.org"See Network Configuration for more information.
|
Chroot Version Comparison Results
Overall: FAILED — Node.js version mismatch between host and chroot environments. Python and Go versions match correctly, but the chroot Node.js version (v22.23.2) differs from the host (v24.21.0). Since not all tests passed, the
|
📡 Smoke Test: API Proxy OTEL Tracing — Results
Overall: All scenarios pass or are expected-pending. No regression detected in the OTEL tracing integration. Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "o205451.ingest.us.sentry.io"See Network Configuration for more information.
|
* Initial plan * docs: add B35 and D16 failure modes Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> * docs: update runner doctor playbook for B35 D16 * docs: refresh B35 status when PR closes * docs: mark B35 provisional pending PR merge * docs: clarify B35 fix is not yet shipped * docs: isolate B35 unmerged remediation details * docs: clarify B35 status is a dated snapshot * docs: track B35 follow-up in issue 9028 * docs: remove B35 status snapshot date * docs: link B35 pending status to canonical entry * docs: mark B35 proposal unverified * docs: mark B35 fixed by merged #9029 * docs: add B35 patched-build verification probe --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>



Host-side steps that run after the AWF agent container exits (e.g. gh-aw's
validateMemoryStepfortools.cache-memory) can fail withEACCES: permission deniedwhen writing into/tmp/gh-aw(e.g.memory-validation/cache-default.ok). AWF remaps the agent's UID/GID to match the host user, but files created during the run can still end up with ownership/mode that a later host-side identity can't write into.containers/agent/entrypoint.shumask 0002for the user command so new files/dirs the agent creates under/tmp/gh-awdefault to group-writable.relax_gh_aw_shared_permissions(), run as root right after the agent command exits (both the normal exit path and the signal-driven cleanup path), whichchmod -R g+w's the/tmp/gh-awtree (/host/tmp/gh-awin chroot mode,/tmp/gh-awotherwise) without making it world-writable.run_agent_with_token_protection()rather than after thechroot ... exec capshinvocation inrun_chroot_command, sinceexec capshreplaces the chroot shell's process image and any code placed after it there would never run.Tests
tests/entrypoint-phase-functions.test.sh: added a fixture test assertingrelax_gh_aw_shared_permissions()adds the group-write bit without widening to world-writable, and that it's wired intorun_agent_with_token_protection().Docs
docs/environment.md: documented the UID/GID remap vs. shared/tmp/gh-awinteraction, why it can still mismatch (e.g. AWF invoked as native root withoutsudo), and the mitigation, with guidance to prefersudo awfwhen possible.