Skip to main content

maf-sandbox-bubblewrap

PyPI Python License

Experimental. Not yet released. maf-sandbox-bubblewrap may change or be removed without notice and emits MafSandboxBubblewrapExperimentalWarning on import.

Experimental Linux sandbox backend using Bubblewrap and cgroup v2, without Docker, an OCI image or a container engine. The runtime is a separately provisioned, trusted Linux root directory. Runtime downloads never happen during a tool call.

Prerequisites

  • Linux with unprivileged user, mount, PID, network, IPC, UTS and cgroup namespaces; Bubblewrap supporting --disable-userns, --assert-userns-disabled, --as-pid-1 and bounded tmpfs mounts. Missing support refuses startup.
  • A private cgroup v2 delegation with cpu, memory and pids enabled, memory.swap.max and cgroup.kill. The host process must already belong to that delegation so it can move children into sibling groups. A systemd service with Delegate=cpu memory pids can provide it; the host must place itself in a leaf and enable the controllers on its empty parent. This package does not grant privileges or change host-wide policy.
  • A trusted runtime directory containing /usr/bin/python3 and /bin/sh, with no host credentials or sockets. Keep it immutable while sandboxes run. Runtime, cgroup and state paths and their ancestors must be controlled by the host administrator. State and cgroup roots must resolve outside the runtime. The state directory must be owned by the service user and mode 0700.

Use

from pathlib import Path
from maf_sandbox import Isolation, SandboxRouter
from maf_sandbox_bubblewrap import BubblewrapSandboxBackend, BubblewrapSandboxConfig

async def make_router() -> SandboxRouter:
    backend = await BubblewrapSandboxBackend.create(BubblewrapSandboxConfig(
        runtime_root=Path("/opt/maf-runtime"),
        state_root=Path("/var/lib/my-service/sandbox-state"),
        cgroup_root=Path("/sys/fs/cgroup/my-service"),
        runtime_id="drawio-native",
    ))
    return SandboxRouter([backend], min_isolation=Isolation.CONTAINER)

SandboxSpec.image is an optional exact match against the configured runtime_id, not an OCI reference. image_id is unsupported. The storage base is /maf-sandbox/work; only that explicit override or None is accepted. Relative working directories address the base. Commands are opaque; a string runs through /bin/sh -c, while a sequence executes directly.

The protocol's Isolation.CONTAINER means Linux namespaces plus cgroups. It describes the boundary even though no container engine is used. The router's default MICROVM floor still refuses this backend. Keep a separate router or use per-spec routing for a native renderer alongside a stronger CodeAct backend; never lower a shared host floor implicitly.

Boundary and lifecycle

Every sandbox gets mandatory private namespaces, no capabilities, disabled nested user namespaces, a new session and a cleared environment. The runtime is read-only. /tmp, /run and /maf-sandbox are separate bounded tmpfs mounts; aggregate memory, swap, process count and CPU are constrained before any guest starts. Default limits are 1 GiB memory, no swap, 256 processes, two CPU equivalents and 128 MiB per writable mount. No host home, display, network or cgroup filesystem is mounted. Only Egress.CLOSED, POSIX EXEC, FILES_IN and FILES_OUT are declared. This is a shared-kernel boundary, not a microVM or a claim of protection against kernel exploits. No seccomp syscall filter is currently supplied.

A private PID 1 broker uses no-follow directory descriptors for transfers. It runs at guest filesystem authority; its stat responses are guest-side metadata, not host attestations. Its control descriptors are protected from ptrace, and commands receive separate stdin/stdout/stderr. Individual transfers are capped at 8 MiB; the router applies its collection count and aggregate byte limits. Combined command output is capped at 1 MiB by default; excess output fails explicitly. A command's descendants, including detached processes, are killed before its reply. Timeout or cancellation after dispatch destroys the entire sandbox; while queued, it refuses only the waiting request. There is no reclamation or snapshot capability; the router uses disposal.

Key identity includes scope, thread, agent, call and kind. An exclusive host file lock prevents another backend object or process from acquiring a live instance. Repeated acquire within one backend can reuse a matching spec; another owner is refused. Files live only in tmpfs and disappear on owner death. Records allow a subsequent host to purge dead owners' cgroups; this is cleanup recovery, not restoration of guest state. Stale instance disposal cannot delete a replacement. A scope purge reports busy or failed records and retains them for retry. Hosts must stop new work across replicas before purging a conversation.

Lock files remain after disposal so a concurrent owner cannot lock a replacement inode under the same name. Remove the state directory only after stopping all owners; long-lived deployments should account for those small files in retention policy.

Ownership records are published atomically before cgroup creation, so a host that dies during startup leaves either no cgroup or a complete cleanup record. Failed setup removes its record after cgroup cleanup succeeds. Commands whose requested timeout exceeds max_timeout (180 seconds by default) are rejected with ValueError before execution. Accepted deadlines include time waiting for the request lock; only the remaining budget reaches the broker.

Offline Draw.io

The runtime provisioning script uses debootstrap and the pinned Draw.io Desktop package directly, with the same offline assets, fonts and exporter as the image profile. Provisioning needs network access and root; rendering needs neither. Run the host outside that runtime and register this backend with maf-sandbox-drawio, passing the configured runtime id as image. Linux is the only supported host platform; native Windows and macOS backends are separate work.

Metadata

Release files for maf-sandbox-bubblewrap 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for maf-sandbox-bubblewrap 0.1.0
File Size Uploaded
maf_sandbox_bubblewrap-0.1.0.tar.gz 14.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for maf-sandbox-bubblewrap 0.1.0
File Interpreter ABI Platform
maf_sandbox_bubblewrap-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 32.4 kB

Release files / maf_sandbox_bubblewrap-0.1.0.tar.gz

Download URL maf_sandbox_bubblewrap-0.1.0.tar.gz
Size 14.8 kB
Tags Source
SHA-256 checksum
How to use checksums
1e65d65e01fa11468e283fdc2c7bd5c5282ab06a13847d3853180b84d93bab14
BLAKE2b-256 checksum
How to use checksums
07cc27f64667e33300b2c3ca086bb9895811a8797518fe1c1d06004f8402b441
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release files / maf_sandbox_bubblewrap-0.1.0-py3-none-any.whl

Download URL maf_sandbox_bubblewrap-0.1.0-py3-none-any.whl
Size 17.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
653f67d7c8b9d9a3b52193d00f187a0575019724f3566b3e2304fe67a433ef0b
BLAKE2b-256 checksum
How to use checksums
f9eb29c803e9e4e3c3a01710c41f5dcfcb8eeb42486129f5ed66fe46e21d4943
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.0

2 release files

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page