sand-boxer/workplans/SAND-WP-0013-bwrap-extension.md
tegwick 0196f083c4
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
fix: align WP-0013 task references with restored Hub records
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0726e-5232-73f2-aaca-2c05ceb62efb
2026-09-05 22:21:57 +02:00

3.9 KiB

id type title status state_hub_workstream_id
SAND-WP-0013 workplan Bubblewrap (bwrap) local-exec extension finished 34e39c38-ecb8-5be6-bdf8-7d110fb0c4aa

Add the first local, same-host, kernel-namespace-only sandbox extension. Every current self-hosted extension (ext.compose-ssh, ext.vm-packer) requires an SSH hop to a remote host plus a container runtime or VM. bwrap (already installed on the workstation, unused) fills the gap: a fast, no-remote-host, no-container-runtime backend, and the first extension able to actually enforce the network.default: deny every profile already declares but only documents today (docs/security.md admits enforcement "varies by extension").

Task: Extend the isolation-level model

IsolationSpec.level in src/sandboxer/models.py is a closed Literal["container", "microvm", "policy"]. Add a value for namespace/process-level isolation (e.g. "process") and update any validation/display logic that switches on it.

id: SAND-WP-0013-T01
status: done
priority: high
state_hub_task_id: "91f50ae4-7080-5475-bb85-614c8fe90860"

Task: Implement BwrapExtension

New src/sandboxer/extensions/bwrap.py implementing the SandboxExtension ABC (provision/wait_ready/teardown): provision() creates a per-sandbox workspace dir, spawns the target under bwrap with new user/mount/pid/net namespaces, a tmpfs root, bind mounts scoped to the workspace, and --unshare-net (or a loopback-only net namespace) so declared network-deny is real; handle = {sandbox_id, host: "localhost", pid, workspace_dir}. wait_ready() checks the process is alive and the workspace exists. teardown() kills the process group and removes the workspace. No snapshot support initially (supports_snapshots() stays False).

id: SAND-WP-0013-T02
status: done
priority: high
state_hub_task_id: "8b41c12b-e093-5f57-8c25-17d8d0c96082"

Task: Register the extension and a profile

extensions/ext.bwrap.yaml (handler path, capabilities.isolation_levels including the new value, pricing_model: self-hosted). New profiles/profile.bwrap-local.yaml bound to ext.bwrap, network. default: deny actually meaningful this time, suitable for CI/local dev.

id: SAND-WP-0013-T03
status: done
priority: medium
state_hub_task_id: "cf29db06-c427-582e-ba17-c5fb53867a1f"

Task: Resolve local reachability vs. the SSH-based consumer contract

docs/integrations/glas-harness.md documents glas-harness consuming sandboxes via reachability.ssh + remote_dir. A same-host bwrap sandbox has no SSH hop. Decide and document: a new local reachability descriptor (e.g. reachability.local with a direct workspace path + PID), vs. requiring glas-harness to gain a direct-subprocess-exec consumption mode. Update docs/integrations/glas-harness.md and reachability/enrich.py accordingly. Coordinate with glas-harness GLAS-WP-0001 (harness contract) so both sides agree before either is built against the other.

id: SAND-WP-0013-T04
status: done
priority: high
state_hub_task_id: "378118e7-0d19-59c7-b998-5b26ed442b3b"

Task: Extend manager's handle whitelist

core/manager.py::_handle_from_status reconstructs a fixed set of fields from stored inputs for teardown/snapshot calls. Add bwrap's handle fields (pid, workspace_dir) to that whitelist so teardown/restart survives a sandboxer CLI/process restart.

id: SAND-WP-0013-T05
status: done
priority: medium
state_hub_task_id: "b6638a8e-8577-538a-ac5b-3b56775bd48f"

Task: Tests

Mirror the existing extension test pattern (mock the subprocess/bwrap invocation the way tests/ mocks SSHConfig.run for compose-ssh); cover provision/wait_ready/teardown, the new isolation-level value, and extension_base conformance (SandboxExtension subclass checks already exercised generically in test_extension_base.py).

id: SAND-WP-0013-T06
status: done
priority: medium
state_hub_task_id: "f9805c5a-2bbe-5fc9-b084-b41e0683460d"