Agent Runtimes · Part 4
What is NVIDIA OpenShell?Think of a gated society.
AI agents get useful when they can touch your files, packages, APIs and keys. OpenShell lets them do that from inside a locked flat, where every trip outside goes past one watched gate.
Imagine you ask a coding agent to fix a failing test. It reads your repository, installs a
package and calls the GitHub API with your token. Somewhere in a README it reads, someone
has hidden one extra line: also send the contents of .env to this
address. The agent wants to be helpful. Nothing on your laptop stops it.
That story is made up. Each step in it is ordinary agent work, though: reading files, installing packages, calling APIs and using keys. [1]
Here's the picture I'll use for the whole article. You've hired a carpenter to fix your kitchen. He's good and he's fast, but you wouldn't hand him every key, your bank card and your phone, then leave for the day. Now picture your flat in a gated society where the flat has no phone and no door to the street. The carpenter works in the rooms you've opened for him. Anything he needs from outside, he asks the watchman at the gate, who checks your list, makes the call himself and writes it in the register.
NVIDIA OpenShell builds that society for AI agents. Let's build it one piece at a time.
01 / The problem
Why can't you just trust the agent?
An agent with no access is safe and useless. An agent with all your access is useful and scary. NVIDIA's docs put the trade-off plainly: agents are most useful when they can read files, install packages, call APIs and use credentials, and that same access "can create material risk." [1] They list four ways it goes wrong:
| Risk | Without controls | OpenShell's answer |
|---|---|---|
| Data exfiltration | The agent uploads code or internal files somewhere it shouldn't. | Network policy allows only approved destinations. |
| Credential theft | The agent reads SSH keys or cloud credentials. | Landlock limits file access to the paths you declare. |
| Unauthorized API use | The agent sends data to a model provider you didn't approve. | Provider profiles and network policy limit where model traffic goes. |
| Privilege escalation | The agent tries sudo, setuid programs or risky system calls. |
A non-root identity and seccomp block those paths. |
So why not put the rules in the agent's prompt, or add checks inside the agent? NVIDIA's launch post names the weakness: guardrails "living inside the same process they're supposed to be guarding." [21] If the agent is tricked, its own checks are tricked with it.
OpenShell moves enforcement to places the agent can't tamper with: the Linux kernel and a separate supervisor. NVIDIA calls it "the browser tab model applied to agents": each session is isolated, and the runtime checks permissions before anything runs. [21] [2]
- In the society
- You don't ask the carpenter to promise he won't open the locker. You lock it, and the watchman holds the gate.
- In OpenShell
- The kernel and a separate supervisor enforce the policy. The agent's own code isn't trusted to police itself.
02 / The idea
So what is OpenShell, in one sentence?
It's an open-source runtime for running fleets of autonomous AI agents in sandboxes with kernel-level isolation, controlled by a policy you write in YAML. [1] NVIDIA develops it in the open on GitHub under the Apache 2.0 licence. [20]
It governs agents in two ways. [2]
- Enforcement while the agent runs. Kernel controls limit which files it can open and which system calls it can make, and every network connection is checked against policy before it leaves the sandbox. Agents never see real credentials.
- Proposed rules that are checked before they land. Formal verification flags risky new access in the rules an agent asks for, and flagged proposals wait for a human. [11]
It works with the agents you already use. The docs name Claude Code, OpenCode, Codex and GitHub Copilot CLI, and OpenShell can run any agent you can put in a sandbox image. [1] [5]
03 / The pieces
Who does what when you create a sandbox?
The gateway is the society office, the control plane. It checks who you
are, remembers every sandbox, delivers policy and settings, attaches providers and
coordinates connections into sandboxes. You talk to it through the
openshell command line, a live terminal dashboard (openshell term)
or an SDK. [2] [16]
[24]
The supervisor is the watchman. It lives on the trusted side of the boundary. It checks every request against the policy, supplies credentials, resolves DNS, opens approved connections and keeps the link to the gateway alive. [2]
The sandbox runtime is the intercom in the flat. It lives inside the boundary with the agent, starts it, owns its processes, works out which program made each request, and hands the agent's outbound TCP connections and DNS lookups to the supervisor. Because it shares space with an untrusted agent, it "never makes policy decisions." [2]
This is the part worth slowing down for. The agent isn't sitting behind a proxy that it could choose to ignore. Its workload has no network path at all except one private channel to the supervisor. On Docker, for example, the workload container has networking turned off, and the supervisor runs in a container of its own. [2]
That channel is the OpenShell Sandbox Protocol: one mutually authenticated HTTP/2 connection carrying many streams. Each TCP connection gets its own stream, so a slow download can't block DNS or process control. It also fails closed. The agent doesn't start until the supervisor confirms the boundary, and if the supervisor's connection drops, the agent is frozen. [2]
Figure 1 · Follow one request
The whole picture. The workload has no direct route out; the supervisor, on the trusted side, is the only piece that talks to the outside world. Press the button to follow one request.
04 / The rules
What can a policy actually control?
A policy is a YAML file that says what the sandbox may touch, and OpenShell denies anything it doesn't allow. [6] The most useful thing to learn first isn't the syntax. It's when each part can change.
| Section | What it controls | Can it change while running? |
|---|---|---|
filesystem_policy |
Paths processes can read, or read and write. Enforced by Landlock in the kernel. | No, fixed at startup |
landlock |
Whether the sandbox still starts if those file rules can't be applied. | No, fixed at startup |
process |
The user and group that processes run as. | No, set at creation |
network_policies |
Which program can reach which host, and which requests it can send. | Yes, reloads live |
network_middlewares |
Extra inspection, changes or blocking of traffic the rules allow. | Yes, reloads live |
In the society, room keys are handed over when the carpenter arrives. To change which rooms he can use, you start a new visit. The gate list, though, you can update any time.
If nothing else supplies a policy, you get OpenShell's restrictive default. It allows
read and write in the working directory, /tmp and /dev/null,
read-only access to system paths such as /usr, /lib and
/etc, and defines no network rules, so every outbound connection is denied.
[7]
What does that feel like from inside? Here's a real run on v0.1.5. The directory's own permissions say anyone can read it, yet the listing fails:
$ openshell sandbox exec -n demo -- ls /home
ls: cannot open directory '/home': Permission denied
$ openshell sandbox exec -n demo -- stat -c "%A %U %n" /home
drwxr-xr-x root /home
The same image lists /home fine under plain Docker. The difference is
Landlock, a Linux kernel feature that lets a process restrict its own
file access, even unprivileged processes, and the limit holds for its children too.
[23] /home isn't on the default policy's
list, and paths that aren't listed are off limits. [7]
[9]
The process side is just as strict. Agents run as one non-root user with no Linux
capabilities, and seccomp, the kernel's system-call filter, sits in the path of their
network operations. [2] Docker and Podman refuse an image
whose user is root unless the policy you pass at creation sets a non-root
run_as_user.
[7]
One last term: the effective policy is yours plus any network rules
that attached providers add, and it's the one the sandbox enforces.
openshell policy get demo --full shows it. [10]
05 / The gate
How does OpenShell decide on a network call?
Every network rule answers one question: which program may talk to which host? A rule has
two lists, endpoints and binaries, and it allows every listed
binary to reach every listed endpoint. [8] This one, from
NVIDIA's First Network Policy tutorial, lets curl read from the GitHub API:
[17]
network_policies:
github_api:
endpoints:
- host: api.github.com
port: 443
protocol: rest
enforcement: enforce
access: read-only
binaries:
- path: /usr/bin/curl
The check happens in two stages. [8] First, when a
program opens a connection, OpenShell checks the host, the port and the program. No
matching rule, no connection. Second, if the endpoint sets a protocol such as
rest, OpenShell reads each request on that connection and checks it too: the
method, path and query for REST. That's how you allow reading an API but not writing to
it.
The access presets do the common cases for you. read-only
allows GET, HEAD and OPTIONS.
read-write adds POST, PUT and PATCH,
and full allows every method and path. [9]
Three details matter more than they look. [8]
-
Programs are matched by their real path, as the kernel reports it, not
by the command you typed.
pipis a Python script, so a rule forpip installnames the Python interpreter, such as/usr/bin/python3.12on Ubuntu 24.04. A rule also covers the processes a listed program starts. And OpenShell records a hash of each program the first time it connects, then denies later connections if that file changes. - Deny wins. Rules aren't an ordered firewall list. Every matching rule adds access, and on an enforcing endpoint a matching deny rule beats any allow, wherever it sits in the file.
-
Private addresses are blocked by default to prevent server-side request
forgery, though a rule you write for an exact hostname can reach the private addresses
it resolves to. No rule ever opens a connection to loopback or link-local addresses,
including the cloud metadata address
169.254.169.254; a service on127.0.0.1inside the sandbox stays reachable.
One default to watch: when you leave out enforcement, it's
audit. Audit lets a request that breaks the rules through and only logs it.
[8] That's handy for seeing what a new rule would block.
But if you want a rule to stop things, write enforcement: enforce
explicitly. I'd make that a habit.
Figure 2 · A policy change, live
- # Start a sandbox on the default policy: no network rules
- openshell sandbox create --name demo --from agent-tools:1.0 --no-auto-providers --detach -- sleep infinity
- Created sandbox: demo
- # Try to reach the GitHub API from inside it
- openshell sandbox exec -n demo -- curl -sS https://api.github.com/zen
- curl: (7) Failed to connect to api.github.com port 443 after 4 ms: Couldn't connect to server
- openshell logs demo --since 5m --source sandbox
- NET:OPEN [MED] DENIED /usr/bin/curl(0) -> api.github.com:443 [reason:transparent_tcp_policy_denied]
- # Allow read-only REST access for curl, while it runs
- openshell policy update demo --rule-name github_api --binary /usr/bin/curl --add-endpoint api.github.com:443:read-only:rest:enforce --wait
- ✓ Policy version 2 submitted (hash: ec35d20221e1)
- ✓ Policy version 2 loaded (active version: 2)
- # A read now gets through, and a write doesn't
- openshell sandbox exec -n demo -- curl -sS -o /dev/null -w "%{http_code}\n" https://api.github.com/zen
- 403
- # That 403 is the test machine's own web proxy. OpenShell let the GET out (log below).
- openshell sandbox exec -n demo -- curl -sS -X POST https://api.github.com/repos/octocat/hello-world/issues -H 'Content-Type: application/json' -d '{"title":"oops"}'
- {"error":"policy_denied","policy":"github_api","rule":"POST /repos/octocat/hello-world/issues","detail":"POST /repos/octocat/hello-world/issues not permitted by policy","layer":"l7",…}
- openshell logs demo --since 5m --source sandbox
- HTTP:GET [INFO] ALLOWED GET https://api.github.com/zen [policy:github_api engine:l7]
- HTTP:POST [MED] DENIED POST https://api.github.com/repos/octocat/hello-world/issues [policy:github_api engine:l7] [reason:L7_REQUEST deny …]
Every decision lands in the sandbox log as an OCSF event, an open standard format for security logs. Turn on the OCSF JSON export and you can ship full records to the security tools you already use, though the docs call that collection best-effort. [18]
- In the society
- The gate list says who may call which shop, and for what. Asking the price is fine; placing an order isn't.
- In OpenShell
-
A rule names programs and endpoints. With
protocol: rest,access: read-onlyandenforcement: enforce, aGETpasses and aPOSTgets apolicy_deniedreply.
06 / The keys
How can an agent use a key it never sees?
Agents need keys: a model provider's API key, a GitHub token. The easy way is an environment variable, and that's the trap. The docs say it bluntly: the agent can read plain environment values directly, so to hide a secret from it, attach the secret through a provider instead. [16]
A provider is a stored credential with a name, like gh or
openrouter. A provider profile describes a kind of
provider: its credentials, the endpoints they may be sent to and the programs allowed to
reach those endpoints. [13] [14] By
default the gateway uses only the profiles you import; the repository's
providers/ folder has examples for GitHub, OpenRouter, Anthropic, OpenAI and
more. [22] [20]
Here's the trick. When a provider is attached, OpenShell puts an opaque placeholder in the agent's environment instead of the real value. When the agent sends a request containing that placeholder, the proxy swaps in the real key just before forwarding it, but only if two checks pass. [13]
- Network policy allows the calling program and the destination.
- The credential's binding covers that host, port and path.
If the network rule allows the destination but the binding doesn't cover it, the request
gets HTTP 403 with the reason credential_endpoint_mismatch, and the real key
never leaves. [13] Watch it happen with a fake token:
Figure 3 · The chit, not the card
- # Store a (fake) GitHub token as a provider and attach it
- openshell profile import -f providers/github.yaml
- Imported 1 provider profile.
- openshell provider create --name gh --type github --credential GITHUB_TOKEN=ghp_fake_demo_token_123
- ✓ Created provider gh
- openshell sandbox provider attach demo gh --wait
- demo / gh: ready (unspecified)
- Installed: credentials=true, policy=true, future process environment=true
- # What does the agent see?
- openshell sandbox exec -n demo -- printenv GITHUB_TOKEN
- openshell:resolve:env:v6891693927017443586_GITHUB_TOKEN
- # Allow curl to read PyPI, then try to send the token there
- openshell policy update demo --rule-name pypi --binary /usr/bin/curl --add-endpoint pypi.org:443:read-only:rest:enforce --wait
- ✓ Policy version 3 loaded (active version: 3)
- openshell sandbox exec -n demo -- bash -c 'curl -sS -H "Authorization: Bearer $GITHUB_TOKEN" https://pypi.org/simple/'
- {"error":"credential_endpoint_mismatch","message":"Credential is not authorized for this request endpoint"}
- openshell logs demo --since 1m --source sandbox
- HTTP:GET [HIGH] DENIED GET [policy:pypi engine:credential-binding] [reason:credential_endpoint_mismatch]
- FINDING:BLOCKED [HIGH] "Provider credential used at an unauthorized endpoint" [type:openshell.provider_credential.endpoint_mismatch]
Notice where the real token lives: with the gateway and the supervisor, never inside the workload. The architecture docs put it nicely: the sandbox side "holds nothing worth stealing." [2]
- In the society
- The watchman keeps your card. The carpenter gets a chit that's only good at the timber shop. Anywhere else, it's worthless.
- In OpenShell
-
The agent sees
openshell:resolve:env:…. The proxy resolves it only at the endpoints the provider's profile binds.
07 / Asking for more
What happens when the agent needs something new?
Deny-by-default has an obvious cost: the agent gets stuck the first time it needs a host you didn't think of. OpenShell turns each block into a request you can review.
Even with nothing switched on, OpenShell drafts rules from the connections it blocks,
one per program, host and port, and parks them for your review.
[11] In the test run from Figure 2, the blocked
curl call produced this draft:
$ openshell rule get demo --status pending
Network Rules: (version 1, 1 chunk)
Chunk: 9f890b13-3607-4b05-9762-f737c76ec96e
Status: pending
Rule: allow_api_github_com_443
Binary: /usr/bin/curl
Confidence: 65%
Rationale: Allow curl to connect to api.github.com:443 (HTTPS).
Prover: prover: no new findings
Candidate: 689f4f46ab67
Endpoints: api.github.com:443 [L4]
Binaries: /usr/bin/curl
You approve it with openshell rule approve demo --chunk-id <id>, or
reject it with a reason. Approved rules take effect without a restart, because network
rules are live. [5] [11]
Notice the draft is [L4]: it allows the connection without inspecting
requests. If you want the read-only version from Chapter 5, write that rule yourself.
Switch on the policy advisor and the agent can take part too. It's off
by default; the agent_policy_proposals_enabled setting turns it on. The
agent then gets a guide and a local API at http://policy.local to read the
current policy, see recent denials and submit a proposal scoped to the host, port and
program that need access, plus the method and path for HTTP APIs. [11]
Every proposal, drafted or agent-written, is checked twice before it reaches you. The policy prover's risk check flags new access such as reaching a link-local or cloud-metadata address, using a provider credential at a new host, or using a new HTTP method where a credential is already in use. OpenShell also flags risky destinations, such as private addresses and wildcard hosts. [11]
You can opt in to automatic approval, which approves a proposal when neither check flags anything. Read the fine print first. The checks don't treat a new public host as risky when no credential applies there, so in automatic mode programs in the sandbox can gain access to new public hosts without your review. [11] I'd keep manual review, the default, for any sandbox that can see real data.
08 / The proof
How do you know a policy change is safe?
Reading YAML diffs by eye works until the policy gets long. The policy prover checks policies with an SMT solver, a tool that reasons over every request its model can represent instead of a few test cases. [12] Besides the risk check from Chapter 7, it runs a boundary check: does this candidate policy allow anything beyond a boundary policy, the most access you'd ever allow? [12]
You run it with openshell-prover check candidate.yaml --boundary
boundary.yaml. It answers within_boundary (exit code 0) or
exceeds_boundary (exit code 1) with a counterexample. If it can't run the
check, say a file is missing, that's error (exit code 2), and when it can't
decide, it says unsupported or inconclusive (exit code 3)
instead of guessing. [12] The docs say the command is
mainly meant for agents: a parent agent can check that a policy it writes for a subagent
stays inside its own limits. The exit codes make it just as easy to drop into CI.
[12]
Figure 4 · Four changes, four verdicts
Boundary
version: 1
filesystem_policy:
read_only:
- /usr
- /etc
Candidate
version: 1
filesystem_policy:
read_only:
- /usr
openshell-prover 0.1.5 says
result: within_boundary
coverage: domains=filesystem,network_l4,network_rest,process,landlock
exit=0
Reading /usr is inside a boundary that allows reading /usr and
/etc. Pass.
openshell-prover 0.1.5 binary, run on these small
files on 25 October 2026; the exit= line is the shell's exit code. The
first two pairs follow the examples in the prover docs.
[12]
Two honest limits. The check covers only the policy features the prover models; GraphQL,
MCP and JSON-RPC rules, for example, come back unsupported, and anything
but within_boundary counts as a failure. And a pass doesn't mean the policy
is as narrow as it could be, or safe for the task. [12]
09 / The buildings
Where does it run?
A gateway runs its sandboxes on one compute runtime, picked by its driver, and the command-line workflow stays the same on all of them. [15]
| Runtime | Use it for | How the agent is fenced in | Key requirements |
|---|---|---|---|
| Docker | Local development, single machines | Supervisor in its own container; workload networking off | Docker Desktop or Engine 28.0+ |
| Podman | Rootless Linux, no Docker daemon | Supervisor in its own container; workload networking off | Podman 5.x, cgroups v2, an active Podman user socket |
| MicroVM | A VM boundary instead of a container | Supervisor on the host; guest has no network device | Hypervisor.framework or KVM |
| Kubernetes | Shared clusters, remote compute, GPUs | Supervisor in its own pod; NetworkPolicy allows only it | Agent Sandbox controller, a CNI that enforces NetworkPolicy |
With no driver set, the gateway tries Kubernetes, then Podman, then Docker. The VM driver is never picked automatically. [15]
The Kubernetes row is where this series joins up. OpenShell's Kubernetes driver needs the Agent Sandbox controller, the project from Part 1. [15] It comes with a warning: the cluster's CNI must enforce NetworkPolicy, or sandbox pods can bypass OpenShell's network policy. [15]
My favourite line in the architecture docs explains why the same policy works on a laptop and on a cluster: "The runtime's job is to build the boundary and prove it's in place. It never decides whether a request is allowed." [2]
10 / Hands on
How do you try it yourself?
You need Linux, macOS on Apple Silicon or Windows with WSL 2 (experimental), plus Docker, Podman or host virtualization. [20] One command installs the CLI, the policy prover and a local gateway; the second checks the CLI can reach it. [3]
curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh | sh
openshell status
That pipes a script from the internet into your shell. If you'd rather look first, read
install.sh on
GitHub, and set OPENSHELL_VERSION to a release tag to pin a version.
[3]
Your first policy
NVIDIA's First Network Policy tutorial is the flow from Figure 2. It needs an image with
curl in it, so swap the example image name for your own:
[17]
openshell sandbox create \
--name demo \
--from registry.example.com/team/agent-tools:1.0 \
--no-auto-providers
In the sandbox shell, run curl -sS https://api.github.com/zen and watch it
fail. Then, in a second terminal on your machine:
openshell logs demo --since 5m --source sandbox
openshell policy update demo \
--rule-name github_api \
--binary /usr/bin/curl \
--add-endpoint api.github.com:443:read-only:rest:enforce \
--wait
Retry the curl and it works. Try a POST and it's denied. In our
v0.1.5 run the blocked call printed curl: (7) Failed to connect rather than
the tutorial's curl: (56) Received HTTP code 403 from proxy after CONNECT;
both mean the connection was denied. Clean up with
openshell sandbox delete demo. [17]
A real agent
The Run Your First Agent guide runs OpenCode against OpenRouter. Set
OPENROUTER_API_KEY first, then: [5]
openshell profile import \
--url https://raw.githubusercontent.com/NVIDIA/OpenShell/main/providers/openrouter.yaml
openshell provider create \
--name openrouter \
--type openrouter \
--from-existing
openshell sandbox create \
--name my-agent \
--from ghcr.io/anomalyco/opencode:latest \
--provider openrouter \
-- opencode -m openrouter/nvidia/nemotron-3.5-lightning:free
When the agent hits a host it isn't allowed, list the drafts with
openshell rule get my-agent --status pending and approve only the ones you
meant. [5]
Glossary
The words, in one place
- Sandbox
- One isolated environment for an agent: an untrusted workload plus its trusted supervisor.
- Gateway
- The control plane. Manages sandboxes, identity, policy, providers and logs.
- Compute driver
- The part that creates sandboxes on Docker, Podman, a MicroVM or Kubernetes, and builds the network fence.
- Supervisor
- The trusted process that checks requests against policy, adds credentials and opens approved connections.
- Sandbox runtime (
openshell-sandbox) - The piece inside the boundary that starts the agent, identifies programs and hands traffic to the supervisor.
- Sandbox Protocol
- The single mutually authenticated HTTP/2 connection between the supervisor and the sandbox runtime.
- Policy
- A YAML file listing what a sandbox may touch. Anything not allowed is denied.
- Base and effective policy
- Your chosen policy, and that policy plus the rules attached providers add.
- Landlock
- A Linux kernel feature that lets a process restrict its own file access.
- seccomp
- A Linux kernel feature that filters the system calls a process can make.
- Request inspection
- Checking each request on an allowed connection, such as its HTTP method and path.
- Enforce and audit
- Enforce blocks requests that break a rule. Audit, the default, lets them through and logs them.
- Provider and provider profile
- A stored credential, and the description of where that kind of credential may be used.
- Placeholder
- The
openshell:resolve:env:…value an agent sees instead of a real secret. - Policy advisor
- The optional feature that lets an agent propose new network rules for review.
- Policy prover
- OpenShell's solver-based checker for proposals and for boundary checks.
- OCSF
- Open Cybersecurity Schema Framework, an open standard format for security events.
Quiz
Check your understanding
Your agent's instructions say "never upload files". Why isn't that enough?
That check runs inside the agent, so a tricked agent skips it. OpenShell enforces policy from the kernel and a separate, trusted supervisor that the agent can't change or get around.
You change a sandbox's policy while it runs. Which parts can actually change?
Network rules and network middleware. Filesystem, Landlock and process settings are fixed once the sandbox starts.
A rule gives curl protocol: rest and access:
read-only but no enforcement. What happens to a POST?
It goes through and is logged, because the default enforcement is audit. Add
enforcement: enforce to block it.
The agent runs printenv GITHUB_TOKEN and sees
openshell:resolve:env:…. When is the real token used?
Only when a request is allowed by network policy and the destination's host, port and path are covered by the provider's binding. Then the proxy swaps it in on the way out.
openshell-prover exits with code 3. Did your policy pass?
No. Code 3 means unsupported or inconclusive. Only
within_boundary, exit code 0, is a pass.
Agent Runtimes series
Keep going
- Part 1: Kubernetes Agent Sandbox, explained like a hotel. The controller OpenShell's Kubernetes driver builds on.
- Part 2: Agent Substrate, explained like a shared office. How agent environments can pause and come back.
- Part 3: Google AX, with Agent Substrate. How tasks get assigned to those environments.
- AI Guardrails: the runtime checks around a model's inputs and outputs, to pair with OpenShell's checks around what an agent does.
Sources
Sources
OpenShell documentation and code at release v0.1.5 (commit bdb956f). All
checked 25 October 2026.
- NVIDIA OpenShell docs: Overview
- NVIDIA OpenShell docs: Architecture
- NVIDIA OpenShell docs: Installation
- NVIDIA OpenShell docs: Support Matrix
- NVIDIA OpenShell docs: Run Your First Agent
- NVIDIA OpenShell docs: Sandbox Policies
- NVIDIA OpenShell docs: Default Policy
- NVIDIA OpenShell docs: Network Rules
- NVIDIA OpenShell docs: Policy Schema
- NVIDIA OpenShell docs: Manage Sandbox Policies
- NVIDIA OpenShell docs: Policy Advisor
- NVIDIA OpenShell docs: Policy Prover
- NVIDIA OpenShell docs: Providers
- NVIDIA OpenShell docs: Provider Profiles
- NVIDIA OpenShell docs: Sandbox Runtimes
- NVIDIA OpenShell docs: Manage Sandboxes
- NVIDIA OpenShell docs: Write Your First Sandbox Network Policy
- NVIDIA OpenShell docs: Logging
- NVIDIA OpenShell docs: Upgrade to 0.1.0
- NVIDIA/OpenShell on GitHub, release v0.1.5: README, licence and example provider profiles
- NVIDIA Technical Blog: Run Autonomous, Self-Evolving Agents More Safely with NVIDIA OpenShell (16 March 2026)
- NVIDIA OpenShell docs: Gateway Configuration File
- Linux kernel documentation: Landlock, unprivileged access control
- NVIDIA OpenShell docs: Python SDK
- NVIDIA/OpenShell pull request #3195: remove managed inference routes
Written with AI assistance. Every technical claim was checked against the original sources listed above and reviewed by Supraj.