Log the resolved filesystem.allowWrite boundary before the Cloud Hypervisor guest boots - #7819
Conversation
There was a problem hiding this comment.
Pull request overview
Adds pre-boot diagnostics for Cloud Hypervisor filesystem write boundaries to explain EROFS failures.
Changes:
- Derives and logs effective per-export write boundaries.
- Adds unit coverage for restricted and unrestricted policies.
- Documents
filesystem.allowWritetroubleshooting and requirements.
Show a summary per file
| File | Description |
|---|---|
src/cloud-hypervisor/filesystem-write-policy.ts |
Adds boundary summarization. |
src/cloud-hypervisor/filesystem-write-policy.test.ts |
Tests summary formats. |
src/cloud-hypervisor/filesystem-write-enforcement.ts |
Exposes the resolved boundary. |
src/cloud-hypervisor/filesystem-write-enforcement.test.ts |
Tests enforcement summaries. |
src/cloud-hypervisor-runtime-backend.ts |
Logs the boundary before boot. |
src/cloud-hypervisor-runtime-backend.test.ts |
Tests logging and silence when unrestricted. |
docs/troubleshooting.md |
Adds EROFS troubleshooting guidance. |
docs/awf-config-spec.md |
Documents caller-owned writable paths. |
Review details
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Files reviewed: 8/8 changed files
- Comments generated: 2
- Review effort level: Balanced
| `[cloud-hypervisor] stage=filesystem-write-policy boundary ${writeBoundary.join(' ')} ` + | ||
| '(writes outside these paths fail with EROFS; widen filesystem.allowWrite to permit them)', |
| **Cause:** AWF does not mount any `/tmp` subdirectory read-only on its own. A | ||
| read-only view of such a path comes from a `filesystem.allowWrite` policy in the | ||
| AWF config file: when that key is present, every writable host mount is narrowed | ||
| to the listed guest-visible paths and everything else becomes read-only (see | ||
| [awf-config-spec.md §4.1](./awf-config-spec.md#41-filesystem-write-boundary)). |
|
@copilot address review feedback |
|
✅ Copilot review passed with no inline comments. @copilot Add the |
|
🛡️ 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.
|
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤
|
|
❌ Smoke Copilot BYOK AOAI (api-key) reports failed. AOAI BYOK (api-key) mode investigation needed...
|
|
🔌 Smoke Services — All services reachable! ✅
|
|
✅ Build Test Suite completed successfully!
|
|
Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded.
|
|
📰 VERDICT: Smoke Docker Sbx has concluded. All systems operational. This is a developing story. 🎤
|
|
❌ Smoke Copilot BYOK AOAI (Entra) reports failed. AOAI BYOK (Entra) mode investigation needed...
|
|
✅ Contribution Check completed successfully! PR #7819 follows CONTRIBUTING.md: it includes tests for the new boundary-summary behavior and updates docs for the new EROFS troubleshooting guidance. The PR description is clear and references the related issue (#7811). No contribution-guidelines issues found.
|
|
📡 Smoke OTel Tracing completed. All tracing scenarios validated. ✅
|
|
❌ Smoke Gemini reports failed. Facets need polishing...
|
|
✅ Smoke Claude passed
|
|
🚀 Security Guard has started processing this pull request |
|
✅ Smoke Copilot BYOK completed. Copilot BYOK mode operational. 🔓
|
|
✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟 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
- "registry.npmjs.org"See Network Configuration for more information.
|
|
Smoke Test: Docker Sbx —
Overall: PASS
|
|
Smoke Test Results
Overall: PASS
|
Smoke Test: Copilot BYOK (Direct) Mode ✅
Mode: Direct BYOK (COPILOT_PROVIDER_API_KEY) via api-proxy → api.githubcopilot.com Status: PASS
|
|
EGRESS_RESULT allow=pass deny=pass ✅ Allowed domain (github.com) reachable: Overall status: PASS cc 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.
|
Smoke Test: Claude Engine Validation
Overall result: PASS
|
Chroot Version Comparison
Result: Not all versions matched (Node.js differs), so the
|
|
Smoke Test: GitHub Actions Services Connectivity
Overall: FAIL —
|
|
PR titles: unavailable ( 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
- "registry.npmjs.org"See Network Configuration for more information.
|
🏗️ Build Test Suite Results
Overall: 8/8 ecosystems passed — PASS Notes:
|
Smoke Test: API Proxy OpenTelemetry Tracing — Results
Overall: ✅ Pass — module, tests, wiring, and hook points all validated; no unexpected errors or regressions. Span export path itself was not exercised because no OTLP collector endpoint was configured for this run (expected during development / not yet enabled here).
|
An agent could not persist repo-memory: writes to
/tmp/gh-aw/repo-memory/default/failed withEROFSand no indication of why. AWF does not mount that path read-only —/tmpis bound read-write inbuildWorkspaceMounts(). The read-only view came from the caller'sfilesystem.allowWritepolicy, which the failing run emitted as:/tmp/gh-awis one virtio-fs export; under a policy its host backing tree is staged read-only with writable overlays only for listed paths, sorepo-memoryis correctly read-only. Widening the allowlist belongs to the gh-aw compiler (as was done forcache-memory). What is missing on the AWF side is any way to see the boundary, so the failure surfaced as a bareEROFS.Changes
src/cloud-hypervisor/filesystem-write-policy.ts— adds puresummarizeCloudHypervisorFilesystemWriteBoundary(plan), rendering one line per export from the existing plan (writable/read-only/selectivewith named overlays). Returns[]when unrestricted.src/cloud-hypervisor/filesystem-write-enforcement.ts— surfaces the summary aswriteBoundary. The unrestricted return still omits themountEnforcementkey, so legacy virtiofsd staging stays byte-identical.src/cloud-hypervisor-runtime-backend.ts— logs the boundary once at the existingfilesystem-write-policystage, before virtiofsd, the VMM, or the guest start:docs/troubleshooting.md— new "Read-Only Filesystem (EROFS) Inside the Sandbox" entry under Permission Issues, using repo-memory as the worked example and noting that gh-aw-launched runs must declare the path insandbox.agent.config.filesystem.allowWrite.docs/awf-config-spec.md§4.1 — states that caller-owned directories under/tmp/gh-aw(e.g./tmp/gh-aw/repo-memory) must appear inallowWrite, and that the boundary is reported before boot.Notes for reviewers
No behavioral change to mounting or policy enforcement — only a derived summary and one log line. Tests cover the summary shape, the unrestricted (silent) case, and the backend log line.