OpenShell sandboxes
Overview
Section titled “Overview”NVIDIA OpenShell runs AI agents in sandboxes. Every sandbox has a policy that says which hosts it may reach, which requests it may send, and which files it may read or write. OpenShell denies everything else.
Shield360 can be the source of that policy. You set the policy once in Shield360, under change control. Shield360 translates it to an OpenShell sandbox policy. The Shield360 collector on each OpenShell host then fetches the policy, verifies it and applies it, and reports the result back to Shield360.
What Shield360 does with OpenShell:
- Translates. Shield360 turns this environment’s enforcement policy into an OpenShell policy (schema version 1). The same policy always gives the same file, so its hash identifies it.
- Reports. Shield360 lists every rule that enforces something and what OpenShell does with it. Nothing is dropped silently.
- Signs. Each collector gets a policy bundle signed for that machine only. The collector applies nothing it has not verified.
- Respects change control. Collectors receive the policy as applied. A change waiting for approval is not delivered until someone approves it. Each bundle names the policy versions it was translated from.
- Keeps credentials in OpenShell. Shield360 never puts a credential in a policy file, a bundle or a report. Gateway addresses, gateway credentials and provider credentials stay in OpenShell’s own configuration.
Tested against OpenShell 0.1.5.
Set the policy
Section titled “Set the policy”There is no separate OpenShell policy to write. OpenShell enforces the parts of the enforcement policy it can. On Govern → Policies & rules:
- AI tools. Each AI tool you allow becomes a rule that lets the sandbox reach that vendor’s model API and product hosts. A blocked tool is left out, so OpenShell denies it. Your own AI sites and your environment’s cloud AI endpoints are included too.
- Approved models. When Approved models is set to Block, providers outside the approved list are left out. When it is set to Warn, they are allowed and every request to them is logged.
- Coding agents → Agent sandboxes. This section is only for sandboxes:
- Sandbox egress lists the other hosts sandboxes may reach. For each rule you set the ports and how much is allowed: all requests, read only, read and write, or only requests you list (for example
GET /repos/**). You can also refuse some requests outright and name the programs that may connect. Choose Block to refuse anything outside the rule, or Warn to log it and let it through. - Sandbox files adds directories that sandboxes may read or write. Shield360 never grants
/, a home directory, a credential store (.ssh,.aws,.kube,.gnupg…), a key file, an.envfile or a container runtime socket.
- Sandbox egress lists the other hosts sandboxes may reach. For each rule you set the ports and how much is allowed: all requests, read only, read and write, or only requests you list (for example
These are ordinary enforcement settings, so they work like every other setting:
- An environment can override them.
- A freeze stops changes to them.
- When approval is required, a change waits for a second person.
- Every applied change is recorded as a version.
Turn on delivery
Section titled “Turn on delivery”- Install the Shield360 collector on each machine that runs the OpenShell CLI against your gateway, and enroll it in the environment. See Installation.
- Open Policies → OpenShell sandboxes for that environment.
- Turn on Deliver this environment’s policy to OpenShell and choose how it is delivered:
| Delivery | What OpenShell does | Use it when |
|---|---|---|
| Each running sandbox (default) | Each sandbox’s network rules are replaced live (openshell policy set NAME --wait). Provider credential rules attached to the sandbox keep working. Filesystem and Landlock rules apply when a sandbox is created with the policy file, because OpenShell fixes them at start-up. | Developers and agents create their own sandboxes and use OpenShell providers for credentials. |
| The gateway’s global policy | Every sandbox on the gateway is held to exactly this policy (openshell policy set --global), and no sandbox can change its own. Provider rules are not added under a global policy, so allow the provider hosts in Sandbox egress. | One central policy must hold every sandbox, with no exceptions. |
| The policy file only | Nothing is applied. The collector keeps the verified file for openshell sandbox create --policy and for image builds. | You create sandboxes from scripts or bake the policy into images. |
- Optionally:
- Name the sandboxes to deliver to. Leave the list empty to deliver to every running sandbox.
- Name the gateway as the OpenShell CLI knows it (
openshell gateway add --name). Leave it empty to use the CLI’s active gateway.
A change freeze stops changes to delivery settings, and a required change comment is required here too. Every change is audited.
The page also shows:
- Delivery status for each collector and gateway: the result, the policy hash it applied (and whether that hash is current), the policy versions, the OpenShell version and each sandbox’s result.
- What OpenShell enforces: every rule, with the reason when OpenShell enforces it only in part or not at all.
- Policy file: exactly what collectors receive, with copy and download.
What OpenShell enforces
Section titled “What OpenShell enforces”| Shield360 rule | In OpenShell | Notes |
|---|---|---|
| AI tool allowed | network_policies.shield360_ai_<vendor>. Model APIs use protocol: rest, enforcement: enforce, access: full; product hosts are connection only. | Every program in the sandbox may connect (/**), because Shield360’s AI tool rules are not per program. |
| AI tool set to warn | The same rule with enforcement: audit | Partial. Requests are allowed and logged. OpenShell cannot ask the person first. |
| AI tool blocked | Left out | Denied by default. |
| Approved providers (Block) | Providers outside the list are left out | Translated. |
| Approved providers (Warn) | Providers outside the list are audited | Partial. |
| Approved model names | — | Not enforced. The model name travels in the request body, which OpenShell’s rules cannot read. OpenShell removed its inference routing (inference.local) in 0.1.0 and does not select or rewrite models. |
| Your AI sites | network_policies.shield360_custom_ai_hosts: the host and **.host | Warn is allowed and logged per connection. An IP address is also listed under allowed_ips, so private addresses work. |
| Your cloud AI endpoints | network_policies.shield360_ai_endpoints | They follow their provider’s action. |
| Sandbox egress | network_policies.shield360_egress_<name>: host, port or ports, access or rules (allow method and path), deny_rules, binaries. Block uses enforcement: enforce; Warn uses audit. | Connection-only rules have no protocol. |
| Sandbox files | filesystem_policy.read_only and read_write, on top of OpenShell’s system paths and the working directory | Translated. |
| Secret files (coding agents) | Credential stores outside the working directory are never granted | Partial. OpenShell’s filesystem policy is an allowlist of directories, so it cannot exclude an .env file inside the working directory. Shield360’s coding-agent hooks still check those reads. |
| Failing closed | landlock.compatibility: hard_requirement | A sandbox that cannot enforce the filesystem policy does not start. |
| Sensitive data in prompts | — | Not enforced. OpenShell does not inspect content. Its only built-in content middleware is a fixed demonstration redactor. |
| Prompt injection | — | Not enforced. |
| Edit rules, expensive patterns | — | Not enforced. OpenShell cannot make part of the working directory read-only. |
| Company AI accounts only | — | Not enforced. |
| Sequence policies | — | Not enforced. OpenShell rules apply to one request at a time. |
| Browser-only settings, people and group targets | — | Not applicable. A sandbox gets the environment’s policy. |
Shield360 does not write the process section. It has no equivalent rule, so OpenShell and the image keep deciding which user the sandbox runs as.
Where OpenShell does not enforce a rule, Shield360’s own enforcement points still do: the coding-agent hooks inside the sandbox, the AI proxy and the browser extension.
How delivery works
Section titled “How delivery works”Each collector pass delivers on machines where the openshell CLI is on the PATH. To deliver now, run:
shield360 collector openshell syncTo verify the policy and print it without applying anything, add --dry-run. To see what this machine last applied, run shield360 collector openshell status.
For each delivery, the collector:
- Fetches the bundle from
GET /api/collector/device/openshell/policywith its collector token. While delivery is off, the platform answers204and the collector changes nothing. - Verifies the bundle before anything is written:
- The HMAC-SHA256 signature is checked over the exact payload, under a key only this collector and the platform can derive from the collector’s token.
- The policy file’s SHA-256 is checked against the hash in the signed payload.
- A bundle older than the last one applied is refused.
- Writes the policy beside the last good one and hands it to the OpenShell CLI.
- Replaces
policy.yamlatomically, but only when OpenShell accepts the policy. If OpenShell refuses it,policy.yamlstays the last good policy, and OpenShell keeps its own last loaded policy. - Reports to
POST /api/collector/device/openshell/status. The report contains hashes, versions, names and an error with credentials masked. A change of result is also recorded in the audit log.
The policy and state are kept in the collector’s config directory under openshell/. When the collector runs as a system service, they are kept in the system directory: /etc/shield360/openshell on Linux, /Library/Application Support/Shield360/openshell on macOS and %ProgramData%\Shield360\openshell on Windows.
The OpenShell CLI on the machine runs as the collector’s account, against that account’s gateway configuration. Run the collector as the account that registered the gateway (openshell gateway add), or point the CLI at the gateway with OpenShell’s own environment variables, such as OPENSHELL_GATEWAY_ENDPOINT. To use a CLI that is not on the PATH, set SHIELD360_OPENSHELL_CLI. Set SHIELD360_OPENSHELL=0 to stop automatic delivery on a machine, or SHIELD360_OPENSHELL=1 to keep the policy file on a machine without the CLI.
Kubernetes and Helm
Section titled “Kubernetes and Helm”OpenShell’s Helm chart has no values for sandbox policies, and a Shield360 server should not hold your gateway’s credentials. In a cluster, run the collector next to the gateway:
- Enroll a collector for the environment.
- Run
shield360 collector openshell syncas a CronJob, for example every five minutes. The CronJob needs:- the collector’s config (platform URL and token) from a Secret,
- the
openshellCLI, - the gateway’s client credentials, mounted the way OpenShell documents for its CLI,
OPENSHELL_GATEWAY_ENDPOINTset to the gateway’s in-cluster service.
- Choose The gateway’s global policy to hold every sandbox in the cluster, or Each running sandbox.
If OpenShell cannot load a policy, its server.policyValidationFailureMode Helm value decides what happens: fail_closed (the default) blocks traffic, and retain_last_valid keeps the last valid policy.
Security notes
Section titled “Security notes”- Bundles are signed per machine. A bundle signed for one machine does not verify on another, and a policy file changed in transit or at rest is refused. The signing key is derived from the collector’s token, so whoever can read that token could also sign. TLS protects the token in transit. ECDSA P-256 signing, with the public key pinned in the collector, is planned.
- Server checks. The routes check permissions on the server:
- Reading needs View agent policies.
- Changing delivery needs Manage agent policies and Change what is collected.
- A request that names another environment is refused.
- Malformed JSON is refused with
400. - Only machine collectors receive bundles.
- Global delivery overrides provider credential rules. OpenShell does not add provider rules under a global policy. With global delivery, allow your providers’ hosts in Sandbox egress. The credentials themselves stay in OpenShell.
- New sandboxes. A sandbox created between two collector passes starts with the policy it was created with. OpenShell’s own default denies all network access. To start sandboxes with the Shield360 policy at once, create them with
--policyand the collector’spolicy.yaml.