Skip to main content

Nexura Sandbox

WASI, bubblewrap and gVisor code-execution backends for nexura-runtime.

Install

pip install nexura-sandbox
pip install "nexura-sandbox[wasi]"  # WASI extra

Alpha (0.4): pip install nexura-sandbox. See package installation.

Minimal example

This example only probes host capabilities; it never runs user code. Execution needs approval and host dependencies: WASI needs [wasi] plus the pinned CPython runtime; bubblewrap needs Linux user namespaces and bwrap; gVisor needs runsc, an OCI rootfs and delegated cgroups. Missing backends fall through or fail with CAPABILITY_UNAVAILABLE; an isolation floor prevents weaker fallbacks.

from nexura_runtime.integrations.sandbox import SandboxConfig, build_backend

from nexura_sandbox import BubblewrapWorker, GVisorOCIWorker, WasiWorker

config = SandboxConfig()
for name in ("wasi", "bubblewrap", "gvisor_oci"):
    backend = build_backend(name)  # the runtime returns this package's class
    assert isinstance(backend, (WasiWorker, BubblewrapWorker, GVisorOCIWorker))
    status = backend.probe(config)
    print(f"{name:<11} isolation={backend.isolation:<12} available={status.available}")

Production gVisor profile

For servers, build the config with SandboxConfig.gvisor_production(...). It enforces: only gvisor_oci, min_isolation="gvisor", no network, a read-only root, explicit normalised absolute paths, host memory/pids cgroups (no test bypass), no command prefix other than the test-only sudo -n, and ceilings of 60 s, 1024 MB, 16 processes, 256 runtime tasks, 128 MiB scratch and 4 MiB output. A config that breaks any of these fails validation. Its limits default lower (10 s, 256 MB, one process with fork/clone denied, 32 MiB scratch, 1 MiB output) and may be raised up to the ceilings. Then check the host. The preflight fails if any root-run file or its directories can be written by group or others, starts one tiny guest, and verifies its observed cgroup limits and cleanup:

python -m nexura_sandbox.preflight --runsc /usr/local/bin/runsc \
  --rootfs /opt/nexura/gvisor-rootfs --cgroup-parent /nexura --runsc-sha512 <hex> --strict

From Python, call nexura_sandbox.gvisor_preflight(config). The SHA-512 pin is a drift check, made by the service user when the module is built and before each execution, not at the moment root executes runsc; the gvisor-bin/ sidecars are not pinned. Root-only directories, which the preflight requires, are the real protection. See Production gVisor profile for the operator checklist: root, the cgroup parent, a pinned runsc with its gvisor-bin/ sidecars, and the rootfs.

Status and limits

Status: alpha (0.4), Python 3.12, Linux only. Escape tests ran against real bubblewrap, gVisor and WASI on one Ubuntu x86_64 host. On that host (cgroup v2, runsc release-20260928.0), the gvisor_production profile also ran with enforced memory and pids cgroups. runsc ran as root through a test-only sudo -n prefix, and the cgroup parent was under a systemd-delegated subtree. A root service with a top-level /nexura parent was not exercised. runsc requires root on the reviewed host. No external security review has been done. WASI's complete listener-based escape profile still needs a host permitting local sockets; the recorded shared escape run had one host-listener setup error (socket() denied).

Bubblewrap enforces a tmpfs byte cap but no inode cap unless bubblewrap_tmpfs_inodes is set. It shares the host kernel with no aggregate memory/CPU ceiling; address-space and CPU limits are per process, and max_memory_mb is not total RAM.

Use a service supervisor (systemd KillMode=control-group or a container) to stop all descendants on service exit. Per-run crash watchdogs and delegated bubblewrap lifecycle cgroups add cleanup, but cannot replace the supervisor if the watchdog is also killed.

Each bubblewrap/gVisor launcher runs under a dedicated stdlib supervisor child, which alone enables subreaping and kills/reaps its own descendants. Worker calls leave the hosting process's subreaper flag unchanged. Watchdog and cleanup pipe polling supports descriptors above 1023. All helpers close unrelated descriptors; only the explicit lifecycle and bubblewrap input descriptors are inherited. In the legacy privileged gVisor test profile, the configured command prefix also invokes the fixed supervisor script with the current Python interpreter, so the operator's test command permissions must cover that invocation. gVisor startup sweeps only attributable stale task directories for absent containers; unmarked older directories need operator inspection. See sandbox details and SECURITY_MODEL.md for resource and isolation limitations.

The shared-service startup guard refuses registered sandbox modules below gvisor; it is a startup check, not a continuous guard over later registry changes.

Documentation and licence

Main documentation · Full guide. MIT, Copyright (c) 2026 Liceron. See LICENSE.

Metadata

Release files for nexura-sandbox 0.4.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 nexura-sandbox 0.4.0
File Size Uploaded Provenance
nexura_sandbox-0.4.0.tar.gz 49.4 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for nexura-sandbox 0.4.0
File Interpreter ABI Platform
nexura_sandbox-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 104.9 kB

Release files / nexura_sandbox-0.4.0.tar.gz

Download URL nexura_sandbox-0.4.0.tar.gz
Size 49.4 kB
Tags Source
SHA-256 checksum
How to use checksums
1f9e2124ecee77b9fb607411d1511dafbb477f1ec0a5f19d4849b665bf537e62
BLAKE2b-256 checksum
How to use checksums
7373fd15e69204492607409f6408e39e73c0d366c4cfedb97c140606ba1b952f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.8 {"installer":{"name":"uv","version":"0.12.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / nexura_sandbox-0.4.0-py3-none-any.whl

Download URL nexura_sandbox-0.4.0-py3-none-any.whl
Size 55.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6f471731afe96ed3b9ee8f3a0f77ed39146be2262d937b1a750a31f113a2c37d
BLAKE2b-256 checksum
How to use checksums
79d7301701838a8675d03de9b3350756cca05b17d0e08383ff74176039f8f0b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.8 {"installer":{"name":"uv","version":"0.12.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for nexura-sandbox 0.4.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files No provenance

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