Skip to content

NVIDIA OpenShell: launch model, policy model and open conflicts ​

Gate note for FOUND-03 (decisions D-16, D-17, D-18). Blocks src/runtime/openshell.ts (Phase 3).

Read date: 2026-10-21 (ISO 8601).

Official URLs read ​

Version caveat and conflict ​

The pages read show "Latest (v0.1.5)". The official pages do not state the host CLI version. An unverified check reported the host CLI as 0.1.2 from openshell sandbox create --help. That CLI was not run again in this phase, so the mismatch is recorded, not resolved. Phase 3 must pin one version and read the matching documentation index (/v0.1.x/llms.txt), which the pages list.

Spec questions and sourced answers ​

Q1. How OpenShell launches inside the container ​

Answer: OpenShell's own gateway launches each sandbox. It does not run inside a container that Realm creates.

From the Architecture page: "When you create a sandbox, its compute driver provisions a workload and a separate supervisor, establishes their protected channel, and builds the isolation boundary; the supervisor confirms that boundary before starting the agent."

The driver table on the same page gives the Podman row as: "Its own container | Authenticated Unix socket on a driver-owned volume | Workload container has networking turned off." From the Gateway overview: the Podman runtime runs "Rootless containers on the gateway host."

Not documented: launching OpenShell inside a container that an external tool (such as Realm) creates and owns. The spec's layer stack (Podman container, then OpenShell inside it, then AgentOS) does not match the documented model, in which the Podman driver creates the sandbox container itself. This is a conflict for Phase 3 to resolve (see the open questions).

Q2. Podman driver prerequisites ​

From the Installation page, the requirements table: "Podman | Linux with Podman 5.x, cgroups v2, and an active Podman user socket." The Gateway overview adds a systemd user unit for Podman gateways: systemctl --user status openshell-gateway.

The host Podman is 4.9.3, which is below the documented 5.x minimum. The OpenShell Podman driver is therefore not supported on the current host, per the documentation. This is a Phase 3 blocker (also recorded in STATE.md).

Q3. Policy model ​

From the Policy Schema reference:

  • A policy is YAML of at most 4 MiB. "OpenShell rejects a policy that contains unknown fields or duplicate keys." version: 1 is required.
  • Top-level sections and when each takes effect:
SectionTakes effectEnforced by
filesystem_policyStartupLandlock LSM in the kernel
landlockStartupSandbox runtime
processStartupDocker and Podman, when they create the sandbox
network_policiesLiveSandbox network proxy
network_middlewaresLiveSandbox network proxy
  • filesystem_policy: read_only and read_write lists. Each path must be absolute, must not contain .., must be at most 4096 bytes, and "read_write cannot contain /." A policy can list at most 256 paths. Paths not listed are inaccessible.
  • landlock: compatibility is best_effort (default) or hard_requirement. "In either mode, a sandbox requires a kernel with Landlock ABI v3 or later."
  • process: run_as_user and run_as_group take sandbox or a numeric ID from 1 to 4294967294. "OpenShell rejects root."
  • network_policies: a map of which binaries can reach which endpoints. Endpoint rules have host, port, optional protocol (rest, mcp, tcp), access, rules and deny_rules.

Source precedence when several policies exist: a global policy, then the sandbox's saved policy (where --policy at creation takes precedence over OPENSHELL_SANDBOX_POLICY), then a policy in the sandbox image, then the default policy.

Q4. What OpenShell enforces ​

From the Architecture and Best Practices pages:

  • Filesystem: Landlock LSM, locked at sandbox creation.
  • Process: seccomp BPF and privilege drop (setuid/setgid), locked at sandbox creation.
  • Network: CONNECT proxy and the OPA policy engine. Hot-reloadable at runtime.
  • Credentials: provider credentials resolve "only at profile-authorized endpoints."

Deny-by-default egress: "All egress denied. Only endpoints listed in network_policies can receive traffic." The proxy resolves DNS after policy allows the connection and "rejects undeclared internal destinations." Loopback, link-local and unspecified addresses are "always blocked regardless of allowed_ips."

Static controls: "OpenShell locks static controls at sandbox creation and requires destroying and recreating the sandbox to change them." Dynamic controls change with openshell policy update or openshell policy set.

The spec's open question on DNS and egress enforcement (spec n5 item 4) is answered by this: the proxy enforces egress by policy, and DNS is resolved by the supervisor.

Q5. Applying a policy at creation ​

From the Policy Overview: "--policy takes precedence over OPENSHELL_SANDBOX_POLICY." The Best Practices page says: "Apply statically at creation (--policy) or dynamically (openshell policy update for incremental changes, openshell policy set for full replacement)." The --policy flag is documented on the policy pages. The other sandbox create flags (--name, --no-auto-providers, the -- argv form) are not documented in the pages read, so they are not confirmed here.

Q6. Gateway and CLI surface ​

From the Installation and Gateway pages: openshell status, openshell gateway add <url> --local --name <name>, openshell gateway list, openshell gateway info, openshell gateway remove <name>, and openshell sandbox create. openshell-gateway config preflight --path <file> checks a gateway config. The page references schema version 2 for the gateway config. The TOML table name is not confirmed in the pages read.

Q7. TypeScript SDK ​

From the TypeScript SDK page:

  • Package: @nvidia/openshell-sdk. It "requires Node.js 20.3 or later." It is "currently distributed through GitHub Packages." The install configures the @nvidia scope in the project .npmrc to https://npm.pkg.github.com and authenticates with a GitHub token. No token is recorded in this note.
  • Connect: OpenShellClient.connect({ gateway, oidcToken }), with client.health() to verify connectivity.
  • Sandbox: client.sandbox.create, waitReady, exec, delete, waitDeleted, and watchLogs.

The package name was confirmed against this page.

Q8. Sandbox identity and credentials ​

From the Architecture page: "The sandbox holds only the gateway's public key, so it can verify the token but can never create one." The agent "holds nothing worth stealing: no gateway signing key, no gateway JWT, and no provider credentials." "If the supervisor disconnects, the sandbox freezes the agent."

Q9. Network isolation of the workload container ​

Documented for the Podman driver: "Workload container has networking turned off." Egress is then only through the supervisor's protected channel, as described in Q4.

Q10. Image pinning ​

Not documented in the pages read. Pinning runtime images by digest is not confirmed for OpenShell images: no page read confirms or refutes that practice. The Security page links an SBOM verification guide for published images, which was not fetched.

Answers not in the docs (D-18 default) ​

  • Launch inside an external container: not documented (see Q1).
  • Image digest pinning: not documented (see Q10).
  • Sandbox image format for Realm: not documented in the pages read.

Open questions for Phase 3 ​

  1. Launch model. The documented Podman driver creates its own sandbox container. The spec requires OpenShell inside a Realm-owned Podman container. Choose one, or record the spec as needing an update. Do not assume nested launch.
  2. Podman version. The Podman driver needs Podman 5.x, and the host has 4.9.3. D-05 forbids changing the host in Phase 1. Phase 3 must decide whether to upgrade, use a different driver, or defer.
  3. OpenShell version. Pin one release (the docs show v0.1.5; the unverified host CLI check reported 0.1.2) and read the matching index.
  4. The gateway TOML table and the sandbox create flags beyond --policy are not on the pages read. Confirm them from the pinned version before use.

Module blocked ​

src/runtime/openshell.ts, until the launch model (Q1) and the Podman version (Q2) are decided.

Phase 3 resolution ​

Recorded in docs/integration/runtime-decision.md (S-08, S-10, OQ-P3-01 to OQ-P3-04, OQ-P3-12, OQ-P3-15, OQ-P3-16). Summary:

  • Launch (Q1): the gateway runs on the host, and the Podman driver creates the sandbox container. The RT-01 and RT-03 wording conflicts are recorded in the runtime note (D-46, D-47) and not edited.
  • Podman (Q2): host 4.9.3 is below 5.x, so the Podman driver path is live-gated.
  • Version (caveat): pinned to 0.1.2 (S-10). The local CLI reports openshell 0.1.2, and its sandbox create --help lists every pinned flag. The docs describe 0.1.5. The drift is OQ-P3-12.
  • Policy (Q3): written as JSON (D-57, OQ-P3-15). No network endpoint is written (OQ-P3-16).

AGPL-3.0-only. Copyright (C) 2026 Spectrum Web Co/swcstudiospace.