Mount the configured container working directory when no other mount exposes it - #8021
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Hidden paths can be exposed through parent-directory mounts or symlink aliases.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds automatic mounting for configured working directories not otherwise visible inside the sandbox.
Changes:
- Adds workdir mount and safety checks.
- Adds unit and integration coverage.
- Documents working-directory behavior.
File summaries
| File | Description |
|---|---|
src/services/agent-volumes/workspace-mounts.ts |
Builds fallback workdir mounts. |
src/services/agent-volumes/workspace-mounts.test.ts |
Tests mount and refusal behavior. |
tests/integration/container-workdir.test.ts |
Verifies external workdirs end-to-end. |
docs/usage.md |
Documents workdir guarantees and exceptions. |
Review details
Suppressed comments (2)
src/services/agent-volumes/workspace-mounts.ts:150
- This warning is inaccurate when an explicit
--mountalready exposes the hidden target: the helper declines only the automatic mount, whilebuildCustomVolumeMounts()still adds the caller's mount and the agent can start there as documented. Avoid claiming that the path will not be mounted or that startup will fall back to/.
`Container working directory ${workDir} is inside a host path that AWF deliberately hides from ` +
'the sandbox; it will not be mounted and the agent will start in / instead'
src/services/agent-volumes/workspace-mounts.ts:159
statSyncfollows symlinks, but the hidden-root check only examines the lexical path. A workdir such as/srv/checkout -> /home/runner/.sshtherefore passes validation and the bind source can expose the hidden directory. Resolve the source withrealpathSync, apply the hidden-root overlap check to the canonical path, and mount that canonical source so the alias cannot be retargeted between validation and mount construction.
if (!isExistingDirectory(workDir)) {
- Files reviewed: 4/4 changed files
- Comments generated: 3
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
✅ Copilot review passed with no inline comments. @copilot Add the |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤
|
|
✅ Smoke Copilot BYOK AOAI (Entra) completed. Copilot AOAI BYOK (Entra) mode operational. 🔓
|
|
✅ Smoke Copilot BYOK completed. Copilot BYOK mode operational. 🔓
|
|
📰 VERDICT: Smoke Docker Sbx has concluded. All systems operational. This is a developing story. 🎤
|
|
✅ Smoke Copilot BYOK AOAI (api-key) completed. Copilot AOAI BYOK (api-key) mode operational. 🔓
|
|
❌ Smoke Gemini reports failed. Facets need polishing...
|
|
🛡️ Smoke Copilot Network Isolation confirmed the egress allowlist is enforced. ✅ 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
- "example.com"See Network Configuration for more information.
|
|
Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded.
|
|
📡 Smoke OTel Tracing completed. All tracing scenarios validated. ✅
|
|
❌ Contribution Check failed. Please review the logs for details.
|
|
✅ Build Test Suite completed successfully!
|
|
✅ 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.
|
|
Smoke Test: Copilot Engine —
Overall: PASS
|
|
Smoke Test Results: Copilot BYOK (Direct Mode) ✅ MCP Connectivity — PRs fetched successfully Overall Status: PASS Recent merged PRs: #8026, #8004
|
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: Services Connectivity
Overall: FAIL —
|
|
Smoke Test: Docker Sbx —
Overall: PASS
|
|
EGRESS_RESULT allow=pass deny=pass ✅ Allowed domain (github.com) reachable: Overall status: 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
- "example.com"See Network Configuration for more information.
|
|
GitHub MCP connectivity: ❌ Running in direct BYOK mode (COPILOT_PROVIDER_API_KEY + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw)
|
Chroot Version Comparison Results
Overall: FAILED — Node.js version mismatch between host and chroot environment.
|
|
Smoke test: FAIL Merged PR titles: Warning Firewall blocked 7 domainsThe following domains were blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "accounts.google.com"
- "android.clients.google.com"
- "clients2.google.com"
- "contentautofill.googleapis.com"
- "msfeed25.pkgs.visualstudio.com"
- "www.google.com"
- "www.gstatic.com"See Network Configuration for more information.
|
|
test: validate shared-gateway enclave smoke, chore: upgrade gh-aw workflows to v0.88.0 — ❌ Running in direct BYOK mode (AWF_AUTH_TYPE=github-oidc + AWF_AUTH_AZURE_* + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw) authenticated via Microsoft Entra
|
Smoke Test: API Proxy OpenTelemetry Tracing — Results
Overall: 4/5 scenarios pass; Scenario 5 is expected-pending (no api-proxy traffic occurred in this run).
|
🏗️ Build Test Suite Results
Overall: 8/8 ecosystems passed — PASS Notes:
|
A codex-engine run under AWF aborted after the agent could not
cdinto/home/runner/work/gh-aw/gh-aw, then re-discovered its context until the context-rebuild circuit breaker tripped. AWF sets the agent CWD from--container-workdir, but nothing guarantees that path exists inside the chroot: if it isn't covered by the workspace mount (derived fromGITHUB_WORKSPACE/cwd at AWF launch, which can differ from the requested workdir),/tmp, a system mount, a$HOMEtool mount, or an explicit--mount,entrypoint.shsilently falls back to/.Changes
src/services/agent-volumes/workspace-mounts.ts— newbuildContainerWorkDirMounts(), called frombuildWorkspaceMounts():<workdir>:<workdir>:rwand<workdir>:/host<workdir>:rwwhen the configured workdir is not already reachable inside the chroot, so the in-container path matches the host path the engine was told to use./tmp,systemDirectories(), aHOME_TOOL_PATHSmount, a custom--mounttarget,$HOMEitself, or/.~/.ssh,~/.aws, …) plus/etc,/root,/proc,/run,/boot,/var/run— so--container-workdir ~/.sshcannot be used to defeat credential hiding. Checked before coverage so a broad tool mount can't shadow the rule./fallback with an actionable log line.tests/integration/container-workdir.test.tsthat runs with a workdir outside every default mount (verified failing without the change).docs/usage.md— new "Working Directory" section describing the guarantee and the two warn-only cases.Sandbox mount surface is unchanged unless a caller explicitly asks for a workdir that AWF was previously unable to provide.