# Bubblewrap execution security review

**Reviewed:** 2026-10-01  
**Code reviewed:** `src/cyberbrain26/execution_plane/bubblewrap_provider.py` and
`src/cyberbrain26/execution_plane/secure_gateway.py`  
**Disposition:** suitable for a constrained local prototype; **not approved as
a general-purpose hostile-code sandbox**.

## Enforced controls

- The provider executes only Python or shell through Bubblewrap. Missing
  Bubblewrap raises an error before process launch; there is no unsandboxed
  fallback.
- `--unshare-all`, `--new-session`, and `--die-with-parent` request separate
  network, process, IPC, and related namespaces. The sandbox receives no
  inherited environment; only a fixed `PATH` and `HOME` are set.
- `/usr`, and existing `/lib` and `/lib64`, are mounted read-only. `/dev` and
  `/proc` are supplied in the sandbox, `/tmp` is private, and the selected
  workspace is the sole writable host bind mount.
- Python/shell execution has a wall-time limit, CPU/address-space/file-size
  rlimits, and separately capped stdout and stderr. Unsupported languages fail
  before process launch.
- `AuthorizedExecutionService` performs identity, policy, permission, optional
  approval, and audit checks before invoking the provider.

## Remaining risks and operating limits

- The workspace is a writable bind mount of a host directory. Its existing
  contents are readable and modifications persist after execution. Callers
  must provide a disposable, task-scoped workspace for untrusted inputs.
- The provider does not configure cgroup memory/PID limits, a process-count
  limit, or a filesystem quota. Per-process rlimits do not cap aggregate memory
  or prevent a workload from consuming many inodes or filling the workspace's
  host filesystem.
- System runtime trees are visible read-only. Their contents and the available
  system binaries still contribute to the attack surface.
- Isolation depends on host kernel namespace support and Bubblewrap's install
  mode. Failure to start is fail-closed, but supported host configurations
  still need deployment checks.
- Timeout/cancellation kills the Bubblewrap subprocess and relies on
  `--die-with-parent` for sandbox descendants. Descendant cleanup should be
  verified on every supported kernel and Bubblewrap build.
- SQLite audit and task files are access-restricted but not encrypted. Retention
  deletes logical rows; it is not secure erasure from database pages, WAL files,
  snapshots, or backups.
- Existing smoke and isolation tests demonstrate selected behaviors only.
  They do not establish resistance to kernel exploits or all resource-exhaustion
  attacks.

## Required before processing hostile code

1. Pin and validate supported Linux/Bubblewrap configurations, including
   namespace availability and process cleanup on timeout/cancellation.
2. Add deployment-level cgroup limits for memory, process count, CPU, and I/O;
   use task-scoped disposable workspaces with disk/inode quotas.
3. Run the execution integration suite in CI with Bubblewrap present and absent.
   Keep the absence case fail-closed.
4. Have a security reviewer assess the complete host deployment and workspace
   lifecycle. This code review is an engineering assessment, not a certification.

## Fail-closed evidence

`execute()` checks for the configured Bubblewrap binary before creating a
process and raises `RuntimeError` if it is unavailable. It never retries via a
host shell or Python process. Unsupported languages raise `ValueError`. The
execution test suite covers these paths along with selected namespace,
workspace, timeout, output-cap, and host-file-isolation behaviors.
