fix: use 0o777 permissions for mcp-logs and squid-logs directories#710
Conversation
Fixes permission denied error when GitHub Actions workflows try to create subdirectories in /tmp/gh-aw/mcp-logs after AWF runs with sudo. Changes: - Set directory permissions to 0o777 (rwxrwxrwx) instead of 0o755 - Explicitly call chmodSync after mkdirSync to bypass umask - Fix permissions if directory already exists from previous run - Update test to verify 777 permissions Root cause: When AWF runs with sudo (e.g., --enable-chroot), it creates /tmp/gh-aw/mcp-logs owned by root. With 755 permissions, non-root users cannot create subdirectories. Using 777 allows workflows to create subdirectories like /tmp/gh-aw/mcp-logs/safeoutputs without sudo. Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Apply same fix to squidLogsDir for consistency with mcpLogsDir. Explicitly calls chmodSync to bypass umask effects. Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤 |
|
🎬 THE END — Smoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨ |
|
Chroot tests failed Smoke Chroot was cancelled - See logs for details. |
|
🎬 THE END — Smoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨ |
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤 |
|
Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded. |
Build Test: Bun - Results
Overall: PASS ✅ All Bun projects built and tested successfully.
|
Deno Build Test Results ✅
Overall: ✅ PASS All Deno tests completed successfully.
|
Build Test: Go - ResultsAll Go projects tested successfully! ✅
Overall: PASS
|
|
Smoke Test Results (Claude) Last 2 merged PRs:
✅ GitHub MCP - Retrieved PRs Status: PASS
|
Smoke Test ResultsLast 2 Merged PRs:
Tests:
Overall Status: PASS cc
|
C++ Build Test Results
Overall: PASS All C++ projects built successfully.
|
Node.js Build Test Results
Overall: PASS ✅ All Node.js test projects built and tested successfully.
|
Build Test: .NET
Overall: PASS All .NET projects successfully restored, built, and ran with expected output.
|
Rust Build Test Results
Overall: PASS All Rust projects built and tested successfully.
|
Chroot Version Comparison Results ❌
Overall: Tests did not pass. Python and Node.js versions differ between host and chroot environments.
|
abeeb41
into
copilot/fix-github-actions-workflow-another-one
There was a problem hiding this comment.
Pull request overview
This PR addresses GitHub Actions permission failures by making the host log directories used by AWF world-writable, ensuring non-root steps can create subdirectories even when AWF is run via sudo.
Changes:
- Create
/tmp/gh-aw/mcp-logswith0o777and explicitlychmodit to bypass umask. - Create
squid-logswith0o777and explicitlychmodit on creation. - Extend
writeConfigstest coverage to assertmcp-logspermissions are0777.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/docker-manager.ts | Adjusts creation/permissions logic for mcp-logs and squid-logs directories. |
| src/docker-manager.test.ts | Updates the writeConfigs test to assert mcp-logs is created with 0777. |
Comments suppressed due to low confidence (1)
src/docker-manager.ts:878
squidLogsDironly getschmodSync(..., 0o777)when the directory is newly created. If it already exists from a previous run with more restrictive permissions, this code won’t fix it (unlikemcpLogsDirbelow) and the debug log still says "created" even when it wasn’t. Consider adding anelsebranch (and adjusting the log message) to normalize permissions consistently, in line with the PR description.
const squidLogsDir = config.proxyLogsDir || path.join(config.workDir, 'squid-logs');
if (!fs.existsSync(squidLogsDir)) {
fs.mkdirSync(squidLogsDir, { recursive: true, mode: 0o777 });
// Explicitly set permissions to 0o777 (not affected by umask)
fs.chmodSync(squidLogsDir, 0o777);
}
logger.debug(`Squid logs directory created at: ${squidLogsDir}`);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| fs.chmodSync(mcpLogsDir, 0o777); | ||
| logger.debug(`MCP logs directory permissions fixed at: ${mcpLogsDir}`); |
There was a problem hiding this comment.
In the else branch, chmodSync(mcpLogsDir, 0o777) is unconditional. If /tmp/gh-aw/mcp-logs already exists and is owned by a different user (e.g., created by a prior sudo run) but already has 0777, a non-root run will still throw EPERM here and fail the workflow unnecessarily. Consider stat’ing first and only chmod’ing when the mode isn’t already 0777, and handle EPERM with a clearer error or a non-fatal warning when permissions are already sufficient.
This issue also appears on line 872 of the same file.
| fs.chmodSync(mcpLogsDir, 0o777); | |
| logger.debug(`MCP logs directory permissions fixed at: ${mcpLogsDir}`); | |
| try { | |
| const stats = fs.statSync(mcpLogsDir); | |
| const currentMode = stats.mode & 0o777; | |
| if (currentMode !== 0o777) { | |
| try { | |
| fs.chmodSync(mcpLogsDir, 0o777); | |
| logger.debug(`MCP logs directory permissions fixed at: ${mcpLogsDir}`); | |
| } catch (err: any) { | |
| const code = (err as NodeJS.ErrnoException).code; | |
| if (code === 'EPERM') { | |
| logger.warn( | |
| `MCP logs directory exists at ${mcpLogsDir} but permissions could not be changed to 0o777 due to EPERM. ` + | |
| `Current mode is ${currentMode.toString(8)}.` | |
| ); | |
| } else { | |
| throw err; | |
| } | |
| } | |
| } else { | |
| logger.debug(`MCP logs directory permissions already set to 0o777: ${mcpLogsDir}`); | |
| } | |
| } catch (err) { | |
| logger.warn(`Unable to verify or adjust MCP logs directory permissions at ${mcpLogsDir}: ${err}`); | |
| } |
| @@ -1514,6 +1514,8 @@ describe('docker-manager', () => { | |||
| expect(fs.existsSync('/tmp/gh-aw/mcp-logs')).toBe(true); | |||
| const stats = fs.statSync('/tmp/gh-aw/mcp-logs'); | |||
| expect(stats.isDirectory()).toBe(true); | |||
| // Verify permissions are 0o777 (rwxrwxrwx) to allow non-root users to create subdirectories | |||
| expect((stats.mode & 0o777).toString(8)).toBe('777'); | |||
There was a problem hiding this comment.
This test writes to a global path (/tmp/gh-aw/mcp-logs) but doesn’t clean it up, which can make the test suite order/environment-dependent on developer machines or persistent runners. Consider removing /tmp/gh-aw/mcp-logs (and possibly /tmp/gh-aw if empty) in setup/teardown for this test, or mocking the fs calls so the test remains isolated.
…709) * Initial plan * fix: revert file approach, need directory solution for mcp-logs Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> * fix: use tmpfs to hide /tmp/gh-aw/mcp-logs directory from container Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> * test: verify tmpfs mount solution works end-to-end Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> * fix: use 0o777 permissions for mcp-logs and squid-logs directories (#710) * Initial plan * fix: set /tmp/gh-aw/mcp-logs to world-writable (0o777) Fixes permission denied error when GitHub Actions workflows try to create subdirectories in /tmp/gh-aw/mcp-logs after AWF runs with sudo. Changes: - Set directory permissions to 0o777 (rwxrwxrwx) instead of 0o755 - Explicitly call chmodSync after mkdirSync to bypass umask - Fix permissions if directory already exists from previous run - Update test to verify 777 permissions Root cause: When AWF runs with sudo (e.g., --enable-chroot), it creates /tmp/gh-aw/mcp-logs owned by root. With 755 permissions, non-root users cannot create subdirectories. Using 777 allows workflows to create subdirectories like /tmp/gh-aw/mcp-logs/safeoutputs without sudo. Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> * fix: ensure squid logs dir has 777 permissions Apply same fix to squidLogsDir for consistency with mcpLogsDir. Explicitly calls chmodSync to bypass umask effects. Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
* Initial plan * feat: hide /tmp/gh-aw/mcp-logs/ directory from agent container Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> * test: improve mcp-logs tests to verify mount protection * fix: create /tmp/gh-aw/mcp-logs before Docker mount (#707) * Initial plan * fix: create /tmp/gh-aw/mcp-logs directory before mounting Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> * test: add test for /tmp/gh-aw/mcp-logs directory creation Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> * fix: use tmpfs to hide /tmp/gh-aw/mcp-logs directory from containers (#709) * Initial plan * fix: revert file approach, need directory solution for mcp-logs Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> * fix: use tmpfs to hide /tmp/gh-aw/mcp-logs directory from container Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> * test: verify tmpfs mount solution works end-to-end Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> * fix: use 0o777 permissions for mcp-logs and squid-logs directories (#710) * Initial plan * fix: set /tmp/gh-aw/mcp-logs to world-writable (0o777) Fixes permission denied error when GitHub Actions workflows try to create subdirectories in /tmp/gh-aw/mcp-logs after AWF runs with sudo. Changes: - Set directory permissions to 0o777 (rwxrwxrwx) instead of 0o755 - Explicitly call chmodSync after mkdirSync to bypass umask - Fix permissions if directory already exists from previous run - Update test to verify 777 permissions Root cause: When AWF runs with sudo (e.g., --enable-chroot), it creates /tmp/gh-aw/mcp-logs owned by root. With 755 permissions, non-root users cannot create subdirectories. Using 777 allows workflows to create subdirectories like /tmp/gh-aw/mcp-logs/safeoutputs without sudo. Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> * fix: ensure squid logs dir has 777 permissions Apply same fix to squidLogsDir for consistency with mcpLogsDir. Explicitly calls chmodSync to bypass umask effects. Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
- Add --allow-full-filesystem-access flag to docs/usage.md - Add link to docs/selective-mounting.md in README.md - Update AGENTS.md container architecture to reflect selective mounting default - Update docs/architecture.md with security features: - Selective mounting and credential protection - One-shot token library (LD_PRELOAD) - MCP logs directory protection Changes sync documentation with code from PRs: - #681 (selective mounting) - #706, #709, #710 (mcp-logs hiding) - #604, #640 (one-shot token library)
GitHub Actions workflows fail with "Permission denied" when creating subdirectories in
/tmp/gh-aw/mcp-logs/safeoutputsafter AWF runs with sudo. The directory is created by root with 755 permissions, preventing non-root workflow steps from writing.Changes
chmodSync(): Bypasses umask (0002) which would reduce 0o777 to 0o775/tmp/gh-aw/mcp-logs) and squidLogsDir for consistencyImplementation
Safe for these temp log directories: already in
/tmp, hidden from AWF container via tmpfs, no sensitive data.💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.