inspect-openshell-sandbox
An NVIDIA OpenShell sandbox environment
for Inspect AI. Each sample runs in its own
OpenShell sandbox: kernel-enforced file, syscall and network policy, with
credentials that only work at approved endpoints. Inspect tasks need no change
beyond sandbox="openshell".
Status
0.1.0, alpha. Tested with OpenShell 0.1.x on Docker Desktop (macOS, Apple
Silicon) with the grpc_endpoint workaround for host networking, and Inspect
AI 0.3.266. Linux hosts and the Podman, Kubernetes and VM drivers are
untested; the CLI mapping should hold but defaults may differ.
Install
# OpenShell CLI + local gateway (see the OpenShell README for options)
curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh | sh
# this provider, into the venv that runs inspect
uv pip install inspect-openshell-sandbox # from PyPI
# or, from a checkout of this repo:
uv pip install -e .
Use
Put an openshell.yaml next to the task file:
image: spec-games-openshell:python # openshell sandbox create --from
build: ./images/python # optional: docker build this dir + tag as `image` at task_init
workdir: /space # must exist in the image, writable by UID 1000
# policy: policy.yaml # optional openshell policy for this task
Without build: and workdir: the defaults are python:3.12-slim and
/sandbox, the unprivileged user's home. To use any other directory, the
image must create it and chown 1000:1000 it, and set it as WORKDIR: on the
Docker driver OpenShell adopts the image's WORKDIR as the workspace. The
bundled images/python/Dockerfile does this for /space.
and in the task:
Task(..., sandbox="openshell")
Inspect finds openshell.yaml automatically, the same way it finds
compose.yaml for docker.
What it does
| Inspect call | OpenShell |
|---|---|
sample_init |
openshell sandbox create --name inspect-<task>-<id> --from <image> [--policy ...] |
exec(cmd, cwd, env, input, timeout) |
openshell sandbox exec -n <name> --no-login-shell [--env K=V] -- bash -c "cd <cwd> && <cmd>" |
write_file |
base64 over stdin, base64 -d > file |
read_file |
base64 < file, decoded locally |
sample_cleanup |
openshell sandbox delete <name> |
Files and commands all go through exec, so the sandbox policy governs the
scorer's reads as well as the agent's writes.
Limits, first version
- Sandboxes run as an unprivileged user (UID 1000); only
/sandboxand below is writable unless the image says otherwise. Aworkdiroutside it fails atsample_initwith a clear error. - Sandbox names are capped at 19 characters by the gateway, so the task name is not part of the name.
- The sandbox exposes
OPENSHELL_SANDBOXin the environment. Since a model that can see it knows it is being sandboxed, the provider unsets it in the agent's shell by default (hide_env).HOMEis the workdir. OpenShell's own directories under/run/openshelland similar are still present. - Per-command
useris not supported. write_fileis capped at about 3 MiB (the CLI's 4 MiB stdin limit after base64). Larger files should useopenshell sandbox upload; not wired yet.- Sandbox creation is slower than docker.
default_concurrencyis 4. - No policy is applied unless
policy:is set. The interesting use is a policy that makes the test file read-only, so a spec edit is refused by the kernel instead of detected afterwards.
Smoke test without a model
python scripts/smoke.py
Creates a sandbox from python:3.12-slim, writes a file, runs a command,
reads the file back, deletes the sandbox, and prints each step.
Origin
Built for spec-games, where it runs a
contradictory-spec task with the test file locked read-only by an OpenShell
policy. That task's policy.yaml and Dockerfile are a worked example.
Metadata
Release files for inspect-openshell-sandbox 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| inspect_openshell_sandbox-0.1.0.tar.gz | 10.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| inspect_openshell_sandbox-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.8 kB
Release files / inspect_openshell_sandbox-0.1.0.tar.gz
| Download URL | inspect_openshell_sandbox-0.1.0.tar.gz |
|---|---|
| Size | 10.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bd470908ccab6027ce6a7eacbff91eebdb89bccfa35dd3ed93d08c5b653d99d7
|
|
BLAKE2b-256 checksum How to use checksums |
e6eba2ab7b96d48678671f33a219bb8abe57d2abcf230533d5a294652c23eea0
|
| 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 Sep 30, 2026.
Transparency logRelease files / inspect_openshell_sandbox-0.1.0-py3-none-any.whl
| Download URL | inspect_openshell_sandbox-0.1.0-py3-none-any.whl |
|---|---|
| Size | 8.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
080b197666f71c84eedd0dd46000f87f2e9fdcd6e3a33cfe5c2ea6604614573e
|
|
BLAKE2b-256 checksum How to use checksums |
9b216a4d62007660779903e6b7068f64345ec78b2217787d8a6a182ead2f32d4
|
| 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 Sep 30, 2026.
Transparency log