feat: require explicit Cloud Hypervisor tool-cache mounts - #7888
Conversation
Default preview mounts to workspace-only exposure. Require an explicit, fail-closed opt-in before mounting the runner tool cache read-only. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Tool-cache exports can remain writable through nested mounts or overlapping writable source aliases.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Balanced
Findings: 2
New issues introduced by this change (2)
| Severity | Finding |
|---|---|
src/cloud-hypervisor/exports.ts — The opt-in can still expose writable descendants of the tool cache. With the normal… |
|
src/cloud-hypervisor/exports.ts — Please reject canonical source overlap between this read-only cache and writable exports. For… |
What changed in this PR
Introduces explicit Cloud Hypervisor mount policies, making workspace-only exposure the default and tool-cache mounting opt-in.
Changes:
- Adds CLI, configuration, schema, and type support for mount policies.
- Restricts tool-cache exports and runner environment forwarding.
- Documents migration behavior and adds validation tests.
| File | Description |
|---|---|
src/types/runtime-options.ts |
Defines mount-policy types and defaults. |
src/types/index.ts |
Exports the new policy API. |
src/schema.test.ts |
Tests schema policy validation. |
src/config-mapper.ts |
Maps config policy to CLI options. |
src/config-file.ts |
Adds the config-file property. |
src/commands/build-config.ts |
Parses, validates, and defaults policies. |
src/cloud-hypervisor/vm-config-builder.test.ts |
Updates test configuration. |
src/cloud-hypervisor/runtime-validation.ts |
Adds runtime policy validation. |
src/cloud-hypervisor/runtime-validation.test.ts |
Tests invalid runtime policies. |
src/cloud-hypervisor/preflight.test.ts |
Updates preflight fixtures. |
src/cloud-hypervisor/manager.test.ts |
Updates manager fixtures. |
src/cloud-hypervisor/exports.ts |
Implements policy-controlled exports. |
src/cloud-hypervisor/exports.test.ts |
Tests secure defaults and opt-in behavior. |
src/cloud-hypervisor/config.test.ts |
Tests mapping, defaults, and validation. |
src/cloud-hypervisor-runtime-backend.ts |
Passes policy into export resolution. |
src/cloud-hypervisor-runtime-backend.test.ts |
Tests policy propagation and environment filtering. |
src/cli-options.ts |
Adds the mount-policy flag. |
src/cli-options.test.ts |
Tests CLI parsing. |
src/awf-config-schema.json |
Updates the runtime schema copy. |
docs/cloud-hypervisor-foundation.md |
Documents behavior and migration. |
docs/awf-config.schema.json |
Adds the canonical schema property. |
docs/awf-config-spec.md |
Documents configuration semantics. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
| Metric | Base | PR | Delta |
|---|---|---|---|
| Lines | 93.86% | 93.90% | 📈 +0.04% |
| Statements | 92.67% | 92.71% | 📈 +0.04% |
| Functions | 93.24% | 93.13% | 📉 -0.11% |
| Branches | 86.14% | 86.22% | 📈 +0.08% |
📁 Per-file Coverage Changes (3 files)
| File | Lines (Before → After) | Statements (Before → After) |
|---|---|---|
src/commands/build-config.ts |
90.0% → 90.7% (+0.74%) | 90.4% → 91.1% (+0.69%) |
src/cloud-hypervisor/exports.ts |
89.7% → 91.8% (+2.08%) | 86.1% → 88.3% (+2.20%) |
src/log-directory-setup.ts |
96.2% → 100.0% (+3.78%) | 96.3% → 100.0% (+3.71%) |
Coverage comparison generated by scripts/ci/compare-coverage.ts
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
Tool-cache submounts can remain writable unless recursive host-side enforcement is always applied.
Review tier: Balanced
Findings: 2
Pre-existing issues (2)
| Severity | Finding |
|---|---|
src/cloud-hypervisor/exports.ts — Please reject canonical source overlap between this read-only cache and writable exports. For… View comment |
|
src/cloud-hypervisor/exports.ts — The opt-in can still expose writable descendants of the tool cache. With the normal… View comment |
Suppressed comments (1)
src/cloud-hypervisor/exports.ts:79
- The tool-cache is not guaranteed to be read-only when
filesystem.allowWriteis unset. Thismode: 'ro'takes virtiofsd's legacy--bind+ root-only remount path; nested host mounts remain independently writable. The code already documents this limitation infilesystem-write-enforcement.ts:79-82, while recursive mount-tree staging is only produced whenfilesystem.allowWriteis configured. Ensure the opt-in tool-cache export always receives a recursive read-only mount plan, even with the default undefined write policy, so a carried-in submount cannot give the guest write access.
candidates.push({
tag: 'runner-tool-cache',
source: toolCache,
target: toolCache,
mode: 'ro',
required: true,
Recursively stage tool-cache submounts and reject writable source aliases. Add focused regression tests and restore function coverage above the base branch. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
✅ Copilot review passed with no inline comments. @lpcox Add the |
✅ Coverage Check PassedOverall Coverage
📁 Per-file Coverage Changes (4 files)
Coverage comparison generated by |
|
📰 VERDICT: Smoke Docker Sbx has concluded. All systems operational. This is a developing story. 🎤
|
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤
|
|
🔌 Smoke Services — All services reachable! ✅
|
|
🚀 Security Guard has started processing this pull request |
|
🛡️ 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.
|
|
✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟 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
- "msfeed25.pkgs.visualstudio.com"
- "registry.npmjs.org"See Network Configuration for more information.
|
|
❌ Smoke Gemini reports failed. Facets need polishing...
|
|
✅ Contribution Check completed successfully! Contribution check complete for PR #7888: the PR includes tests for the new Cloud Hypervisor mount-policy behavior, updates the relevant documentation, and the new config/code lives in the expected src/ and docs/ locations. No CONTRIBUTING.md issues to flag.
|
|
✅ 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 OTel Tracing completed. All tracing scenarios validated. ✅
|
|
✅ Smoke Copilot BYOK AOAI (api-key) completed. Copilot AOAI BYOK (api-key) mode operational. 🔓
|
|
Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded.
|
|
✅ Smoke Copilot BYOK completed. Copilot BYOK mode operational. 🔓
|
|
✅ Build Test Suite completed successfully!
|
|
✅ Smoke Copilot BYOK AOAI (Entra) completed. Copilot AOAI BYOK (Entra) mode operational. 🔓
|
|
📰 VERDICT: Smoke Docker Sbx has concluded. All systems operational. This is a developing story. 🎤
|
|
🔌 Smoke Services — All services reachable! ✅
|
|
❌ Smoke Gemini reports failed. Facets need polishing...
|
|
📡 Smoke OTel Tracing completed. All tracing scenarios validated. ✅
|
|
❌ Contribution Check failed. Please review the logs for details.
|
|
✅ Build Test Suite completed successfully!
|
|
EGRESS_RESULT allow=pass deny=pass ✅ Allowed domain (github.com) reachable: Overall status: PASS cc @lpcox 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 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 BYOK (Direct) Mode ✅Status: PASS — Running in direct BYOK mode (COPILOT_PROVIDER_API_KEY) via api-proxy → api.githubcopilot.com
All BYOK components working correctly.
|
|
Smoke Test: Copilot Engine — PASS
PR: "feat: require explicit Cloud Hypervisor tool-cache mounts" (#7888) @lpcox — all checks green.
|
|
Smoke Test: Docker Sbx Validation
Overall: PASS cc @lpcox
|
|
Smoke Test Results — GitHub Actions Services Connectivity
Overall: FAIL —
|
Chroot Version Comparison Results
Overall: FAILED — Node.js version mismatch between host (
|
Smoke Test: API Proxy OTEL Tracing — Results
Overall: All scenarios passed / expected-pending. No errors detected in OTEL init, span creation, env propagation, or export pipeline.
|
|
Merged: "fix: filter workflow commands from microVM output"; "fix: drop CAP_NET_ADMIN from Cloud Hypervisor VMM" 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
- "msfeed25.pkgs.visualstudio.com"
- "registry.npmjs.org"See Network Configuration for more information.
|
|
@lpcox
|
🏗️ Build Test Suite Results
Overall: 8/8 ecosystems passed — ✅ PASS Notes:
|
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)
|

Summary
workspace-onlypolicy instead of automatically exposingRUNNER_TOOL_CACHEworkspace-and-tool-cachepolicy through CLI and config schema, with strict validation and mandatory host-side read-only stagingRUNNER_TOOL_CACHE,AGENT_TOOLSDIRECTORY, andRUNNER_TEMPonly when their corresponding narrow exports are mountedBehavior change and migration
Earlier preview builds automatically exported the full runner tool cache whenever
RUNNER_TOOL_CACHEorAGENT_TOOLSDIRECTORYwas present. The secure default is nowworkspace-only; narrow gh-aw runtime directories remain available when present.Workflows that execute or scan runner-installed tools must explicitly add:
or set
cloudHypervisor.mountPolicytoworkspace-and-tool-cache. gh-aw generators that emit commands referencingRUNNER_TOOL_CACHEshould emit this opt-in. Missing cache variables, nonexistent paths, and unknown policy values fail closed.Validation
npm test -- --runInBand src/cloud-hypervisor/exports.test.ts src/cloud-hypervisor/config.test.ts src/cloud-hypervisor/runtime-validation.test.ts src/cloud-hypervisor-runtime-backend.test.ts src/cloud-hypervisor/virtiofsd.test.ts src/schema.test.ts src/cli-options.test.ts(155 tests)npm run buildnpm run lint --if-present(passes with existing warnings)