|
| 1 | +# OpenShell Integration |
| 2 | + |
| 3 | +[NVIDIA OpenShell](https://docs.nvidia.com/openshell/about/overview) 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. |
| 4 | + |
| 5 | +OpenShell does not replace tinycode's agent, tool, or session system — it wraps the entire process in a security sandbox. They are complementary layers. |
| 6 | + |
| 7 | +## Architecture |
| 8 | + |
| 9 | +OpenShell has two components: |
| 10 | + |
| 11 | +- **Gateway** — Control plane that manages policy enforcement, credential injection, and inference routing. Runs outside the sandbox. |
| 12 | +- **Supervisor** — Runs inside each sandbox container, enforcing kernel-level restrictions defined in YAML policy files. |
| 13 | + |
| 14 | +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. |
| 15 | + |
| 16 | +## Why OpenShell + tinycode |
| 17 | + |
| 18 | +| Concern | Without OpenShell | With OpenShell | |
| 19 | +|---------|-------------------|----------------| |
| 20 | +| Shell tool execution | Unrestricted (user approval only) | Kernel-level filesystem/network/process isolation | |
| 21 | +| LLM inference routing | Direct network to Ollama/vLLM | Routed via `inference.local`, no direct network needed | |
| 22 | +| GPU access | Manual device plugin config | `--gpu` flag for NVIDIA passthrough | |
| 23 | +| Credential management | Environment variables | Gateway-managed injection | |
| 24 | +| Network policy | Manual NetworkPolicy on K8s | Declarative per-sandbox YAML | |
| 25 | +| MCP servers | Direct network to MCP endpoints | Routed via `protocol: mcp` in network policy | |
| 26 | + |
| 27 | +## Running tinycode in an OpenShell Sandbox |
| 28 | + |
| 29 | +### Prerequisites |
| 30 | + |
| 31 | +- OpenShell installed ([installation guide](https://docs.nvidia.com/openshell/getting-started/installation)) |
| 32 | +- A local LLM provider (Ollama, vLLM) running on the host |
| 33 | +- tinycode container image (`ghcr.io/bjohns/tinycode-container:latest`) |
| 34 | + |
| 35 | +### Basic Usage |
| 36 | + |
| 37 | +```bash |
| 38 | +# Run tinycode in a sandbox with GPU access |
| 39 | +openshell sandbox create \ |
| 40 | + --image ghcr.io/bjohns/tinycode-container:latest \ |
| 41 | + --gpu \ |
| 42 | + -- tinycode |
| 43 | +``` |
| 44 | + |
| 45 | +### With Host-Side Ollama |
| 46 | + |
| 47 | +When Ollama runs on the host, OpenShell routes inference traffic through `host.openshell.internal`: |
| 48 | + |
| 49 | +```bash |
| 50 | +# Start a sandbox with inference routing to host Ollama |
| 51 | +openshell sandbox create \ |
| 52 | + --image ghcr.io/bjohns/tinycode-container:latest \ |
| 53 | + --provider ollama --type openai --host host.openshell.internal:11434 \ |
| 54 | + -- tinycode |
| 55 | +``` |
| 56 | + |
| 57 | +Inside the sandbox, configure tinycode to use the routed endpoint: |
| 58 | + |
| 59 | +```json |
| 60 | +{ |
| 61 | + "model": "ollama/qwen3.5:9b" |
| 62 | +} |
| 63 | +``` |
| 64 | + |
| 65 | +tinycode's auto-discovery will find Ollama at the routed address. |
| 66 | + |
| 67 | +### With vLLM |
| 68 | + |
| 69 | +```bash |
| 70 | +openshell sandbox create \ |
| 71 | + --image ghcr.io/bjohns/tinycode-container:latest \ |
| 72 | + --provider vllm --type openai --host host.openshell.internal:8000 \ |
| 73 | + -- tinycode |
| 74 | +``` |
| 75 | + |
| 76 | +### Custom Policy |
| 77 | + |
| 78 | +Create a policy file to control what tinycode can access: |
| 79 | + |
| 80 | +```yaml |
| 81 | +# tinycode-policy.yaml |
| 82 | +filesystem: |
| 83 | + read: |
| 84 | + - /workspace |
| 85 | + - /home/tinycode |
| 86 | + write: |
| 87 | + - /workspace |
| 88 | + - /home/tinycode/.config/tinycode |
| 89 | + - /tmp |
| 90 | +network: |
| 91 | + allow: |
| 92 | + - inference.local |
| 93 | +process: |
| 94 | + allow: |
| 95 | + - git |
| 96 | + - bun |
| 97 | + - node |
| 98 | + - grep |
| 99 | + - find |
| 100 | +``` |
| 101 | +
|
| 102 | +```bash |
| 103 | +openshell sandbox create \ |
| 104 | + --policy tinycode-policy.yaml \ |
| 105 | + --image ghcr.io/bjohns/tinycode-container:latest \ |
| 106 | + -- tinycode /workspace |
| 107 | +``` |
| 108 | + |
| 109 | +## Installing tinycode Plugins in a Sandbox |
| 110 | + |
| 111 | +OpenShell 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. |
| 112 | + |
| 113 | +**Option 1: Pre-bake plugins into the container image (recommended)** |
| 114 | + |
| 115 | +Install plugins during the Docker build so no runtime network access is needed: |
| 116 | + |
| 117 | +```dockerfile |
| 118 | +# In your Containerfile |
| 119 | +RUN tinycode plugin install tinycode-plugin-example |
| 120 | +``` |
| 121 | + |
| 122 | +This is the most secure approach — the sandbox policy can block all network access except the inference endpoint. |
| 123 | + |
| 124 | +**Option 2: Install plugins at runtime** |
| 125 | + |
| 126 | +Allow npm registry access in the sandbox policy: |
| 127 | + |
| 128 | +```yaml |
| 129 | +# tinycode-policy.yaml |
| 130 | +filesystem: |
| 131 | + write: |
| 132 | + - /workspace |
| 133 | + - /home/tinycode/.config/tinycode |
| 134 | + - /tmp |
| 135 | +network: |
| 136 | + allow: |
| 137 | + - inference.local |
| 138 | + - registry.npmjs.org |
| 139 | +process: |
| 140 | + allow: |
| 141 | + - git |
| 142 | + - bun |
| 143 | + - node |
| 144 | + - npm |
| 145 | +``` |
| 146 | +
|
| 147 | +Then install plugins inside the running sandbox: |
| 148 | +
|
| 149 | +```bash |
| 150 | +tinycode plugin install tinycode-plugin-example |
| 151 | +``` |
| 152 | + |
| 153 | +**MCP 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. |
| 154 | + |
| 155 | +## OpenShift Deployment |
| 156 | + |
| 157 | +OpenShell has Helm-based Kubernetes support but **no OpenShift-specific documentation exists yet**. Deploying on OpenShift requires addressing several platform-specific concerns. |
| 158 | + |
| 159 | +### Installing OpenShell on OpenShift |
| 160 | + |
| 161 | +```bash |
| 162 | +helm install openshell oci://ghcr.io/nvidia/openshell/helm-chart \ |
| 163 | + --namespace openshell-system \ |
| 164 | + --create-namespace |
| 165 | +``` |
| 166 | + |
| 167 | +### OpenShift-Specific Considerations |
| 168 | + |
| 169 | +OpenShell's defaults conflict with OpenShift's `restricted-v2` SCC in several ways: |
| 170 | + |
| 171 | +| Concern | OpenShell Default | OpenShift Requirement | Resolution | |
| 172 | +|---------|-------------------|----------------------|------------| |
| 173 | +| AppArmor | `Unconfined` | Profile required by restricted-v2 | Create a custom SCC or use `privileged` SCC for the gateway | |
| 174 | +| UID | Root sidecar proxy (UID 0) | Arbitrary UID enforcement | Bind gateway ServiceAccount to an SCC that allows UID 0 | |
| 175 | +| Seccomp | Custom profile | RuntimeDefault required | Custom SCC with seccomp allowance | |
| 176 | +| Networking | Port-forward for access | Route/Ingress preferred | Create an OpenShift Route to the gateway service | |
| 177 | +| GPU | `--gpu` passthrough | NVIDIA GPU Operator + device plugin | Install the [NVIDIA GPU Operator](https://docs.nvidia.com/datacenter/cloud-native/openshift/latest/index.html) on the cluster first | |
| 178 | + |
| 179 | +**SCC configuration for the gateway:** |
| 180 | + |
| 181 | +```bash |
| 182 | +# Create a ServiceAccount for OpenShell |
| 183 | +oc -n openshell-system create sa openshell-gateway |
| 184 | + |
| 185 | +# Bind to a permissive SCC (gateway needs elevated privileges) |
| 186 | +oc adm policy add-scc-to-user anyuid -z openshell-gateway -n openshell-system |
| 187 | +``` |
| 188 | + |
| 189 | +**Expose the gateway via Route:** |
| 190 | + |
| 191 | +```bash |
| 192 | +oc -n openshell-system expose svc/openshell-gateway |
| 193 | +``` |
| 194 | + |
| 195 | +> **Note:** 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. |
| 196 | +
|
| 197 | +### Operator Integration (Future) |
| 198 | + |
| 199 | +The tinycode-operator could detect OpenShell on the cluster and optionally delegate sandbox management: |
| 200 | + |
| 201 | +1. **Detection** — Check for the `sandboxes.agents.x-k8s.io` CRD or the gateway service |
| 202 | +2. **Sandbox creation** — Instead of creating bare Deployments, create `AgentSandbox` custom resources |
| 203 | +3. **Inference routing** — Use OpenShell's gateway for vLLM routing instead of direct service discovery |
| 204 | +4. **Security context** — Delegate SCC/seccomp configuration to OpenShell policies |
| 205 | + |
| 206 | +This integration is tracked in [issue #90](http://localhost:3000/bjohns/tinycode/issues/90). |
| 207 | + |
| 208 | +## Comparison with tinycode-operator |
| 209 | + |
| 210 | +OpenShell and tinycode-operator serve different purposes: |
| 211 | + |
| 212 | +| Feature | tinycode-operator | OpenShell | |
| 213 | +|---------|-------------------|-----------| |
| 214 | +| Purpose | Lifecycle management | Security sandbox | |
| 215 | +| Deploys tinycode | Yes (CRD-driven) | No (wraps existing containers) | |
| 216 | +| vLLM discovery | Auto-probes cluster services | Routes via gateway | |
| 217 | +| Storage provisioning | PVC management | Not applicable | |
| 218 | +| GitOps mode | Built-in repo cloning | Not applicable | |
| 219 | +| Shared workspaces | RWX PVC support | Not applicable | |
| 220 | +| Security isolation | SCC binding, NetworkPolicy | Kernel-level Landlock/seccomp | |
| 221 | +| GPU management | Device plugin config | `--gpu` passthrough | |
| 222 | +| MCP connectivity | Direct network | Gateway-routed with policy | |
| 223 | + |
| 224 | +The operator manages *what* runs; OpenShell manages *how safely* it runs. They can work together. |
| 225 | + |
| 226 | +## Next Steps |
| 227 | + |
| 228 | +- Test tinycode inside an OpenShell sandbox on a local Docker setup |
| 229 | +- Validate `inference.local` routing with tinycode's provider auto-discovery |
| 230 | +- Test OpenShift deployment with SCC and Route configuration |
| 231 | +- Propose tinycode as a supported agent upstream in the OpenShell project |
| 232 | +- Evaluate operator integration for OpenShift clusters with OpenShell installed |
0 commit comments