Skip to content

feat(sandbox): add the bubblewrap provider (sandbox Phase 1) - #197

Merged
quickbeard merged 1 commit into
mainfrom
sandbox-bwrap-provider
Aug 12, 2026
Merged

quickbeard merged 1 commit into
mainfrom
sandbox-bwrap-provider

Conversation

@quickbeard

Copy link
Copy Markdown
Owner

Summary

Phase 1 of the desktop sandbox: the first platform backend, an Ubuntu bubblewrap provider implementing the SandboxProvider contract from Phase 0 (#196). The codev server runs inside bwrap with unshared user/pid/net/uts/ipc namespaces — the guest's only network interface is loopback, and its only paths out are unix sockets bind-mounted at /run/codev, per the agreed NIC-less + host-broker design.

How it works

  • bwrap/args.ts — pure invocation builder: read-only rootfs binds with merged-usr symlinks preserved (/bin -> usr/bin recreated as --symlink), project rw at /workspace, server bundle ro at /opt/codev (injected from the host for automatic version parity), per-sandbox home, --clearenv + the boot env contract, --die-with-parent.
  • bwrap/bridge.ts — how TCP crosses the network namespace: unix sockets are filesystem objects, so a host-side TCP→unix forwarder gives the renderer its usual http://127.0.0.1:<port> + Basic-auth contract, and a guest-side node forward script (run with the image's node) bridges unix↔TCP inside — one script serves both the server path (unix-to-tcp) and the broker path (tcp-to-unix).
  • bwrap/rootfs.ts — tar unpack into per-sandbox dirs + top-level layout probing.
  • bwrap/provider.ts — availability probe (bwrap --ro-bind / / true) that distinguishes "not installed" from "cannot create sandboxes" (the Ubuntu 23.10+ AppArmor userns restriction, with guidance in the message); create stages the manifest image (SHA-256-verified, content-addressed) and unpacks it; start is health-gated (/global/health with generated credentials) with a 30s timeout, stderr-tail capture in errors, and clean kill on failure; reset wipes rootfs + home and re-unpacks from the cached image without re-downloading.
  • broker.ts — gains listenUnix so the egress broker can serve netns-isolated guests; boot.ts gains checkSandboxHealth.

CI

turbo.json now registers @codev/sandbox#test, so bun turbo test (the unit CI job) runs this package — previously it was silently skipped. That's an upstream-file edit: DIVERGENCES.md row added in this PR.

The real-bwrap integration tests (bwrap.integration.test.ts) verify loopback-only networking via /proc/net/dev, workspace rw vs rootfs ro, and env clearing against actual bubblewrap, using the host's own /usr as rootfs so no image download is needed. They auto-skip where bwrap can't run (macOS, AppArmor-restricted runners) via a capability probe rather than a platform check.

Notes

  • No CHANGELOG entry yet — still not user-facing until the desktop wiring lands.
  • Packaging follow-up recorded in the README: the .deb should ship an AppArmor profile permitting unprivileged userns on Ubuntu 24.04+.

Testing

  • bun test in packages/codev-sandbox: 51 pass / 2 skipped (the real-bwrap integration tests, correctly skipped on this macOS machine), 138 assertions — including end-to-end bridge chains (host TCP → forwarder → unix socket → guest script → guest TCP, both directions) and full create/reset/destroy against a staged image over real HTTP.
  • bun typecheck in packages/codev-sandbox: clean.
  • bun turbo test --filter=@codev/sandbox from root: runs and passes, confirming the CI registration.

🤖 Generated with Claude Code

First platform backend for the sandbox: an Ubuntu provider that runs the
codev server inside bubblewrap with unshared user/pid/net/uts/ipc
namespaces — loopback-only networking, read-only rootfs binds (merged-usr
symlinks preserved), project rw at /workspace, server bundle ro at
/opt/codev, per-sandbox home, cleared env.

- bwrap/args.ts: pure bwrap invocation builder
- bwrap/bridge.ts: unix-socket bridges that cross the guest netns — a
  host-side TCP-to-unix forwarder plus the guest-side node forward
  script for the server and broker paths
- bwrap/rootfs.ts: tar unpack + rootfs layout probing
- bwrap/provider.ts: SandboxProvider with an availability probe that
  detects the Ubuntu 23.10+ AppArmor userns restriction, health-gated
  start with stderr capture, and create/reset/destroy dir management
- boot.ts: checkSandboxHealth (basic-auth /global/health probe)
- broker.ts: listenUnix so the broker can serve netns-isolated guests
- turbo.json: register @codev/sandbox#test so CI's `bun turbo test`
  gates the package (DIVERGENCES.md row added)

Real-bwrap integration tests auto-skip where bwrap can't run (macOS,
AppArmor-restricted runners).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@quickbeard
quickbeard merged commit 1521661 into main Aug 12, 2026
0 of 5 checks passed
@quickbeard
quickbeard deleted the sandbox-bwrap-provider branch August 12, 2026 01:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant