Add SAND-WP-0013: bubblewrap local-exec extension
First local, same-host, kernel-namespace-only sandbox extension -- every current self-hosted extension requires an SSH hop plus a container runtime or VM. Also the first extension able to actually enforce the network.default: deny every profile already declares. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
bc1f5f8238
commit
d2186e8ac8
1 changed files with 104 additions and 0 deletions
104
workplans/SAND-WP-0013-bwrap-extension.md
Normal file
104
workplans/SAND-WP-0013-bwrap-extension.md
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
---
|
||||
id: SAND-WP-0013
|
||||
title: "Bubblewrap (bwrap) local-exec extension"
|
||||
status: proposed
|
||||
---
|
||||
|
||||
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.
|
||||
|
||||
```task
|
||||
id: SAND-WP-0013-T01
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
## 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`).
|
||||
|
||||
```task
|
||||
id: SAND-WP-0013-T02
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
```task
|
||||
id: SAND-WP-0013-T03
|
||||
status: todo
|
||||
priority: medium
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
```task
|
||||
id: SAND-WP-0013-T04
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
```task
|
||||
id: SAND-WP-0013-T05
|
||||
status: todo
|
||||
priority: medium
|
||||
```
|
||||
|
||||
## 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`).
|
||||
|
||||
```task
|
||||
id: SAND-WP-0013-T06
|
||||
status: todo
|
||||
priority: medium
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue