supraj.dev

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.

Supraj Maripeddi · · 17 min read

An isometric gated society: a carpenter works inside a glass-walled flat with no door to the street, while a watchman at the only gate checks a list before letting one approved errand through.
Start hereYou've used a terminal. That's enough.
Leave knowingGateway, supervisor, sandbox, policies, providers and the prover.
VersionOpenShell v0.1.5, the latest release on 25 October 2026.

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:

The risks OpenShell is built for, from its overview page. [1]
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

OpenShell architecture You talk to the gateway, the control plane. Its compute driver builds one sandbox: an untrusted workload with all direct egress denied, holding the agent and the openshell-sandbox runtime, and a trusted supervisor. The two are joined by the Sandbox Protocol. The supervisor links to the gateway for policy, credentials and logs, and is the only thing that opens connections to the outside world: approved hosts are allowed, everything else is denied and logged. ONE SANDBOX You openshell CLI, terminal UI or SDK create · policy Gateway Control plane: sandboxes, auth, policy, providers, logs policy prover Compute driver Docker, Podman, VM or Kubernetes builds the boundary policy, credentials, logs (gateway JWT) Workload · untrusted all direct egress denied Agent Claude Code, Codex, OpenCode… openshell-sandbox names the calling program, hands over TCP and DNS Sandbox Protocol mutual TLS Supervisor · trusted • checks policy • adds allowed credentials • resolves DNS • opens approved connections • writes the log • keeps the gateway link ✕ Outside world api.github.com allowed by policy anything else denied and logged OpenShell architecture, stacked for small screens ONE SANDBOX You openshell CLI, terminal UI or SDK create · policy Gateway Control plane: sandboxes, auth, policy, providers, logs policy prover Compute driver builds the boundary policy, credentials, logs Workload · untrusted all direct egress denied Agent Claude Code, Codex, OpenCode… openshell-sandbox names the program, hands over TCP and DNS Sandbox Protocol (mutual TLS) Supervisor · trusted • checks policy • adds allowed credentials • resolves DNS • opens approved connections • writes the log • keeps the gateway link Outside world api.github.com anything else allowed by policy denied and logged
Whole picture

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.

Drawn from the architecture page of the OpenShell docs, simplified. [2]

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.

The sections of a policy file. [6]
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. pip is a Python script, so a rule for pip install names the Python interpreter, such as /usr/bin/python3.12 on 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 on 127.0.0.1 inside 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

  1. # Start a sandbox on the default policy: no network rules
  2. openshell sandbox create --name demo --from agent-tools:1.0 --no-auto-providers --detach -- sleep infinity
  3. Created sandbox: demo
  4. # Try to reach the GitHub API from inside it
  5. openshell sandbox exec -n demo -- curl -sS https://api.github.com/zen
  6. curl: (7) Failed to connect to api.github.com port 443 after 4 ms: Couldn't connect to server
  7. openshell logs demo --since 5m --source sandbox
  8. NET:OPEN [MED] DENIED /usr/bin/curl(0) -> api.github.com:443 [reason:transparent_tcp_policy_denied]
  9. # Allow read-only REST access for curl, while it runs
  10. openshell policy update demo --rule-name github_api --binary /usr/bin/curl --add-endpoint api.github.com:443:read-only:rest:enforce --wait
  11. ✓ Policy version 2 submitted (hash: ec35d20221e1)
  12. ✓ Policy version 2 loaded (active version: 2)
  13. # A read now gets through, and a write doesn't
  14. openshell sandbox exec -n demo -- curl -sS -o /dev/null -w "%{http_code}\n" https://api.github.com/zen
  15. 403
  16. # That 403 is the test machine's own web proxy. OpenShell let the GET out (log below).
  17. 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"}'
  18. {"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",…}
  19. openshell logs demo --since 5m --source sandbox
  20. HTTP:GET [INFO] ALLOWED GET https://api.github.com/zen [policy:github_api engine:l7]
  21. HTTP:POST [MED] DENIED POST https://api.github.com/repos/octocat/hello-world/issues [policy:github_api engine:l7] [reason:L7_REQUEST deny …]
Shown in full
Real output from OpenShell v0.1.5 in a disposable test environment on 25 October 2026, following NVIDIA's First Network Policy tutorial, trimmed. The test machine's own web proxy answered the allowed GET with 403; OpenShell's log shows it let the request out. [17]

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-only and enforcement: enforce, a GET passes and a POST gets a policy_denied reply.

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]

  1. Network policy allows the calling program and the destination.
  2. 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

  1. # Store a (fake) GitHub token as a provider and attach it
  2. openshell profile import -f providers/github.yaml
  3. Imported 1 provider profile.
  4. openshell provider create --name gh --type github --credential GITHUB_TOKEN=ghp_fake_demo_token_123
  5. ✓ Created provider gh
  6. openshell sandbox provider attach demo gh --wait
  7. demo / gh: ready (unspecified)
  8. Installed: credentials=true, policy=true, future process environment=true
  9. # What does the agent see?
  10. openshell sandbox exec -n demo -- printenv GITHUB_TOKEN
  11. openshell:resolve:env:v6891693927017443586_GITHUB_TOKEN
  12. # Allow curl to read PyPI, then try to send the token there
  13. openshell policy update demo --rule-name pypi --binary /usr/bin/curl --add-endpoint pypi.org:443:read-only:rest:enforce --wait
  14. ✓ Policy version 3 loaded (active version: 3)
  15. openshell sandbox exec -n demo -- bash -c 'curl -sS -H "Authorization: Bearer $GITHUB_TOKEN" https://pypi.org/simple/'
  16. {"error":"credential_endpoint_mismatch","message":"Credential is not authorized for this request endpoint"}
  17. openshell logs demo --since 1m --source sandbox
  18. HTTP:GET [HIGH] DENIED GET [policy:pypi engine:credential-binding] [reason:credential_endpoint_mismatch]
  19. FINDING:BLOCKED [HIGH] "Provider credential used at an unauthorized endpoint" [type:openshell.provider_credential.endpoint_mismatch]
Shown in full
Real output from the same v0.1.5 test sandbox, trimmed. The token is fake. PyPI was allowed by the network rule; the log shows the credential binding, not the network rule, stopped the request.

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.

Real results from the 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]

Runtimes in OpenShell v0.1.5. A Windows driver is listed as coming soon. [15] [2] [3]
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.

  1. NVIDIA OpenShell docs: Overview
  2. NVIDIA OpenShell docs: Architecture
  3. NVIDIA OpenShell docs: Installation
  4. NVIDIA OpenShell docs: Support Matrix
  5. NVIDIA OpenShell docs: Run Your First Agent
  6. NVIDIA OpenShell docs: Sandbox Policies
  7. NVIDIA OpenShell docs: Default Policy
  8. NVIDIA OpenShell docs: Network Rules
  9. NVIDIA OpenShell docs: Policy Schema
  10. NVIDIA OpenShell docs: Manage Sandbox Policies
  11. NVIDIA OpenShell docs: Policy Advisor
  12. NVIDIA OpenShell docs: Policy Prover
  13. NVIDIA OpenShell docs: Providers
  14. NVIDIA OpenShell docs: Provider Profiles
  15. NVIDIA OpenShell docs: Sandbox Runtimes
  16. NVIDIA OpenShell docs: Manage Sandboxes
  17. NVIDIA OpenShell docs: Write Your First Sandbox Network Policy
  18. NVIDIA OpenShell docs: Logging
  19. NVIDIA OpenShell docs: Upgrade to 0.1.0
  20. NVIDIA/OpenShell on GitHub, release v0.1.5: README, licence and example provider profiles
  21. NVIDIA Technical Blog: Run Autonomous, Self-Evolving Agents More Safely with NVIDIA OpenShell (16 March 2026)
  22. NVIDIA OpenShell docs: Gateway Configuration File
  23. Linux kernel documentation: Landlock, unprivileged access control
  24. NVIDIA OpenShell docs: Python SDK
  25. 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.