Handing a coding agent your shell is a bet that nobody will ever talk it into something dumb. NVIDIA’s OpenShell, a 0.1.x open source runtime with about 16k GitHub stars, takes the other route: let the agent work, but keep the file, process, network and credential rules outside its reach, in a YAML policy you can review.
This guide covers what it is, the four-step architecture, the commands as documented, a real policy and, just as important, where it stops. The one-line start: openshell sandbox create --name demo. A sandbox limits damage; it does not make an agent trustworthy.
1. What Is OpenShell?
OpenShell is a runtime for running autonomous AI agents inside sandboxes whose permissions you declare in a YAML policy. The repo’s own description calls it “the safe, private runtime for autonomous AI agents”: agents get the files, packages, APIs and credentials they need, but only inside the policy. NVIDIA publishes it under Apache-2.0, and the repo is a Rust workspace with Python, TypeScript, Go and Rust SDKs.
~16.2k
Stars
GitHub page, Oct 14, 2026
Apache-2.0
License
Open source
v0.1.4
Latest release
Oct 13, 2026
Rust
Stack
CLI, gateway, SDKs
Read from the GitHub repo page, the releases page and the docs on 2026-10-14. Stars move daily. v0.1.1 through v0.1.4 landed between Sep 26 and Oct 13.
That cadence is the first thing to internalize. The docs describe 0.1.x as a stable release cadence and the support matrix says stable releases generally ship weekly, but it is still a 0.1 line: the same page warns that interfaces marked Experimental may change or be removed in a patch release, and one v0.1.3 entry carries the conventional-commit breaking marker. Read the release notes before every upgrade.
Why the enforcement has to live outside the agent
NVIDIA’s post on the 0.1.0 release makes the case plainly: agents need broad access to be useful, that access makes failures more consequential, and OpenShell enforces the permissions outside the workload so the agent’s own reasoning doesn’t decide what it can do. My gloss: a limit written into a prompt is only as strong as the agent’s resistance to prompt injection, while a confused or hijacked agent still hits the same wall here.
2. Architecture in Four Steps
The docs’ architecture page splits the system into a control plane (the gateway), a trusted decision-maker (the supervisor) and the sandbox where your agent runs. Follow one request through it and you get four steps.
1. The gateway and a compute driver create the sandbox
The gateway is the control plane: it manages the sandbox lifecycle, delivers policy, attaches providers and authorizes connections, all outside the sandbox. A compute driver (Docker, Podman, Kubernetes through the Helm chart, or a libkrun-based MicroVM) creates the sandbox, starts the supervisor and the workload, and builds the network fence.
2. Kernel controls confine the workload
On the Linux backend the agent runs with a non-root identity and no Linux capabilities, Landlock restricts files to the paths you declare and seccomp blocks escalation paths. These layers are fixed when the sandbox is created.
3. The supervisor decides every connection
The workload’s only way out is a private channel to the supervisor. For each TCP connection or DNS lookup the sandbox identifies the calling program, and the supervisor checks policy: host and port, the binary that opened the connection and, if you set a protocol, the individual request (method, path, GraphQL operation, MCP tool). Only then does it open the real connection.
4. Credentials and proposals close the loop
The agent’s environment holds opaque placeholders, not real keys; the supervisor resolves them only for endpoints the provider profile authorizes. A blocked connection becomes a draft rule, the policy prover checks it, a person approves or rejects it, and approved network rules hot-reload with no restart.
The four policy layers (docs overview and schema)
📁 Filesystem
LandlockLocked at creation
Only declared paths are reachable, through read_only and read_write lists. Unlisted paths are inaccessible.
⚙️ Process
seccomp + non-rootLocked at creation
Unprivileged identity; root is rejected. Syscalls such as mount, pivot_root, ptrace and bpf are blocked.
🌐 Network
Default denyHot-reloadable
Rules name endpoints and the binaries allowed to reach them. Everything else is denied.
🔐 Credentials
PlaceholdersRuntime
Real secrets resolve only at the hosts, ports and paths a provider profile authorizes.
3. Quickstart: Verified Against the README on 2026-10-14
Every command below is copied from the README or the docs as of today. I am documenting them, not running them for you. Note that the install line pipes a script from the main branch into your shell: read install.sh first, which is the same advice I give for any skill or package.
Install (README, verbatim)
curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh | sh
Create your first sandbox (README)
openshell sandbox create --name demo
Check the CLI reaches the gateway (docs, installation)
openshell status
Day to day (docs, sandboxes; name changed to demo)
openshell sandbox list openshell sandbox connect demo openshell sandbox exec -n demo -- ls -la /workspace openshell sandbox delete demo
What the installer sets up
Per the docs it installs the CLI, the policy prover and a local gateway. On Linux the packaged gateway runs as a systemd user service at https://127.0.0.1:17670; on macOS it runs as a Homebrew service at https://localhost:17670. To pin a version, the docs say to set OPENSHELL_VERSION to a release tag. Prerelease and dev builds are documented too, but prerelease artifacts expire after 90 days and dev builds may be unstable.
Requirements (README and support matrix)
- • Linux (Debian/Ubuntu, x86_64 and aarch64) and macOS on Apple Silicon with Docker Desktop are supported
- • Windows through WSL 2 plus Docker Desktop is marked Experimental
- • A runtime: Docker or Engine 28.0+, Podman 5.x, Kubernetes 1.29+ via Helm, or a MicroVM (KVM or Hypervisor.framework)
- • On Linux, Landlock ABI 3 or newer (kernel 6.2+); without it, launch fails closed
4. Writing a Policy That Actually Does Something
A policy file starts with version: 1 and has up to five sections: filesystem_policy, landlock, process, network_policies and network_middlewares. The first three apply at startup; the network sections can change while the sandbox runs. This is the complete example from the docs’ schema page.
policy.yaml (docs, policy schema)
version: 1
filesystem_policy:
include_workdir: true
read_only: [/usr, /lib, /etc]
read_write: [/tmp]
network_policies:
github_rest_api:
endpoints:
- host: api.github.com
port: 443
protocol: rest
enforcement: enforce
access: read-only
binaries:
- path: /usr/bin/gh
npm_registry:
endpoints:
- host: registry.npmjs.org
port: 443
protocol: rest
enforcement: enforce
access: read-only
allow_encoded_slash: true
binaries:
- path: /usr/bin/nodeApply it and change it live (docs, manage policies)
openshell sandbox create --name my-sandbox --policy ./policy.yaml openshell policy update my-sandbox \ --rule-name github_readonly \ --binary /usr/bin/curl \ --add-endpoint api.github.com:443:read-only:rest:enforce \ --wait openshell policy list my-sandbox
What the docs’ first-policy tutorial shows
Before the rule, a curl to api.github.com from inside the sandbox is denied: the proxy answers 403 after CONNECT. After the rule, a GET works, and a POST to the issues endpoint is denied at layer 7 with policy_denied. The denial shows up in openshell logs, so you can see what the agent tried.
Defaults that surprise people (docs, schema and best practices)
- • enforcement defaults to audit, which logs a violation and allows it. Set enforce to actually block.
- • Without a protocol on the endpoint, there are no method or path restrictions at layer 7.
- • landlock.compatibility defaults to best_effort: if paths can’t be applied the sandbox can run without filesystem rules and logs a high-severity finding. Use hard_requirement to fail startup instead.
- • Binary rules need the real executable path, not a symlink. For a script, list the interpreter.
5. Running an Agent Inside It
The default workload image is nvcr.io/nvidia/base/ubuntu:24.04 unless the operator changes it: a minimal Ubuntu userspace with no agent CLI. So the quickstart gives you a clean box, not a working agent. To run one you bring an image that contains it. The docs’ walkthrough uses OpenCode with an OpenRouter key; the steps below are copied from it.
1. Import a provider profile and create the provider
openshell profile import \ --url https://raw.githubusercontent.com/NVIDIA/OpenShell/main/providers/openrouter.yaml openshell provider create \ --name openrouter \ --type openrouter \ --from-existing
2. Create the sandbox with the agent as its main process
openshell sandbox create \ --name my-agent \ --from ghcr.io/anomalyco/opencode:latest \ --provider openrouter \ -- opencode -m openrouter/nvidia/nemotron-3.5-lightning:free
3. Review and approve what the agent asked for
openshell rule get my-agent --status pending openshell rule approve my-agent --chunk-id <chunk-id> openshell rule reject my-agent \ --chunk-id <chunk-id> \ --reason "Not needed for this task."
How a denied request becomes a rule
When the agent reaches a destination the policy doesn’t allow, OpenShell denies it and drafts a proposal. The gateway runs the policy prover first and flags things like link-local reach or credentialed traffic it can’t inspect. By default every proposal waits for a person; automatic approval is opt-in. rule approve-all skips security-flagged proposals unless you add --include-security-flagged.
Shape for Claude Code (docs, sandboxes; the image is a placeholder you must build)
openshell sandbox create --from registry.example.com/your-org/claude-agent:latest -- claude
The overview page lists Claude Code, OpenCode, Codex and GitHub Copilot CLI as supported agents, and the run-your-first-agent page says OpenShell can run any agent available in a sandbox image.
Read what you pull
The profile import fetches a file from the main branch, and the example image uses a floating latest tag. Read the profile before you import it, and pin images by digest for anything beyond a demo. That is my advice, not a quote from the docs.
6. How It Differs From Container-Only Isolation
A plain docker run is a fine start, and OpenShell’s Docker and Podman drivers use containers underneath. What it adds is a policy language and a decision point that sits outside the workload.
A plain container
- • Egress is open by default; you bolt firewall rules on around it
- • Secrets usually arrive as environment variables the agent can read and leak
- • File access is whatever you mounted
- • No per-binary or per-request view of outbound traffic
- • Changing the limits means rebuilding the run command
OpenShell
- • Egress is default-deny, with rules per binary and endpoint, optionally per method and path
- • Placeholders in the environment; real credentials resolved only at approved endpoints
- • Landlock path allowlist, non-root identity and seccomp
- • A supervisor outside the workload makes the decisions, and the agent is frozen if the supervisor disconnects
- • Network rules hot-reload and denied requests become reviewable proposals
What it does not change
The container drivers still share the host kernel, like any container. The docs list a MicroVM driver (libkrun, with KVM on Linux and Hypervisor.framework on macOS) where the guest has no network device; that a separate guest kernel sits in between is my reading, not a docs claim. The best-practices page doesn’t state a threat model for kernel exploits, so don’t assume one.
7. Use Cases That Earn Their Keep
Four places where a policy sandbox is worth the setup time.
A coding agent with scoped egress
Allow the package registry and GitHub read-only for the binaries that need them (the docs show pip, uv, npm and gh examples) and nothing else.
Unattended runs with approval on demand
Leave an agent working. Denied destinations queue as proposals you review later, with prover findings attached.
Keeping real API keys out of the agent
Provider profiles inject placeholders and the key resolves only at the authorized host. Output isn’t scrubbed, so don’t print secrets into logs.
Policy as code for a team
The policy is YAML you version and review. The prover ships as a standalone openshell-prover CLI for CI, and the SDKs create sandboxes from code.
SDKs (README; they connect to a gateway and don’t install the CLI)
uv add openshell npm install @nvidia/openshell-sdk
It also pairs with a pre-install scan: vet a skill or MCP server first with the scanner I covered in SkillSpector, then run what you keep inside a sandbox. The scanner answers “what is in this?”, the sandbox answers “what can it do if it misbehaves?”.
8. When Not to Use It
An honest list. Most of it comes from the project’s own security best-practices page, which is refreshingly direct.
A moving 0.1.x target
Four stable releases between Sep 26 and Oct 13, Experimental interfaces that can change in a patch release and a flagged breaking change in v0.1.3. Pin versions and read the notes before building a compliance story on it.
Windows and unlisted hosts
Windows through WSL 2 is the only platform marked Experimental. Linux needs Landlock ABI 3 or newer, and Intel Macs aren’t listed in the matrix. The best-practices page calls NVIDIA device plugin compatibility with user namespaces unverified.
Nothing works out of the box
The default image has no agent. You pick or build an image, import provider profiles and iterate on a policy; the docs’ own walkthrough has you approving denied requests as proposals.
Not a full-containment promise
Each allowed endpoint is an exfiltration path: an agent can send workspace content, credentials or conversation history to any host you allow. Approving a proposal widens the policy until you recreate the sandbox.
Also remember
- • Several defaults are permissive: audit enforcement, no layer-7 rules until you set a protocol and Landlock best_effort. The docs say audit mode provides visibility but does not prevent unauthorized actions.
- • Broad binary globs such as /** let any matching executable authorize an endpoint. Keep them narrow.
- • The local gateway is meant for local use: TLS-enabled loopback gateways also accept plaintext HTTP for sandbox service hostnames by default, so any local process can reach exposed service URLs.
- • The README says telemetry is anonymous and operational, and can be turned off with OPENSHELL_TELEMETRY_ENABLED=false on the gateway.
- • The README suggests npx skills add NVIDIA/OpenShell for agent skills. Treat them like any third-party skill: read or scan them first.
✅ Good fit when...
- • You run coding or ops agents next to real credentials
- • You want egress allowlists per binary, not per container
- • You want a human approval trail for new access
- • You can pin versions and follow release notes
⚠️ Not a replacement for...
- • Reviewing what the agent changed: diffs, tests, logs
- • Least-privilege tokens issued upstream
- • A VM or separate host for the riskiest, untrusted work
- • A threat model you own and test
Golden rule
A sandbox shrinks the blast radius; it does not decide whether the agent should act. Start with enforce, default-deny, a scoped token and a throwaway workspace, then widen only what a denied request proves you need.
Conclusion
OpenShell is the clearest attempt I have seen to turn “what can this agent touch?” from a hope into a file you can review. Default-deny egress per binary, credentials as placeholders and a supervisor outside the workload are the right primitives, and the proposal-and-prover loop is a sensible answer to the agent that needs one more domain.
It is also a 0.1.x project that ships weekly. Try it on a throwaway repo, pin the version, set enforcement to enforce and read what the denial log tells you before you trust it with anything that matters. If your agents already hold production credentials and nobody owns that boundary, that is the kind of gap I close in project-rescue work.
Primary sources (checked 2026-10-14)
- NVIDIA/OpenShell — GitHub repository and README ↗
- Releases: v0.1.4 and earlier notes ↗
- OpenShell docs — overview and architecture ↗
- Policy schema and network rules ↗
- Security controls: defaults, risks and limitations ↗
- Support matrix and release channels ↗
- Run your first agent (OpenCode with OpenRouter) ↗
- NVIDIA developer blog — Add runtime controls to AI agents ↗



