Skip to content

fix: drop CAP_NET_ADMIN from Cloud Hypervisor VMM - #7887

Merged
lpcox merged 1 commit into
mainfrom
lpcox-zero-cap-vmm
Aug 31, 2026
Merged

fix: drop CAP_NET_ADMIN from Cloud Hypervisor VMM#7887
lpcox merged 1 commit into
mainfrom
lpcox-zero-cap-vmm

Conversation

@lpcox

@lpcox lpcox commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • launch Cloud Hypervisor with empty inheritable, permitted, effective, bounding, and ambient capability sets while retaining only the /dev/kvm supplementary group
  • rely on the pre-created, VMM-owned, vnet_hdr TAP and narrow Landlock access from the TAP sysfs directory to only tun_flags
  • update focused unit and live-KVM assertions to require zero capabilities

Security rationale

This closes the capability gap with github/agent-microvm v0.9.0 at commit 9ca223049a3af490df168cbb74233ab438aceefb. The prior launcher retained CAP_NET_ADMIN because a vm.boot Landlock denial reading TAP flags was attributed to TAP configuration. AWF already creates, configures, owns, and brings up the TAP before launching the VMM. Granting read-only access to its tun_flags attribute lets Cloud Hypervisor reopen the TAP without a capability. A compromised VMM can no longer reconfigure namespace interfaces or firewall policy, and a zero bounding set prevents capability recovery.

Validation

  • npm test -- --runInBand src/cloud-hypervisor/launcher.test.ts src/cloud-hypervisor/vm-config-builder.test.ts src/microvm/network.test.ts scripts/ci/cloud-hypervisor-ci-scripts.test.ts (74 tests passed)
  • npm run build
  • npm run type-check
  • bash -n scripts/ci/cloud-hypervisor-live-smoke.sh
  • targeted ESLint (0 errors; existing warnings only)

Pre-create and own the TAP for the VMM identity.

Narrow Landlock access to tun_flags and launch Cloud Hypervisor with empty capability sets.

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:20
@lpcox lpcox added the cloud-hypervisor-kvm Trigger the Cloud Hypervisor live-KVM smoke/security suite label Aug 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Documentation Preview

Documentation build failed for this PR. View logs.

Built from commit 80f51a4

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Security Guard has started processing this pull request

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

The security-critical capability and Landlock boundary should receive final human review with live-KVM confirmation.

Review tier: Balanced
Findings: None

What changed in this PR

Removes CAP_NET_ADMIN from the Cloud Hypervisor VMM while preserving TAP access through ownership and a narrowly scoped Landlock rule.

Changes:

  • Empties all VMM capability sets.
  • Restricts TAP sysfs access to tun_flags.
  • Updates unit, live-security, and documentation assertions.
File Description
src/​cloud-hypervisor/​launcher.ts Drops capabilities and narrows Landlock access.
src/​cloud-hypervisor/​launcher.test.ts Verifies zero-capability launch arguments and rules.
scripts/​ci/​cloud-hypervisor-live-smoke.sh Checks all capability sets and TAP rule live.
scripts/​ci/​cloud-hypervisor-ci-scripts.test.ts Verifies smoke-test coverage.
docs/​INTEGRATION-TESTS.md Documents updated security assertions.
docs/​cloud-hypervisor-foundation.md Updates confinement and troubleshooting guidance.
docs/​architecture.md Reflects the zero-capability VMM boundary.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Coverage Check Passed

Overall Coverage

Metric Base PR Delta
Lines 93.86% 93.88% 📈 +0.02%
Statements 92.67% 92.69% 📈 +0.02%
Functions 93.24% 93.24% ➡️ +0.00%
Branches 86.14% 86.16% 📈 +0.02%
📁 Per-file Coverage Changes (1 files)
File Lines (Before → After) Statements (Before → After)
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:39

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

The security-critical capability change depends on live KVM behavior not demonstrated by the listed validation.

Review tier: Balanced
Findings: None

@lpcox lpcox changed the title Drop CAP_NET_ADMIN from Cloud Hypervisor VMM fix: drop CAP_NET_ADMIN from Cloud Hypervisor VMM Aug 31, 2026
@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 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

🛡️ 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

📡 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

📰 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

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

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

📰 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 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 #7887

@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 #7887

@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 failed. Please review the logs for details.

Generated by Contribution Check for #7887

@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

🔌 Smoke Services — All services reachable! ✅

🔌 Service connectivity validated by Smoke Services

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Copilot BYOK (Direct Mode) ✅

Status: PASS

All tests verified:

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

🔑 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@lpcox

  • ✅ GitHub MCP connectivity (list_pull_requests OK)
  • ✅ GitHub.com connectivity (HTTP 200)
  • ✅ File write/read test (smoke-test-copilot-33404795078.txt)

Overall: PASS

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

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Claude Engine Validation

Check Status
API ✅ PASS
GitHub 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 #7887 · claude · haiku45 · 56 AIC · ⊞ 4.5K ·
Add label ready-for-aw to run again

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

Copy link
Copy Markdown
Contributor

EGRESS_RESULT allow=pass deny=pass

✅ Allowed domain (github.com) reachable: allowed=200
✅ Blocked domain (example.com) denied: CONNECT tunnel failed, response 403

Overall: PASS

@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: Docker Sbx Validation

PR: fix: drop CAP_NET_ADMIN from Cloud Hypervisor VMM (#7887)

  • ✅ GitHub MCP connectivity (verified via list_pull_requests)
  • ✅ GitHub.com connectivity (HTTP 200)
  • ✅ File write/read test

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

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 v22.23.2 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

Overall: FAILED — Node.js version mismatch between host and chroot environment. smoke-chroot label not applied.

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

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test Results:

  • Redis: ❌ (DNS resolution failure for host.docker.internal)
  • PostgreSQL pg_isready: ❌ (no response)
  • PostgreSQL SELECT 1: ❌ (DNS resolution failure)

Overall: FAILhost.docker.internal could not 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

@lpcox

  • docs: add B28 runner-doctor coverage for private-CA api-proxy TLS failures: ❌
  • chore(deps): update safe patch dependencies: ❌
  • GitHub.com connectivity: ✅
  • Agent file I/O: ✅
  • BYOK inference: ✅

Running in direct BYOK mode (COPILOT_PROVIDER_API_KEY + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw)

Overall status: 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

docs: add B28 runner-doctor coverage for private-CA api-proxy TLS failures
ochore(deps): update safe patch dependencies
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) authenticated via Microsoft Entra
Overall Status: FAIL
cc @lpcox

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

@github-actions

Copy link
Copy Markdown
Contributor

Smoke test status: FAIL
Merged PRs: "docs: add B28 runner-doctor coverage for private-CA api-proxy TLS failures"; "chore(deps): update safe patch dependencies"
Queried PRs: "feat: isolate Cloud Hypervisor with per-run VMM identities"; "feat: reserve microVM network resources atomically"
Merged PR review ✅
GH query ✅ (used gh; safeinputs-gh unavailable)
Playwright title ✅
File write/read ✅
Discussion query ✅, discussion comment ❌
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

🏗️ 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 (ran, "Hello, World!") ✅ PASS
.NET json-parse N/A (ran, produced JSON output) ✅ 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

Note: Maven's default ~/.m2 directory was owned by root in this environment (pre-existing, unrelated to the firewall), causing an initial LocalRepositoryNotAccessibleException. Worked around by pointing Maven at an alternate writable localRepository path (-s settings override); both Java projects then compiled and tested successfully through the Squid proxy with no other issues.

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

@github-actions

Copy link
Copy Markdown
Contributor

OTel Tracing Smoke Test Results

  • Scenario 1 (Module Loading): otel.js loads successfully. isEnabled()true. Exports: startRequestSpan, setTokenAttributes, setBudgetAttributes, endSpan, endSpanError, shutdown, isEnabled, plus internal helpers (_provider, _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 to the agent; api-proxy-env-config.ts forwards GH_AW_OTLP_ENDPOINTS, OTEL_EXPORTER_OTLP_ENDPOINT, and the same trace-context vars to api-proxy.
  • Scenario 4 (Token Tracker Integration): token-tracker-http.js implements the onUsage callback hook (invoked after normalized usage extraction) — confirmed OTEL integration point.
  • Scenario 5 (OTEL Diagnostics): No api-proxy/otel.jsonl span file found under the sandbox firewall logs (api-proxy OTLP file-export not active this run — expected since a live Sentry OTLP endpoint was configured instead of file export); token-usage.jsonl present and populated, confirming baseline usage tracking is active. This is expected/graceful behavior, not a regression.

Summary: All scenarios pass or behave as expected during development. No regressions detected.

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

@lpcox
lpcox merged commit eeef497 into main Aug 31, 2026
306 of 309 checks passed
@lpcox
lpcox deleted the lpcox-zero-cap-vmm branch August 31, 2026 15:09
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