Skip to content

draft - feat/arm64 vm launcher - #1834

Open
kelenyibenjamin wants to merge 7 commits into
mainfrom
feat/arm64-vm-launcher
Open

draft - feat/arm64 vm launcher#1834
kelenyibenjamin wants to merge 7 commits into
mainfrom
feat/arm64-vm-launcher

Conversation

@kelenyibenjamin

Copy link
Copy Markdown
Contributor

No description provided.

Comment thread go/internal/cli/vm/store.go Fixed
Comment thread go/internal/cli/vm/store.go Fixed
Apple Silicon gets HVF and ARM64 Linux gets KVM when /dev/kvm is usable;

Signed-off-by: Benjamin Kelenyi <benjamin@wendy.sh>
State lives under ~/.wendy/vms/<name>/. Creation takes a stream, refuses to

Signed-off-by: Benjamin Kelenyi <benjamin@wendy.sh>
User mode carries no multicast, so discovery only works on the shared segment.

Signed-off-by: Benjamin Kelenyi <benjamin@wendy.sh>
One function owns the argv so it can be asserted in tests instead of discovered

Signed-off-by: Benjamin Kelenyi <benjamin@wendy.sh>
create/start/list/rm, defaulting to the published image and falling back to
--image. Name and port are checked before anything downloads or launches.

Signed-off-by: Benjamin Kelenyi <benjamin@wendy.sh>
The skill assets described a meta-wendyos-virtual layer and a setup-dev-vm.sh
script that do not exist, which is what a reader finds first.

Signed-off-by: Benjamin Kelenyi <benjamin@wendy.sh>
Every PR builds a VM image precisely because it is the one target a reviewer can
run without hardware; --pr is what makes that build reachable.

Signed-off-by: Benjamin Kelenyi <benjamin@wendy.sh>
@github-actions

Copy link
Copy Markdown
Contributor

AI Security Review

Note

Automated security review from Claude. Apply, adapt, silence with // SECURITY: <reason>, or dismiss as needed.

Input coverage: 17/17 changed files; 82,173/82,173 bytes reviewed; diff SHA-256 d6b9a4409f6ec0587ad1e444041f90ced56a415d7ff9499c170fec7d889a8cdc; truncation: none.

Claude found security review findings for this PR.

⚠️ Concern — Open MEDIUM: --pr boots an OS image built from an arbitrary pull request

go/internal/cli/commands/vm.go:116-133: The --pr &lt;n&gt; flag resolves and boots the OS image produced by any pull request build, which can be attacker-influenced content run locally.

Details
**Status:** Open
**Severity:** MEDIUM
**Standards:** SOC2-CC6, ISO27001-A.8.28, NIST-SP800-53-SI-7, NIST-CSF-PR.DS
**Location:** `go/internal/cli/commands/vm.go:116-133`

`fetchPRMainManifest(pr)` lets a user create and boot a VM from the build output of an arbitrary PR number (`wendy vm create review --pr 1234`). PR-triggered CI builds are, by design, built from untrusted contributor branches. A developer reviewing a malicious PR who runs `wendy vm start` executes an attacker-crafted WendyOS image on their machine (with a loopback-exposed agent, filesystem-backed disk, and host QEMU process).

Remediation:
- Treat PR images as untrusted by default and warn prominently in `wendy vm create --pr` output.
- Ensure PR artifacts are namespaced/isolated from release artifacts (they appear to reuse `LatestNightly`), so a PR build can never masquerade as a release.
- Verify artifact digests against the PR build's own signed manifest, and consider restricting `--pr` to trusted/labelled PRs or gating behind an explicit `--i-trust-this-pr` style confirmation.

This is an intentional dev-convenience feature, so it may be accepted, but the trust boundary should be documented and the risk explicitly acknowledged.

⚠️ Concern — Open MEDIUM: Downloaded VM images are booted without visible integrity/provenance verification

go/internal/cli/commands/vm.go:111-160: fetchPublishedVMImage resolves and downloads a multi-gigabyte OS image that is then written to disk and booted, but no checksum/signature verification is visible in the diff.

Details
**Status:** Open
**Severity:** MEDIUM
**Standards:** SOC2-CC6, SOC2-CC7, ISO27001-A.8.28, NIST-SP800-53-SI-7, NIST-CSF-PR.DS
**Location:** `go/internal/cli/commands/vm.go:111-160`

`fetchPublishedVMImage` calls `resolveSeekableZst` / `resolveOSImage` to fetch the published `.wic`/`.zst` artifact and streams it straight into `store.CreateFrom`, which is then executed by QEMU. Booting an OS image is effectively executing untrusted code; if the artifact source (manifest URL, CDN, or registry) is compromised or MITM'd, an attacker-controlled image runs on the developer's machine and speaks the (initially unauthenticated) agent protocol on loopback.

The integrity check likely lives in the referenced helpers (`resolveSeekableZst`, `resolveOSImage`, `getImageInfo`) which are not part of this diff, so this cannot be confirmed. Please ensure:
- The manifest and artifacts are fetched over TLS with cert validation.
- Each artifact's digest (and ideally a signature) from the manifest is verified against the downloaded bytes before `CreateFrom` writes/boot.
- The digest covers the uncompressed content, not just the compressed blob.

If verification already exists in those helpers, mark this addressed; otherwise add explicit digest/signature validation before provisioning the disk.

💡 Info — Open LOW: Guest agent forwarded to loopback is unauthenticated until provisioning

go/internal/cli/vm/net.go:104-116: User-mode networking forwards the guest agent port to 127.0.0.1, and the agent is unauthenticated until the device is provisioned, which any local process can reach.

Details
**Status:** Open
**Severity:** LOW
**Standards:** SOC2-CC6.1, ISO27001-A.8.16, NIST-CSF-DE.CM
**Location:** `go/internal/cli/vm/net.go:104-116`

The code correctly and deliberately binds the hostfwd to `127.0.0.1` (good, and asserted by `TestUserModeForwardsOnLoopbackOnly`). However, the comment notes the agent is 'unauthenticated until the device is provisioned.' On a multi-user host, any local user/process can connect to `127.0.0.1:50051` and interact with the fresh VM's agent (e.g., trigger provisioning binding it to an attacker's org, deploy containers) before the legitimate user does.

Remediation: document that a freshly created VM's agent is unauthenticated on loopback and should be provisioned promptly; consider whether the agent should refuse enrollment except from an authenticated local channel, or generate a one-time enrollment token surfaced by `wendy vm start`. Low severity given loopback scope and dev-only use.

💡 Info — Open INFORMATIONAL: MAC address derived from unsalted SHA-256 of the VM name

go/internal/cli/vm/net.go:78-84: MACFor derives the guest MAC deterministically from the VM name via SHA-256, which makes the guest's mDNS-visible identity predictable across hosts.

Details
**Status:** Open
**Severity:** INFORMATIONAL
**Standards:** SOC2-CC6.6, ISO27001-A.8.24
**Location:** `go/internal/cli/vm/net.go:78-84`

`MACFor` computes a stable, unicast, locally-administered MAC from `sha256("wendy-vm:"+name)`. This is a reasonable design for lease stability, and there is no direct exploit. The only note is that the MAC (and therefore DHCP-derived address/hostname advertised over mDNS on `--net shared`) is globally predictable from the VM name, so two developers using name `dev` on the same shared segment could collide, and an observer can enumerate likely MACs. Not a security defect; documented here for awareness. No action required.
Compliance summary
The VM launcher demonstrates solid engineering-level hardening (loopback-only port forwarding, name validation preventing path traversal, O_EXCL disk creation, read-only firmware code, deterministic non-colliding MACs, robust cleanup). The primary compliance-relevant gaps map to **SOC 2 CC6/CC7** and **ISO 27001 A.8.28** and **NIST SP 800-53 SI-7 (software/firmware integrity)**: downloaded and especially PR-built OS images are provisioned and booted with no integrity/provenance verification visible in this diff. Confirm digest/signature validation in the fetch helpers (`resolveSeekableZst`, `resolveOSImage`) and treat `--pr` images as an explicit trust boundary. No PCI DSS, HIPAA, or GDPR data domains are touched by this change.

@github-actions github-actions Bot added risk: high High estimated risk; thoroughly test compatibility and affected workflows api-review Ask Joannis - Changes a public CLI or protobuf API surface labels Aug 30, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Docs preview

Preview this PR's docs at: https://docs.wendy.dev/branch-feat-arm64-vm-launcher-c848768c6d0d9d72cb88ae480d0167128b3344b7/

This comment is updated automatically when the docs preview is redeployed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api-review Ask Joannis - Changes a public CLI or protobuf API surface risk: high High estimated risk; thoroughly test compatibility and affected workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant