Skip to content

feat: require explicit Cloud Hypervisor tool-cache mounts - #7888

Merged
lpcox merged 3 commits into
mainfrom
lpcox-explicit-tool-cache-mounts
Aug 31, 2026
Merged

feat: require explicit Cloud Hypervisor tool-cache mounts#7888
lpcox merged 3 commits into
mainfrom
lpcox-explicit-tool-cache-mounts

Conversation

@lpcox

@lpcox lpcox commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • default Cloud Hypervisor preview exports to the workspace-only policy instead of automatically exposing RUNNER_TOOL_CACHE
  • add an explicit workspace-and-tool-cache policy through CLI and config schema, with strict validation and mandatory host-side read-only staging
  • forward RUNNER_TOOL_CACHE, AGENT_TOOLSDIRECTORY, and RUNNER_TEMP only when their corresponding narrow exports are mounted
  • document the preview behavior change and gh-aw generator migration

Behavior change and migration

Earlier preview builds automatically exported the full runner tool cache whenever RUNNER_TOOL_CACHE or AGENT_TOOLSDIRECTORY was present. The secure default is now workspace-only; narrow gh-aw runtime directories remain available when present.

Workflows that execute or scan runner-installed tools must explicitly add:

--cloud-hypervisor-mount-policy workspace-and-tool-cache

or set cloudHypervisor.mountPolicy to workspace-and-tool-cache. gh-aw generators that emit commands referencing RUNNER_TOOL_CACHE should 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 build
  • npm run lint --if-present (passes with existing warnings)

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>
Copilot AI balanced review requested due to automatic review settings August 31, 2026 14:25
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Documentation Preview

Documentation build failed for this PR. View logs.

Built from commit 14e749f

@lpcox lpcox changed the title Require explicit Cloud Hypervisor tool-cache mounts feat: require explicit Cloud Hypervisor tool-cache mounts Aug 31, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 High severity

New issues introduced by this change (2)
Severity Finding
High severity src/​cloud-hypervisor/​exports.ts — The opt-in can still expose writable descendants of the tool cache. With the normal…
High severity 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.

Comment thread src/cloud-hypervisor/exports.ts
Comment thread src/cloud-hypervisor/exports.ts
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Coverage Regression Detected

This PR decreases test coverage. Please add tests to maintain coverage levels.

Overall Coverage

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

@lpcox
lpcox requested a balanced review from Copilot August 31, 2026 14:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 High severity

Pre-existing issues (2)
Severity Finding
High severity src/​cloud-hypervisor/​exports.ts — Please reject canonical source overlap between this read-only cache and writable exports. For… View comment
High severity 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.allowWrite is unset. This mode: 'ro' takes virtiofsd's legacy --bind + root-only remount path; nested host mounts remain independently writable. The code already documents this limitation in filesystem-write-enforcement.ts:79-82, while recursive mount-tree staging is only produced when filesystem.allowWrite is 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>
@github-actions

Copy link
Copy Markdown
Contributor

✅ Copilot review passed with no inline comments.

@lpcox Add the ready-for-aw label to this PR to trigger agentic CI smoke tests.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Coverage Check Passed

Overall Coverage

Metric Base PR Delta
Lines 93.86% 93.92% 📈 +0.06%
Statements 92.67% 92.75% 📈 +0.08%
Functions 93.24% 93.32% 📈 +0.08%
Branches 86.14% 86.26% 📈 +0.12%
📁 Per-file Coverage Changes (4 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/virtiofsd.ts 77.7% → 79.0% (+1.35%) 74.8% → 77.3% (+2.51%)
src/cloud-hypervisor/exports.ts 89.7% → 92.5% (+2.80%) 86.1% → 89.4% (+3.30%)
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

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

📰 VERDICT: Smoke Docker Sbx has concluded. All systems operational. This is a developing story. 🎤

📰 BREAKING: Report filed by Smoke Docker Sbx

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

📰 BREAKING: Report filed by Smoke Copilot

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

🔌 Smoke Services — All services reachable! ✅

🔌 Service connectivity validated by Smoke Services

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Security Guard has started processing this pull request

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

🛡️ Smoke Copilot Network Isolation confirmed the egress allowlist is enforced. ✅

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • example.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "example.com"

See Network Configuration for more information.

🛡️ Egress verdict from Smoke Copilot Network Isolation

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

Warning

Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • msfeed25.pkgs.visualstudio.com
  • registry.npmjs.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "msfeed25.pkgs.visualstudio.com"
    - "registry.npmjs.org"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Smoke Gemini reports failed. Facets need polishing...

💎 Faceted by Smoke Gemini

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

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.

Generated by Contribution Check for #7888

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Smoke Claude passed

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • api.anthropic.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "api.anthropic.com"

See Network Configuration for more information.

Generated by Smoke Claude for #7888

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

📡 Smoke OTel Tracing completed. All tracing scenarios validated. ✅

📡 OTel tracing validated by Smoke OTel Tracing

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Smoke Copilot BYOK AOAI (api-key) completed. Copilot AOAI BYOK (api-key) mode operational. 🔓

🔑 BYOK (AOAI api-key) report filed by Smoke Copilot BYOK AOAI (api-key)

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded.

Tested by Smoke Chroot

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Smoke Copilot BYOK completed. Copilot BYOK mode operational. 🔓

🔑 BYOK report filed by Smoke Copilot BYOK

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Build Test Suite completed successfully!

Generated by Build Test Suite for #7888

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Smoke Copilot BYOK AOAI (Entra) completed. Copilot AOAI BYOK (Entra) mode operational. 🔓

🪪 BYOK (AOAI Entra) report filed by Smoke Copilot BYOK AOAI (Entra)

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

📰 VERDICT: Smoke Docker Sbx has concluded. All systems operational. This is a developing story. 🎤

📰 BREAKING: Report filed by Smoke Docker Sbx

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

🔌 Smoke Services — All services reachable! ✅

🔌 Service connectivity validated by Smoke Services

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Smoke Gemini reports failed. Facets need polishing...

💎 Faceted by Smoke Gemini

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

📡 Smoke OTel Tracing completed. All tracing scenarios validated. ✅

📡 OTel tracing validated by Smoke OTel Tracing

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Contribution Check failed. Please review the logs for details.

Generated by Contribution Check for #7888

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Build Test Suite completed successfully!

Generated by Build Test Suite for #7888

@github-actions github-actions Bot added the smoke-copilot-network-isolation Copilot network-isolation egress smoke test label Aug 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

EGRESS_RESULT allow=pass deny=pass

✅ Allowed domain (github.com) reachable: allowed=200
✅ Non-allowed domain (example.com) blocked: CONNECT tunnel failed 403

Overall status: PASS

cc @lpcox

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • example.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "example.com"

See Network Configuration for more information.

🛡️ Egress verdict from Smoke Copilot Network Isolation
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Claude Engine Validation

Check Status
API ✅ PASS
gh CLI ✅ PASS
File ✅ PASS

Overall result: PASS

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • api.anthropic.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "api.anthropic.com"

See Network Configuration for more information.

Generated by Smoke Claude for #7888 · claude · haiku45 · 32.8 AIC · ⊞ 4.5K ·
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Copilot BYOK (Direct) Mode ✅

Status: PASS — Running in direct BYOK mode (COPILOT_PROVIDER_API_KEY) via api-proxy → api.githubcopilot.com

Test Result
GitHub MCP connectivity
GitHub.com HTTP code ✅ 200
File write/read
BYOK inference

All BYOK components working correctly.

🔑 BYOK report filed by Smoke Copilot BYOK
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Copilot Engine — PASS

PR: "feat: require explicit Cloud Hypervisor tool-cache mounts" (#7888)

@lpcox — all checks green.

📰 BREAKING: Report filed by Smoke Copilot
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Docker Sbx Validation

Overall: PASS

cc @lpcox

📰 BREAKING: Report filed by Smoke Docker Sbx
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test Results — GitHub Actions Services Connectivity

  • Redis PING: ❌ (Temporary failure in name resolution)
  • PostgreSQL pg_isready: ❌ (no response)
  • PostgreSQL SELECT 1: ❌ (could not translate host name)

Overall: FAILhost.docker.internal cannot be resolved from the AWF sandbox.

🔌 Service connectivity validated by Smoke Services
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.14 Python 3.12.14 ✅ YES
Node.js v24.19.0 v2.97.0 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

Overall: FAILED — Node.js version mismatch between host (v24.19.0) and chroot (v2.97.0) environments. Not adding the smoke-chroot label since not all tests passed.

Tested by Smoke Chroot
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: API Proxy OTEL Tracing — Results

  • Scenario 1 (Module Loading): otel.js loads cleanly, exports startRequestSpan, setTokenAttributes, setBudgetAttributes, endSpan, endSpanError, shutdown, isEnabled, plus exporter internals (_ProxyAwareOtlpExporter, _FileSpanExporter, _FanOutSpanExporter, _parseEndpoints, _parseOtlpHeaders, _buildResourceSpans, _createOtlpWorkloadIdentity).
  • Scenario 2 (Test Suite): otel.test.js, otel-fanout.test.js, otel-workload-identity.test.js → 3 suites, 68/68 tests passed.
  • Scenario 3 (Env Var Forwarding): env-passthrough.ts forwards GITHUB_AW_OTEL_TRACE_ID / GITHUB_AW_OTEL_PARENT_SPAN_ID (plus COPILOT_OTEL_FILE_EXPORTER_PATH) into the agent container; api-proxy-env-config.ts forwards OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, GITHUB_AW_OTEL_TRACE_ID, GITHUB_AW_OTEL_PARENT_SPAN_ID, OTEL_SERVICE_NAME into the api-proxy container.
  • Scenario 4 (Token Tracker Integration): token-tracker-http.js accepts an onUsage(normalizedUsage, model) callback (and onSpanEnd), confirmed as the OTEL hook point where normalized token usage is fed to span attributes.
  • Scenario 5 (OTEL Diagnostics): /tmp/gh-aw/otel.jsonl contains 1 exported span (gh-aw.agent.setup, workflow-level trace) — export path works end-to-end; no api-proxy request spans were present since api-proxy wasn't exercised with live LLM traffic in this run (expected, no --enable-api-proxy request made).

Overall: All scenarios passed / expected-pending. No errors detected in OTEL init, span creation, env propagation, or export pipeline.

📡 OTel tracing validated by Smoke OTel Tracing
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Merged: "fix: filter workflow commands from microVM output"; "fix: drop CAP_NET_ADMIN from Cloud Hypervisor VMM"
PR query: "feat: add durable identity-validated microVM cleanup"; "feat: isolate Cloud Hypervisor with per-run VMM identities"
GitHub review: ✅
safeinputs-gh query: ❌
Playwright title check: ✅
File write/readback: ✅
Discussion interaction: ❌
Build (npm ci && npm run build): ✅
Overall: FAIL

Warning

Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • msfeed25.pkgs.visualstudio.com
  • registry.npmjs.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "msfeed25.pkgs.visualstudio.com"
    - "registry.npmjs.org"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

@lpcox
fix: drop CAP_NET_ADMIN from Cloud Hypervisor VMM
docs: add B28 runner-doctor coverage for private-CA api-proxy TLS failures
GitHub MCP Testing: ❌
GitHub.com Connectivity: ✅
File I/O Test: ✅
BYOK Inference Test: ✅
Running in direct BYOK mode (COPILOT_PROVIDER_API_KEY + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw)
Overall: FAIL

🔑 BYOK (AOAI api-key) report filed by Smoke Copilot BYOK AOAI (api-key)
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Build Test Suite Results

Ecosystem Project Build/Install Tests Status
Bun elysia 1/1 passed ✅ PASS
Bun hono 1/1 passed ✅ PASS
C++ fmt N/A ✅ PASS
C++ json N/A ✅ PASS
Deno oak N/A 1/1 passed ✅ PASS
Deno std N/A 1/1 passed ✅ PASS
.NET hello-world N/A ✅ PASS
.NET json-parse N/A ✅ PASS
Go color ok ✅ PASS
Go env ok ✅ PASS
Go uuid ok ✅ PASS
Java gson 1/1 passed ✅ PASS
Java caffeine 1/1 passed ✅ PASS
Node.js clsx all passed ✅ PASS
Node.js execa all passed ✅ PASS
Node.js p-limit all passed ✅ PASS
Rust fd 1/1 passed ✅ PASS
Rust zoxide 1/1 passed ✅ PASS

Overall: 8/8 ecosystems passed — ✅ PASS

Notes:

  • Maven required a workaround: /home/runner/.m2 was read-only (owned by root), so a custom -s settings.xml with <localRepository> pointing to a writable path was used instead of the default ~/.m2.
  • All 18 test projects across all 8 ecosystems built/installed and ran their test suites successfully with no failures.

Generated by Build Test Suite for #7888 · copilot · auto · 42.2 AIC · ⊞ 12K ·
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

@lpcox

  • GitHub MCP Testing: ❌
  • GitHub.com Connectivity: ✅
  • File Write/Read Test: ✅
  • BYOK Inference Test: ✅

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)
Overall: FAIL

🪪 BYOK (AOAI Entra) report filed by Smoke Copilot BYOK AOAI (Entra)
Add label ready-for-aw to run again

@lpcox
lpcox merged commit 6804428 into main Aug 31, 2026
166 of 168 checks passed
@lpcox
lpcox deleted the lpcox-explicit-tool-cache-mounts branch August 31, 2026 16:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants