NVIDIA OpenShell is an open-source (Apache 2.0) sandboxed runtime for AI coding agents. It provides kernel-level isolation via Landlock and seccomp with declarative YAML policies controlling filesystem, network, process, and inference access.
OpenShell does not replace tinycode's agent, tool, or session system — it wraps the entire process in a security sandbox. They are complementary layers.
OpenShell has two components:
- Gateway — Control plane that manages policy enforcement, credential injection, and inference routing. Runs outside the sandbox.
- Supervisor — Runs inside each sandbox container, enforcing kernel-level restrictions defined in YAML policy files.
Sandboxes are containers (Docker, Podman, or Kubernetes pods) with policies that control what the agent can access. OpenShell uses the AgentSandbox CRD (sandboxes.agents.x-k8s.io) from the Kubernetes SIG project for cluster deployments.
| Concern | Without OpenShell | With OpenShell |
|---|---|---|
| Shell tool execution | Unrestricted (user approval only) | Kernel-level filesystem/network/process isolation |
| LLM inference routing | Direct network to Ollama/vLLM | Routed via inference.local, no direct network needed |
| GPU access | Manual device plugin config | --gpu flag for NVIDIA passthrough |
| Credential management | Environment variables | Gateway-managed injection |
| Network policy | Manual NetworkPolicy on K8s | Declarative per-sandbox YAML |
| MCP servers | Direct network to MCP endpoints | Routed via protocol: mcp in network policy |
- OpenShell installed (installation guide)
- A local LLM provider (Ollama, vLLM) running on the host
- tinycode container image (
ghcr.io/bjohns/tinycode-container:latest)
# Run tinycode in a sandbox with GPU access
openshell sandbox create \
--image ghcr.io/bjohns/tinycode-container:latest \
--gpu \
-- tinycodeWhen Ollama runs on the host, OpenShell routes inference traffic through host.openshell.internal:
# Start a sandbox with inference routing to host Ollama
openshell sandbox create \
--image ghcr.io/bjohns/tinycode-container:latest \
--provider ollama --type openai --host host.openshell.internal:11434 \
-- tinycodeInside the sandbox, configure tinycode to use the routed endpoint:
{
"model": "ollama/qwen3.5:9b"
}tinycode's auto-discovery will find Ollama at the routed address.
openshell sandbox create \
--image ghcr.io/bjohns/tinycode-container:latest \
--provider vllm --type openai --host host.openshell.internal:8000 \
-- tinycodeCreate a policy file to control what tinycode can access:
# tinycode-policy.yaml
filesystem:
read:
- /workspace
- /home/tinycode
write:
- /workspace
- /home/tinycode/.config/tinycode
- /tmp
network:
allow:
- inference.local
process:
allow:
- git
- bun
- node
- grep
- findopenshell sandbox create \
--policy tinycode-policy.yaml \
--image ghcr.io/bjohns/tinycode-container:latest \
-- tinycode /workspaceOpenShell controls what the sandbox can access externally, not what runs inside the container. tinycode plugins (tinycode plugin install <name>) work inside a sandbox as long as the policy permits it.
Option 1: Pre-bake plugins into the container image (recommended)
Install plugins during the Docker build so no runtime network access is needed:
# In your Containerfile
RUN tinycode plugin install tinycode-plugin-exampleThis is the most secure approach — the sandbox policy can block all network access except the inference endpoint.
Option 2: Install plugins at runtime
Allow npm registry access in the sandbox policy:
# tinycode-policy.yaml
filesystem:
write:
- /workspace
- /home/tinycode/.config/tinycode
- /tmp
network:
allow:
- inference.local
- registry.npmjs.org
process:
allow:
- git
- bun
- node
- npmThen install plugins inside the running sandbox:
tinycode plugin install tinycode-plugin-exampleMCP servers: OpenShell sandboxes can connect to external MCP servers as clients using protocol: mcp in the network policy. You can also bundle MCP servers inside the container image — OpenShell does not interfere with processes running inside the container.
OpenShell has Helm-based Kubernetes support but no OpenShift-specific documentation exists yet. Deploying on OpenShift requires addressing several platform-specific concerns.
helm install openshell oci://ghcr.io/nvidia/openshell/helm-chart \
--namespace openshell-system \
--create-namespaceOpenShell's defaults conflict with OpenShift's restricted-v2 SCC in several ways:
| Concern | OpenShell Default | OpenShift Requirement | Resolution |
|---|---|---|---|
| AppArmor | Unconfined |
Profile required by restricted-v2 | Create a custom SCC or use privileged SCC for the gateway |
| UID | Root sidecar proxy (UID 0) | Arbitrary UID enforcement | Bind gateway ServiceAccount to an SCC that allows UID 0 |
| Seccomp | Custom profile | RuntimeDefault required | Custom SCC with seccomp allowance |
| Networking | Port-forward for access | Route/Ingress preferred | Create an OpenShift Route to the gateway service |
| GPU | --gpu passthrough |
NVIDIA GPU Operator + device plugin | Install the NVIDIA GPU Operator on the cluster first |
SCC configuration for the gateway:
# Create a ServiceAccount for OpenShell
oc -n openshell-system create sa openshell-gateway
# Bind to a permissive SCC (gateway needs elevated privileges)
oc adm policy add-scc-to-user anyuid -z openshell-gateway -n openshell-systemExpose the gateway via Route:
oc -n openshell-system expose svc/openshell-gatewayNote: These instructions are untested and based on OpenShell's Kubernetes requirements mapped to OpenShift equivalents. The OpenShell project does not officially support OpenShift yet. Test thoroughly in a non-production cluster first.
The tinycode-operator could detect OpenShell on the cluster and optionally delegate sandbox management:
- Detection — Check for the
sandboxes.agents.x-k8s.ioCRD or the gateway service - Sandbox creation — Instead of creating bare Deployments, create
AgentSandboxcustom resources - Inference routing — Use OpenShell's gateway for vLLM routing instead of direct service discovery
- Security context — Delegate SCC/seccomp configuration to OpenShell policies
This integration is tracked in issue #90.
OpenShell and tinycode-operator serve different purposes:
| Feature | tinycode-operator | OpenShell |
|---|---|---|
| Purpose | Lifecycle management | Security sandbox |
| Deploys tinycode | Yes (CRD-driven) | No (wraps existing containers) |
| vLLM discovery | Auto-probes cluster services | Routes via gateway |
| Storage provisioning | PVC management | Not applicable |
| GitOps mode | Built-in repo cloning | Not applicable |
| Shared workspaces | RWX PVC support | Not applicable |
| Security isolation | SCC binding, NetworkPolicy | Kernel-level Landlock/seccomp |
| GPU management | Device plugin config | --gpu passthrough |
| MCP connectivity | Direct network | Gateway-routed with policy |
The operator manages what runs; OpenShell manages how safely it runs. They can work together.
- Test tinycode inside an OpenShell sandbox on a local Docker setup
- Validate
inference.localrouting with tinycode's provider auto-discovery - Test OpenShift deployment with SCC and Route configuration
- Propose tinycode as a supported agent upstream in the OpenShell project
- Evaluate operator integration for OpenShift clusters with OpenShell installed