From f21d3240b18496d43d18d565aa2b1b66c106368f Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 5 Mar 2026 08:21:31 -0800 Subject: [PATCH 01/39] initial doc filling --- docs/about/how-it-works.md | 190 ++++++++++++++++++++++++ docs/about/index.md | 105 ++++++++++++- docs/about/release-notes.md | 33 ++++ docs/about/support-matrix.md | 91 ++++++++++++ docs/clusters/index.md | 77 ++++++++++ docs/clusters/remote-deploy.md | 63 ++++++++ docs/conf.py | 1 + docs/feature1/index.md | 6 - docs/feature2/index.md | 6 - docs/gator/index.md | 111 ++++++++++++++ docs/get-started/first-sandbox.md | 117 +++++++++++++++ docs/get-started/index.md | 46 +++++- docs/get-started/installation.md | 48 ++++++ docs/index.md | 130 +++++++++++++++- docs/inference/index.md | 110 ++++++++++++++ docs/observability/index.md | 81 +++++++++- docs/reference/architecture.md | 88 +++++++++++ docs/reference/cli.md | 179 ++++++++++++++++++++++ docs/reference/environment-variables.md | 43 ++++++ docs/reference/index.md | 11 +- docs/reference/policy-schema.md | 189 +++++++++++++++++++++++ docs/resources/index.md | 35 ++++- docs/sandboxes/create-and-manage.md | 118 +++++++++++++++ docs/sandboxes/custom-containers.md | 81 ++++++++++ docs/sandboxes/file-sync.md | 41 +++++ docs/sandboxes/index.md | 61 ++++++++ docs/sandboxes/port-forwarding.md | 60 ++++++++ docs/sandboxes/providers.md | 85 +++++++++++ docs/security/index.md | 74 +++++++++ docs/security/network-access.md | 148 ++++++++++++++++++ docs/security/policies.md | 190 ++++++++++++++++++++++++ docs/troubleshooting/index.md | 119 ++++++++++++++- 32 files changed, 2714 insertions(+), 23 deletions(-) create mode 100644 docs/about/how-it-works.md create mode 100644 docs/about/release-notes.md create mode 100644 docs/about/support-matrix.md create mode 100644 docs/clusters/index.md create mode 100644 docs/clusters/remote-deploy.md delete mode 100644 docs/feature1/index.md delete mode 100644 docs/feature2/index.md create mode 100644 docs/gator/index.md create mode 100644 docs/get-started/first-sandbox.md create mode 100644 docs/get-started/installation.md create mode 100644 docs/inference/index.md create mode 100644 docs/reference/architecture.md create mode 100644 docs/reference/cli.md create mode 100644 docs/reference/environment-variables.md create mode 100644 docs/reference/policy-schema.md create mode 100644 docs/sandboxes/create-and-manage.md create mode 100644 docs/sandboxes/custom-containers.md create mode 100644 docs/sandboxes/file-sync.md create mode 100644 docs/sandboxes/index.md create mode 100644 docs/sandboxes/port-forwarding.md create mode 100644 docs/sandboxes/providers.md create mode 100644 docs/security/index.md create mode 100644 docs/security/network-access.md create mode 100644 docs/security/policies.md diff --git a/docs/about/how-it-works.md b/docs/about/how-it-works.md new file mode 100644 index 00000000..125b0632 --- /dev/null +++ b/docs/about/how-it-works.md @@ -0,0 +1,190 @@ + + +# How It Works + +This page covers the NemoClaw architecture, its major subsystems, and the end-to-end flow from bootstrapping a cluster to running a safety-enforced sandbox. + +## Architecture + +```{mermaid} +flowchart TB + subgraph USER["User's Machine"] + CLI["Command-Line Interface"] + end + + subgraph CLUSTER["Kubernetes Cluster (single Docker container)"] + SERVER["Gateway / Control Plane"] + DB["Database (SQLite or Postgres)"] + + subgraph SBX["Sandbox Pod"] + SUPERVISOR["Sandbox Supervisor"] + PROXY["Network Proxy"] + CHILD["Agent Process (restricted)"] + OPA["Policy Engine (OPA)"] + end + end + + subgraph EXT["External Services"] + HOSTS["Allowed Hosts (github.com, api.anthropic.com, ...)"] + CREDS["Provider APIs (Claude, GitHub, GitLab, ...)"] + BACKEND["Inference Backends (LM Studio, vLLM, ...)"] + end + + CLI -- "gRPC / HTTPS" --> SERVER + CLI -- "SSH over HTTP CONNECT" --> SERVER + SERVER -- "CRUD + Watch" --> DB + SERVER -- "Create / Delete Pods" --> SBX + SUPERVISOR -- "Fetch Policy + Credentials" --> SERVER + SUPERVISOR -- "Spawn + Restrict" --> CHILD + CHILD -- "All network traffic" --> PROXY + PROXY -- "Evaluate request" --> OPA + PROXY -- "Allowed traffic only" --> HOSTS + PROXY -- "Inference reroute" --> SERVER + SERVER -- "Proxied inference" --> BACKEND + SERVER -. "Store / retrieve credentials" .-> CREDS +``` + +Users interact through the CLI, which communicates with a central gateway. The gateway manages sandbox lifecycle in Kubernetes, and each sandbox enforces its own policy locally. + +## Major Subsystems + +### Sandbox Execution Environment + +Each sandbox runs inside a container as two processes: a privileged **supervisor** and a restricted **child process** (the agent). Safety and privacy are enforced through four independent layers: + +- **Filesystem restrictions** — the Linux Landlock LSM controls which directories the agent can read and write. Attempts to access files outside the allowed set are blocked by the kernel. +- **System call filtering** — seccomp prevents the agent from creating raw network sockets, eliminating proxy bypass. +- **Network namespace isolation** — the agent is placed in a separate network where the only reachable destination is the proxy, preventing data exfiltration. +- **Process privilege separation** — the agent runs as an unprivileged user, protecting against privilege escalation. + +All restrictions are driven by a YAML **policy** evaluated by an embedded OPA/Rego engine. See [Safety & Privacy](../security/index.md). + +### Network Proxy + +Every sandbox forces all outbound traffic through an HTTP CONNECT proxy — no data leaves without inspection. The proxy: + +1. **Identifies the requesting program** via the process table. +2. **Verifies binary integrity** with trust-on-first-use SHA256 hashing. +3. **Evaluates requests against policy** with per-binary, per-host granularity. +4. **Protects private infrastructure** by blocking DNS results that resolve to internal IP ranges. +5. **Performs L7 inspection** for configured endpoints, examining HTTP requests within TLS tunnels. +6. **Keeps inference traffic private** by intercepting AI API calls and rerouting them to policy-controlled backends. + +### Gateway + +The central orchestration service providing gRPC and HTTP APIs, sandbox lifecycle management, data persistence, TLS termination, SSH tunnel gateway, and real-time status streaming. + +### Providers + +Credentials are managed with a privacy-first design. API keys and tokens are stored separately from sandbox definitions, never appear in pod specs, and are fetched only at runtime. See [Providers](../sandboxes/providers.md). + +### Inference Routing + +AI inference API calls are transparently intercepted and rerouted to policy-controlled backends, keeping sensitive prompts and responses on private infrastructure. See [Inference Routing](../inference/index.md). + +### Cluster Infrastructure + +The entire platform packages into a single Docker container running k3s. Docker is the only dependency. See [Clusters](../clusters/index.md). + +## End-to-End Flow + +```{mermaid} +sequenceDiagram + participant User as User + participant CLI as CLI + participant Docker as Docker + participant GW as Gateway + participant K8s as Kubernetes + participant SBX as Sandbox + + User->>CLI: nemoclaw sandbox create -- claude + CLI->>CLI: Check for running cluster + alt No cluster found + CLI->>Docker: Bootstrap k3s cluster + Docker-->>CLI: Cluster ready + end + CLI->>CLI: Discover local credentials (ANTHROPIC_API_KEY, ~/.claude.json) + CLI->>GW: Upload credentials as provider + CLI->>GW: CreateSandbox(policy, providers) + GW->>K8s: Create sandbox pod + K8s-->>GW: Pod scheduled + GW-->>CLI: Sandbox provisioning + loop Wait for Ready + CLI->>GW: GetSandbox(name) + GW-->>CLI: Status update + end + CLI->>GW: CreateSshSession(sandbox_id) + GW-->>CLI: Session token + CLI->>SBX: SSH tunnel through gateway + User->>SBX: Interactive shell session +``` + +## What Happens Inside a Sandbox + +When a sandbox starts, the supervisor executes this sequence: + +1. **Load policy** — fetches the YAML policy from the gateway. The policy defines all filesystem, network, and process restrictions. +2. **Fetch credentials** — retrieves provider credentials via gRPC for injection into child processes. +3. **Set up filesystem isolation** — configures Landlock rules. Writable directories are created and ownership is set automatically. +4. **Generate ephemeral TLS certificates** — creates a per-sandbox CA for transparent TLS inspection. +5. **Create network namespace** — isolates the agent's network so the only reachable destination is the proxy. +6. **Start the proxy** — launches the HTTP CONNECT proxy with OPA policy evaluation. +7. **Start the SSH server** — launches the embedded SSH daemon for interactive access. +8. **Spawn the agent** — launches the child process with reduced privileges: seccomp filters, network namespace, Landlock rules, and credentials injected as environment variables. +9. **Begin policy polling** — checks for policy updates every 30 seconds, enabling live changes without restart. + +## How Network Safety Works + +```{mermaid} +flowchart TD + A[Agent makes HTTPS request] --> B[Request routed to proxy via network namespace] + B --> C{OPA policy evaluation} + C -->|Endpoint + binary match| D[Allow: forward to destination] + C -->|No match, inference routes exist| E[Inspect for inference patterns] + C -->|No match, no routes| F[Deny: connection rejected] + E --> G{Known inference API?} + G -->|Yes| H[Route to configured backend] + G -->|No| F + D --> I{DNS resolves to private IP?} + I -->|Yes| F + I -->|No| J[Connection established] +``` + +Every connection is evaluated with three pieces of context: +- **Which program** is making the request (identified via `/proc`). +- **Which host and port** the program is trying to reach. +- **Whether the binary has been tampered with** since its first request. + +## How Credential Privacy Works + +Credentials flow through a privacy-preserving pipeline: + +1. **Discovery** — the CLI scans local environment variables and config files for credentials. +2. **Upload** — credentials are sent to the gateway over mTLS and stored separately from sandbox definitions. +3. **Injection** — the supervisor fetches credentials via gRPC and injects them as environment variables. They never appear in Kubernetes pod specs. +4. **Isolation** — the sandbox policy controls which endpoints the agent can reach, so credentials cannot be exfiltrated. + +## How Inference Privacy Works + +When inference routing is configured, the proxy intercepts AI API calls and keeps them private: + +1. The agent calls the OpenAI/Anthropic SDK as normal. +2. The proxy TLS-terminates the connection and detects the inference API pattern. +3. The proxy strips the original authorization header and routes the request to a configured backend. +4. The backend's API key is injected by the router — the sandbox never sees it. +5. The response flows back to the agent transparently. + +This keeps prompts and responses on your private infrastructure while the agent operates as if it were calling the original API. + +## How Live Policy Updates Work + +Policies can be updated on running sandboxes without restarts: + +1. Push the updated policy: `nemoclaw sandbox policy set --policy updated.yaml --wait`. +2. The gateway stores the new revision as `pending`. +3. The sandbox detects the new version within 30 seconds. +4. The OPA engine atomically reloads with the new rules. +5. If the reload fails, the previous policy stays active (last-known-good behavior). diff --git a/docs/about/index.md b/docs/about/index.md index 73a57815..f8e85647 100644 --- a/docs/about/index.md +++ b/docs/about/index.md @@ -1,6 +1,109 @@ +--- +title: + page: "NVIDIA NemoClaw Overview" + nav: "Overview" +description: "Learn about NemoClaw, the safe and private runtime for autonomous AI agents. Run agents in sandboxed environments that protect your data, credentials, and infrastructure." +keywords: ["nemoclaw", "ai agent sandbox", "agent safety", "agent privacy", "sandboxed execution"] +topics: ["generative_ai", "cybersecurity"] +tags: ["ai_agents", "sandboxing", "security", "privacy", "inference_routing"] +content: + type: concept + difficulty: technical_beginner + audience: [engineer, data_scientist, devops] +--- + -# About NemoClaw +# NVIDIA NemoClaw Overview + +NemoClaw is a safe, private runtime for autonomous AI agents. It provides sandboxed execution environments that protect your data, credentials, and infrastructure while giving agents the system access they need to be useful. Each sandbox enforces declarative YAML policies through Linux kernel-level isolation, a policy-enforcing network proxy, and a credential management pipeline — agents run with exactly the permissions you grant and nothing more. + +You do not modify agent code to use NemoClaw. Instead, the CLI bootstraps a local Kubernetes cluster packaged in a single Docker container, creates sandboxes with the safety policies you define, and connects you to the running agent through an SSH tunnel. + +## How NemoClaw Works + +```{mermaid} +flowchart LR + CLI["CLI"] -->|gRPC| GW["Gateway"] + GW --> SBX["Sandbox"] + + subgraph SBX["Sandbox"] + direction TB + AGENT["Agent Process"] -->|All traffic| PROXY["Network Proxy"] + PROXY -->|Evaluate| OPA["Policy Engine"] + end + + PROXY -->|Allowed traffic| EXT["External Services"] + + style CLI fill:#ffffff,stroke:#000000,color:#000000 + style GW fill:#76b900,stroke:#000000,color:#000000 + style SBX fill:#f5f5f5,stroke:#000000,color:#000000 + style AGENT fill:#ffffff,stroke:#000000,color:#000000 + style PROXY fill:#76b900,stroke:#000000,color:#000000 + style OPA fill:#76b900,stroke:#000000,color:#000000 + style EXT fill:#ffffff,stroke:#000000,color:#000000 + + linkStyle default stroke:#76b900,stroke-width:2px +``` + +The CLI bootstraps a cluster, creates sandboxes, and connects you via SSH. Inside each sandbox, an agent process runs with kernel-level filesystem restrictions while all network traffic passes through a policy-enforcing proxy. The proxy evaluates every request against an OPA policy engine before allowing or denying access. For the full architecture and end-to-end flow, refer to [How It Works](how-it-works.md). + +## Key Capabilities + +:::{dropdown} Data Safety + +Filesystem restrictions prevent agents from reading sensitive files or writing outside designated directories. The Linux Landlock LSM controls which paths the agent can access, and seccomp filters block raw network socket creation. Restrictions are enforced at the kernel level — they cannot be bypassed by the agent process. +::: + +:::{dropdown} Network Privacy + +All outbound traffic passes through an HTTP CONNECT proxy that inspects every connection. The proxy identifies which program is making the request, verifies binary integrity through SHA256 hashing, and evaluates requests against per-host, per-binary policies. DNS results that resolve to private IP ranges are blocked automatically to prevent SSRF attacks. +::: + +:::{dropdown} Credential Privacy + +API keys and tokens are stored separately from sandbox definitions, never appear in container or pod specifications, and are fetched only at runtime over mTLS. The CLI auto-discovers local credentials for supported providers (Anthropic, OpenAI, GitHub, GitLab, NVIDIA) and uploads them through a privacy-preserving pipeline. Refer to [Providers](../sandboxes/providers.md) for the full list. +::: + +:::{dropdown} Inference Privacy + +AI API calls (OpenAI, Anthropic) are transparently intercepted by the proxy and rerouted to local or self-hosted backends such as LM Studio or vLLM. The agent calls its SDK as normal — NemoClaw swaps the destination and injects the backend's API key without the sandbox ever seeing it. Prompts and responses stay on your infrastructure. Refer to [Inference Routing](../inference/index.md) for configuration details. +::: + +:::{dropdown} Declarative Policies + +YAML policies define what each sandbox can access — filesystems, network endpoints, inference routes, and credential bindings. Policies can be updated on running sandboxes without restart: push a new policy revision and the OPA engine reloads atomically within 30 seconds. Refer to [Policies](../security/policies.md) for the schema and examples. +::: + +:::{dropdown} Zero-Config Deployment + +The entire platform packages into a single Docker container running k3s. Docker is the only dependency. Two commands go from zero to a running sandbox: + +```bash +nemoclaw cluster admin deploy +nemoclaw sandbox create -- claude +``` + +No Kubernetes expertise is required. Refer to [Get Started](../get-started/index.md) for full installation steps. +::: + +## Use Cases + +| Use Case | Description | +| --- | --- | +| Autonomous coding agents | Run Claude, Codex, or OpenCode with full shell access while preventing unauthorized file reads, credential leaks, and network exfiltration. | +| Secure CI/CD agent execution | Execute AI-assisted build, test, and deploy workflows in sandboxes that restrict what the agent can reach on your network. | +| Private inference | Route all LLM API calls to self-hosted backends, keeping prompts, code, and responses off third-party servers. | +| Multi-tenant agent hosting | Run sandboxes for multiple users or teams on a shared cluster with isolated policies, credentials, and network access. | +| Compliance-sensitive environments | Enforce auditable, declarative policies that prove agents operate within defined boundaries for regulatory or security review. | +| Custom toolchain sandboxing | Bring your own container image with custom tools and dependencies while NemoClaw enforces the same safety guarantees. Refer to [Custom Containers](../sandboxes/custom-containers.md). | + +## Next Steps + +- [How It Works](how-it-works.md): Explore the architecture, major subsystems, and the end-to-end flow from cluster bootstrap to running sandbox. +- [Support Matrix](support-matrix.md): Find platform requirements, supported providers, agent tools, and compatibility details. +- [Release Notes](release-notes.md): Track what changed in each version. +- [Get Started](../get-started/index.md): Install the CLI, bootstrap a cluster, and launch your first sandbox. diff --git a/docs/about/release-notes.md b/docs/about/release-notes.md new file mode 100644 index 00000000..f2c61d3c --- /dev/null +++ b/docs/about/release-notes.md @@ -0,0 +1,33 @@ + + +# Release Notes + +## 0.1.0 (Initial Release) + +### Features + +- **Sandbox execution environment** — isolated AI agent runtime with Landlock filesystem restrictions, seccomp system call filtering, network namespace isolation, and process privilege separation. +- **HTTP CONNECT proxy** — policy-enforcing network proxy with per-binary access control, binary integrity verification (TOFU), SSRF protection, and L7 HTTP inspection. +- **OPA/Rego policy engine** — embedded policy evaluation using the `regorus` pure-Rust Rego evaluator. No external OPA daemon required. +- **Live policy updates** — hot-reload `network_policies` and `inference` fields on running sandboxes without restart. +- **Provider system** — first-class credential management with auto-discovery from local machine, secure gateway storage, and runtime injection. +- **Inference routing** — transparent interception and rerouting of OpenAI/Anthropic API calls to policy-controlled backends for inference privacy. +- **Cluster bootstrap** — single-container k3s deployment with Docker as the only dependency. Supports local and remote (SSH) targets. +- **CLI** (`nemoclaw` / `ncl`) — full command-line interface for cluster, sandbox, provider, and inference route management. +- **Gator TUI** — terminal dashboard for real-time cluster monitoring and sandbox management. +- **BYOC (Bring Your Own Container)** — run custom container images as sandboxes with supervisor bootstrap. +- **SSH tunneling** — secure access to sandboxes through the gateway with session tokens and mTLS. +- **File sync** — push and pull files to/from sandboxes via tar-over-SSH. +- **Port forwarding** — forward local ports into sandboxes via SSH tunnels. +- **mTLS** — automatic PKI bootstrap and mutual TLS for all gateway communication. + +### Supported Providers + +Claude, Codex, OpenCode, GitHub, GitLab, NVIDIA, Generic, Outlook. + +### Supported Inference Protocols + +`openai_chat_completions`, `openai_completions`, `anthropic_messages`. diff --git a/docs/about/support-matrix.md b/docs/about/support-matrix.md new file mode 100644 index 00000000..d170de88 --- /dev/null +++ b/docs/about/support-matrix.md @@ -0,0 +1,91 @@ + + +# Support Matrix + +## Platform Requirements + +| Requirement | Supported | +|-------------|-----------| +| **Operating System** | Linux (sandbox runtime). macOS and Linux (CLI). | +| **Docker** | Required for cluster bootstrap. | +| **Python** | 3.12+ (for CLI installation via `pip`). | +| **Rust** | 1.88+ (for building from source). | +| **Kubernetes** | k3s (bundled — no external cluster needed). | + +## Linux Kernel Features + +The sandbox isolation mechanisms require the following Linux kernel features: + +| Feature | Minimum Kernel | Purpose | +|---------|---------------|---------| +| **Landlock** | 5.13+ (ABI V1) | Filesystem access restriction. | +| **seccomp-BPF** | 3.5+ | System call filtering. | +| **Network namespaces** | 2.6.29+ | Network isolation for sandbox processes. | +| **`/proc` filesystem** | — | Process identity resolution for proxy. | + +:::{note} +When `landlock.compatibility` is set to `best_effort` (the default), the sandbox runs with the best available Landlock ABI. Set to `hard_requirement` to fail startup if the required ABI is not available. +::: + +## Supported Provider Types + +| Provider | Type Slug | Auto-Discovery | +|----------|-----------|----------------| +| Anthropic Claude | `claude` | `ANTHROPIC_API_KEY`, `CLAUDE_API_KEY`, `~/.claude.json` | +| OpenAI Codex | `codex` | `OPENAI_API_KEY`, `~/.config/codex/config.json` | +| OpenCode | `opencode` | `OPENCODE_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY` | +| GitHub | `github` | `GITHUB_TOKEN`, `GH_TOKEN`, `~/.config/gh/hosts.yml` | +| GitLab | `gitlab` | `GITLAB_TOKEN`, `GLAB_TOKEN`, `~/.config/glab-cli/config.yml` | +| NVIDIA | `nvidia` | `NVIDIA_API_KEY` | +| Generic | `generic` | Manual only (`--credential KEY=VALUE`) | +| Outlook | `outlook` | Manual only | + +## Supported Inference Protocols + +| Protocol | API Pattern | Method | Path | +|----------|-------------|--------|------| +| `openai_chat_completions` | OpenAI Chat | POST | `/v1/chat/completions` | +| `openai_completions` | OpenAI Completions | POST | `/v1/completions` | +| `anthropic_messages` | Anthropic Messages | POST | `/v1/messages` | + +## Supported Agent Tools + +The following tools are recognized by `nemoclaw sandbox create -- ` for auto-provider discovery: + +| Tool | Provider Type | Notes | +|------|--------------|-------| +| `claude` | `claude` | Auto-discovers Anthropic credentials. | +| `codex` | `codex` | Auto-discovers OpenAI credentials. | +| `opencode` | `opencode` | Auto-discovers OpenCode/OpenRouter credentials. | + +## Network Policy Features + +| Feature | Support | +|---------|---------| +| L4 allow/deny (host + port) | Supported | +| Per-binary access control | Supported (glob patterns) | +| Binary integrity (TOFU) | Supported (SHA256) | +| SSRF protection (private IP blocking) | Supported | +| L7 HTTP inspection | Supported (TLS termination) | +| L7 enforcement modes | `enforce`, `audit` | +| L7 access presets | `read-only`, `read-write`, `full` | +| Inference interception | Supported | + +## Container Image Compatibility (BYOC) + +| Image Type | Supported | Notes | +|------------|-----------|-------| +| Standard Linux images | Yes | Must have glibc and `/proc`. | +| Alpine / musl-based | Yes | Requires `iproute2` for proxy mode. | +| Distroless / `FROM scratch` | No | Supervisor needs glibc, `/proc`, and a shell. | +| Images without `iproute2` | Partial | Works in Block mode; fails in Proxy mode. | + +## Database Backends + +| Backend | Support | +|---------|---------| +| SQLite | Default. No configuration needed. | +| PostgreSQL | Supported as an alternative. | diff --git a/docs/clusters/index.md b/docs/clusters/index.md new file mode 100644 index 00000000..8c1a564a --- /dev/null +++ b/docs/clusters/index.md @@ -0,0 +1,77 @@ + + +# About Clusters + +NemoClaw packages the entire platform — Kubernetes, the gateway, networking, and pre-loaded container images — into a single Docker container. Docker is the only dependency. + +## Bootstrapping a Cluster + +```console +$ nemoclaw cluster admin deploy +``` + +This provisions a local k3s cluster in Docker, pre-loaded with all required images and Helm charts. The cluster is automatically set as the active cluster. + +### What Gets Created + +- A Docker container running k3s (lightweight Kubernetes). +- The NemoClaw gateway (control plane) deployed as a Kubernetes service. +- Pre-loaded sandbox and gateway container images. +- mTLS certificates for secure communication. +- Cluster metadata stored in `~/.config/nemoclaw/clusters/`. + +## Cluster Lifecycle + +| Command | Description | +|---------|-------------| +| `nemoclaw cluster admin deploy` | Provision or restart a cluster (idempotent). | +| `nemoclaw cluster admin stop` | Stop the cluster container (preserves state). | +| `nemoclaw cluster admin destroy` | Destroy the cluster and all its state. | +| `nemoclaw cluster status` | Check gateway connectivity and version. | +| `nemoclaw cluster list` | List all provisioned clusters. | +| `nemoclaw cluster use ` | Set the active cluster. | + +### Idempotent Deploy + +Running `deploy` again is safe. It reuses existing infrastructure or recreates only what changed. + +### Stop vs. Destroy + +- **Stop** pauses the Docker container, preserving all state (sandboxes, providers, routes). Restarting with `deploy` brings everything back. +- **Destroy** permanently removes the container, volumes, kubeconfig, metadata, and mTLS certificates. + +## Cluster Resolution + +The CLI resolves which cluster to operate on through this priority chain: + +1. `--cluster` flag (explicit). +2. `NEMOCLAW_CLUSTER` environment variable. +3. Active cluster set by `nemoclaw cluster use`. + +## Multiple Clusters + +You can manage multiple clusters simultaneously: + +```console +$ nemoclaw cluster admin deploy --name dev +$ nemoclaw cluster admin deploy --name staging --port 8081 +$ nemoclaw cluster list +$ nemoclaw cluster use dev +``` + +## Remote Deployment + +Deploy NemoClaw on a remote host via SSH. See [Remote Deployment](remote-deploy.md). + +## Cluster Info + +View deployment details: + +```console +$ nemoclaw cluster admin info +``` + +Shows the gateway endpoint, kubeconfig path, kube port, and remote host (if applicable). diff --git a/docs/clusters/remote-deploy.md b/docs/clusters/remote-deploy.md new file mode 100644 index 00000000..d5025150 --- /dev/null +++ b/docs/clusters/remote-deploy.md @@ -0,0 +1,63 @@ + + +# Remote Deployment + +NemoClaw can deploy clusters on remote hosts via SSH. The same bootstrap flow that works locally also works on remote machines — Docker on the remote host is the only requirement. + +## Deploying Remotely + +```console +$ nemoclaw cluster admin deploy --remote user@host --ssh-key ~/.ssh/id_rsa +``` + +This: + +1. Connects to the remote host via SSH. +2. Pulls the NemoClaw cluster image on the remote Docker daemon. +3. Provisions the k3s cluster, gateway, and all components on the remote host. +4. Extracts the kubeconfig and mTLS certificates back to your local machine. +5. Sets the remote cluster as the active cluster. + +All subsequent CLI commands (sandbox create, provider management, etc.) operate against the remote cluster transparently. + +## Creating Sandboxes Remotely + +You can bootstrap a remote cluster and create a sandbox in a single command: + +```console +$ nemoclaw sandbox create --remote user@host -- claude +``` + +If no cluster exists on the remote host, one is bootstrapped automatically. + +## Accessing the Kubernetes API + +For kubectl access to a remote cluster, use the tunnel command: + +```console +$ nemoclaw cluster admin tunnel --name my-remote-cluster +``` + +This starts an SSH tunnel so `kubectl` can reach the Kubernetes API on the remote host. + +To print the SSH command without executing it: + +```console +$ nemoclaw cluster admin tunnel --name my-remote-cluster --print-command +``` + +## Managing Remote Clusters + +All lifecycle commands accept `--remote` and `--ssh-key` flags: + +```console +$ nemoclaw cluster admin stop --remote user@host --ssh-key ~/.ssh/id_rsa +$ nemoclaw cluster admin destroy --remote user@host --ssh-key ~/.ssh/id_rsa +``` + +## How It Works + +Remote deployment uses the Docker daemon over SSH (`ssh://user@host`). All operations — image pulls, container creation, health checks, kubeconfig extraction — are executed via the Docker API on the remote daemon. No additional software needs to be installed on the remote host beyond Docker. diff --git a/docs/conf.py b/docs/conf.py index f1c2ff2f..17c00993 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -38,6 +38,7 @@ exclude_patterns = [ "README.md", + "SETUP.md", "_build/**", ] diff --git a/docs/feature1/index.md b/docs/feature1/index.md deleted file mode 100644 index debf3ae8..00000000 --- a/docs/feature1/index.md +++ /dev/null @@ -1,6 +0,0 @@ - - -# Feature 1 diff --git a/docs/feature2/index.md b/docs/feature2/index.md deleted file mode 100644 index 9b14022e..00000000 --- a/docs/feature2/index.md +++ /dev/null @@ -1,6 +0,0 @@ - - -# Feature 2 diff --git a/docs/gator/index.md b/docs/gator/index.md new file mode 100644 index 00000000..870cd755 --- /dev/null +++ b/docs/gator/index.md @@ -0,0 +1,111 @@ + + +# About Gator TUI + +Gator is a terminal user interface for NemoClaw, inspired by [k9s](https://k9scli.io/). Instead of typing individual CLI commands to check cluster health, list sandboxes, and manage resources, Gator gives you a real-time, keyboard-driven dashboard. + +## Launching Gator + +```console +$ nemoclaw gator +$ nemoclaw gator --cluster prod +$ NEMOCLAW_CLUSTER=prod nemoclaw gator +``` + +Gator inherits all CLI configuration — cluster selection, TLS settings, and verbosity flags work the same way. No separate configuration is needed. + +## Screen Layout + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ gator ─ my-cluster ─ Dashboard ● Healthy │ ← title bar +├─────────────────────────────────────────────────────────────────┤ +│ │ +│ (view content — Dashboard or Sandboxes) │ ← main area +│ │ +├─────────────────────────────────────────────────────────────────┤ +│ [1] Dashboard [2] Sandboxes │ [?] Help [q] Quit │ ← nav bar +├─────────────────────────────────────────────────────────────────┤ +│ : │ ← command bar +└─────────────────────────────────────────────────────────────────┘ +``` + +- **Title bar** — Gator logo, cluster name, current view, and live health status. +- **Main area** — the active view. +- **Navigation bar** — available views with shortcut keys. +- **Command bar** — appears when you press `:` (vim-style). + +## Views + +### Dashboard (press `1`) + +Shows your cluster at a glance: + +- **Cluster name** and **gateway endpoint**. +- **Health status** — polls every 2 seconds: + - `●` **Healthy** (green) — everything is running normally. + - `◐` **Degraded** (yellow) — the cluster is up but something needs attention. + - `○` **Unhealthy** (red) — the cluster is not operating correctly. +- **Sandbox count**. + +### Sandboxes (press `2`) + +A live table of all sandboxes: + +| Column | Description | +|--------|-------------| +| NAME | Sandbox name. | +| STATUS | Current phase, color-coded (green = Ready, yellow = Provisioning, red = Error). | +| AGE | Time since creation. | +| IMAGE | Container image. | +| PROVIDERS | Attached provider names. | +| NOTES | Metadata like forwarded ports (`fwd:8080,3000`). | + +Navigate with `j`/`k` or arrow keys. + +## Keyboard Controls + +### Normal Mode + +| Key | Action | +|-----|--------| +| `1` | Switch to Dashboard. | +| `2` | Switch to Sandboxes. | +| `j` / `↓` | Move selection down. | +| `k` / `↑` | Move selection up. | +| `:` | Enter command mode. | +| `q` | Quit Gator. | +| `Ctrl+C` | Force quit. | + +### Command Mode + +Press `:` to open the command bar. Type a command and press `Enter`. + +| Command | Action | +|---------|--------| +| `quit` / `q` | Quit Gator. | +| `dashboard` / `1` | Switch to Dashboard. | +| `sandboxes` / `2` | Switch to Sandboxes. | + +Press `Esc` to cancel. + +## Port Forwarding + +When creating a sandbox in Gator, specify ports in the **Ports** field (comma-separated, e.g., `8080,3000`). After the sandbox reaches `Ready` state, Gator automatically spawns background SSH tunnels. Forwarded ports appear in the **NOTES** column and in the sandbox detail view. + +## Data Refresh + +Gator polls the cluster every 2 seconds. Both cluster health and the sandbox list update automatically — no manual refresh needed. + +## Theme + +Gator uses a dark terminal theme based on the NVIDIA brand palette: + +- **Background**: Terminal black. +- **Text**: White for primary, dimmed for secondary. +- **Accent**: NVIDIA Green (`#76b900`) for selected rows, active tabs, and healthy status. +- **Borders**: Everglade (`#123123`) for structural separators. +- **Status**: Green = Ready/Healthy, Yellow = Provisioning/Degraded, Red = Error/Unhealthy. diff --git a/docs/get-started/first-sandbox.md b/docs/get-started/first-sandbox.md new file mode 100644 index 00000000..2074fe28 --- /dev/null +++ b/docs/get-started/first-sandbox.md @@ -0,0 +1,117 @@ + + +# Your First Sandbox + +This walkthrough takes you from a fresh install to an interactive sandbox session. By the end, you will have a running AI agent inside an isolated environment with full policy enforcement. + +## Step 1: Bootstrap a Cluster + +If you don't have a cluster running yet: + +```console +$ nemoclaw cluster admin deploy +``` + +This provisions a local k3s cluster inside a Docker container. The cluster is automatically set as the active cluster. + +For remote deployment (running the cluster on a different machine): + +```console +$ nemoclaw cluster admin deploy --remote user@host --ssh-key ~/.ssh/id_rsa +``` + +### Verify the Cluster + +```console +$ nemoclaw cluster status +``` + +You should see the cluster version and a healthy status. + +## Step 2: Set Up Providers + +Providers supply credentials to sandboxes (API keys, tokens, etc.). When you use `nemoclaw sandbox create -- claude`, the CLI auto-discovers local Claude credentials and creates a provider for you. You can also set up providers manually: + +```console +$ nemoclaw provider create --name my-claude --type claude --from-existing +``` + +The `--from-existing` flag scans your local machine for credentials (environment variables like `ANTHROPIC_API_KEY`, config files like `~/.claude.json`). + +To see what providers you have: + +```console +$ nemoclaw provider list +``` + +## Step 3: Create a Sandbox + +The simplest way to get a sandbox running: + +```console +$ nemoclaw sandbox create -- claude +``` + +This creates a sandbox with defaults, auto-discovers and uploads your Claude credentials, and drops you into an interactive shell. + +### With More Options + +```console +$ nemoclaw sandbox create \ + --name my-sandbox \ + --provider my-claude \ + --provider my-github \ + --sync \ + -- claude +``` + +- `--name` — give the sandbox a specific name. +- `--provider` — attach providers explicitly (repeatable). +- `--sync` — push local git-tracked files to `/sandbox` in the container. + +## Step 4: Work Inside the Sandbox + +Once connected, you are inside an isolated environment. All provider credentials are available as environment variables: + +```console +sandbox@my-sandbox:~$ echo $ANTHROPIC_API_KEY +sk-ant-... + +sandbox@my-sandbox:~$ claude +``` + +The sandbox enforces its safety and privacy policy: +- Your data is protected — filesystem access is restricted to allowed directories. +- No data leaves unmonitored — network connections go through the privacy-enforcing proxy. +- Only explicitly permitted hosts and programs can reach the internet. + +## Step 5: Connect from Another Terminal + +If you exited the sandbox or want a second session: + +```console +$ nemoclaw sandbox connect my-sandbox +``` + +For VS Code Remote-SSH access: + +```console +$ nemoclaw sandbox ssh-config my-sandbox >> ~/.ssh/config +``` + +Then connect via VS Code's Remote-SSH extension to the host `my-sandbox`. + +## Step 6: Clean Up + +```console +$ nemoclaw sandbox delete my-sandbox +``` + +## Next Steps + +- [Sandboxes](../sandboxes/index.md) — full sandbox lifecycle management. +- [Providers](../sandboxes/providers.md) — managing credentials. +- [Safety & Privacy](../security/index.md) — understanding and customizing sandbox policies. diff --git a/docs/get-started/index.md b/docs/get-started/index.md index 6452a1e9..d881162c 100644 --- a/docs/get-started/index.md +++ b/docs/get-started/index.md @@ -3,4 +3,48 @@ SPDX-License-Identifier: Apache-2.0 --> -# Get Started +# About Getting Started + +NemoClaw is designed for minimal setup with safety and privacy built in from the start. Docker is the only prerequisite. + +## Quickstart + +**Step 1: Install the CLI.** + +```console +$ pip install nemoclaw +``` + +See [Installation](installation.md) for detailed prerequisites and alternative install methods. + +**Step 2: Create a sandbox.** + +```console +$ nemoclaw sandbox create -- claude +``` + +If no cluster exists, the CLI automatically bootstraps one. It provisions a local Kubernetes cluster inside a Docker container, discovers your AI provider credentials from local configuration files, uploads them to the gateway, and launches a sandbox — all from a single command. + +**Step 3: Connect to a running sandbox.** + +```console +$ nemoclaw sandbox connect +``` + +This opens an interactive SSH session into the sandbox, with all provider credentials available as environment variables. + +## What Happens Under the Hood + +When you run `nemoclaw sandbox create -- claude`, the CLI: + +1. Checks for a running cluster. If none exists, it bootstraps one automatically (a k3s cluster inside a Docker container). +2. Scans your local machine for Claude credentials (`ANTHROPIC_API_KEY`, `~/.claude.json`, etc.) and uploads them to the gateway as a provider. +3. Creates a sandbox pod with the default policy and attaches the discovered provider. +4. Waits for the sandbox to reach `Ready` state. +5. Opens an interactive SSH session into the sandbox. + +## Next Steps + +- [Installation](installation.md) — detailed prerequisites and install methods. +- [Your First Sandbox](first-sandbox.md) — a step-by-step walkthrough. +- [Sandboxes](../sandboxes/index.md) — full sandbox management guide. diff --git a/docs/get-started/installation.md b/docs/get-started/installation.md new file mode 100644 index 00000000..255f9925 --- /dev/null +++ b/docs/get-started/installation.md @@ -0,0 +1,48 @@ + + +# Installation + +## Prerequisites + +- **Docker** — must be installed and running. This is the only runtime dependency. +- **Python 3.12+** — required for `pip install`. + +## Install the CLI + +```console +$ pip install nemoclaw +``` + +This installs the `nemoclaw` command (also available as `ncl`). + +### Verify the Installation + +```console +$ nemoclaw --help +``` + +You should see the top-level help with command groups: `cluster`, `sandbox`, `provider`, `inference`, and `gator`. + +## Shell Completions + +Generate shell completions for tab-completion support: + +```console +$ nemoclaw completions bash >> ~/.bashrc +$ nemoclaw completions zsh >> ~/.zshrc +$ nemoclaw completions fish >> ~/.config/fish/completions/nemoclaw.fish +``` + +## For Contributors + +If you are developing NemoClaw itself, see the [Contributing Guide](https://github.com/NVIDIA/NemoClaw/blob/main/CONTRIBUTING.md) for building from source using `mise`. + +The contributor workflow uses a local shortcut script at `scripts/bin/nemoclaw` that automatically builds the CLI from source. With `mise` active, you can run `nemoclaw` directly from the repository. + +```console +$ mise trust +$ mise run sandbox +``` diff --git a/docs/index.md b/docs/index.md index 96144b97..1acd4a53 100644 --- a/docs/index.md +++ b/docs/index.md @@ -5,13 +5,98 @@ # NVIDIA NemoClaw Developer Guide -NemoClaw is the runtime environment for autonomous agents. It provides secure sandboxed execution, cluster management, and infrastructure for running AI agent workloads. +NemoClaw is the safe, private runtime for autonomous AI agents. It provides sandboxed execution environments that protect your data, credentials, and infrastructure — agents run with exactly the permissions they need and nothing more, governed by declarative policies that prevent unauthorized file access, data exfiltration, and uncontrolled network activity. + +::::{grid} 2 2 3 3 +:gutter: 3 + +:::{grid-item-card} About +:link: about/index +:link-type: doc + +Learn what NemoClaw is, how the subsystems fit together, and the safety and privacy model that protects your data and infrastructure. +::: + +:::{grid-item-card} Get Started +:link: get-started/index +:link-type: doc + +Install the CLI, bootstrap a cluster, and launch your first sandbox in minutes. +::: + +:::{grid-item-card} Sandboxes +:link: sandboxes/index +:link-type: doc + +Create, connect to, and manage sandboxes with built-in safety guarantees. Configure providers, sync files, forward ports, and bring your own containers. +::: + +:::{grid-item-card} Safety and Privacy +:link: security/index +:link-type: doc + +Understand how NemoClaw keeps your data safe and private — and write policies that control filesystem, network, and inference access. +::: + +:::{grid-item-card} Inference Routing +:link: inference/index +:link-type: doc + +Keep inference traffic private by routing AI API calls to local or self-hosted backends — without modifying agent code. +::: + +:::{grid-item-card} Clusters +:link: clusters/index +:link-type: doc + +Bootstrap, manage, and deploy NemoClaw clusters locally or on remote hosts via SSH. +::: + +:::{grid-item-card} Gator TUI +:link: gator/index +:link-type: doc + +Use the keyboard-driven terminal dashboard for real-time cluster monitoring and sandbox management. +::: + +:::{grid-item-card} Observability +:link: observability/index +:link-type: doc + +Stream sandbox logs, audit agent activity, and monitor policy enforcement in real time. +::: + +:::{grid-item-card} Reference +:link: reference/index +:link-type: doc + +CLI command reference, policy schema, environment variables, and system architecture diagrams. +::: + +:::{grid-item-card} Troubleshooting +:link: troubleshooting/index +:link-type: doc + +Diagnose common issues with clusters, sandboxes, and networking. +::: + +:::{grid-item-card} Resources +:link: resources/index +:link-type: doc + +Links to the GitHub repository, related projects, and additional learning materials. +::: + +:::: ```{toctree} :caption: About :hidden: about/index +about/how-it-works +about/support-matrix +about/release-notes ``` ```{toctree} @@ -19,20 +104,51 @@ about/index :hidden: get-started/index +get-started/installation +get-started/first-sandbox +``` + +```{toctree} +:caption: Sandboxes +:hidden: + +sandboxes/index +sandboxes/create-and-manage +sandboxes/providers +sandboxes/custom-containers +sandboxes/file-sync +sandboxes/port-forwarding +``` + +```{toctree} +:caption: Safety and Privacy +:hidden: + +security/index +security/policies +security/network-access +``` + +```{toctree} +:caption: Inference Routing +:hidden: + +inference/index ``` ```{toctree} -:caption: Feature 1 +:caption: Clusters :hidden: -feature1/index +clusters/index +clusters/remote-deploy ``` ```{toctree} -:caption: Feature 2 +:caption: Gator TUI :hidden: -feature2/index +gator/index ``` ```{toctree} @@ -47,6 +163,10 @@ observability/index :hidden: reference/index +reference/cli +reference/policy-schema +reference/environment-variables +reference/architecture ``` ```{toctree} diff --git a/docs/inference/index.md b/docs/inference/index.md new file mode 100644 index 00000000..614ac0c8 --- /dev/null +++ b/docs/inference/index.md @@ -0,0 +1,110 @@ + + +# About Inference Routing + +The inference routing system keeps your AI inference traffic private by transparently intercepting API calls from sandboxed agents and rerouting them to policy-controlled backends. This enables organizations to keep sensitive prompts and model responses on private infrastructure — redirecting traffic to local or self-hosted models without modifying the agent's code. + +## How It Works + +When an agent inside a sandbox makes an API call (e.g., using the OpenAI or Anthropic SDK), the request flows through the sandbox proxy. If the destination does not match any explicit network policy but the sandbox has inference routes configured, the proxy: + +1. **TLS-terminates** the connection using the sandbox's ephemeral CA. +2. **Detects the inference API pattern** (e.g., `POST /v1/chat/completions` for OpenAI, `POST /v1/messages` for Anthropic). +3. **Strips authorization headers** and forwards the request to a matching backend. +4. **Rewrites the authorization** with the route's API key and injects the correct model ID. +5. **Returns the response** to the agent — the agent sees a normal HTTP response as if it came from the original API. + +Agents need zero code changes. Standard OpenAI/Anthropic SDK calls work transparently. + +```{mermaid} +sequenceDiagram + participant Agent as Sandboxed Agent + participant Proxy as Sandbox Proxy + participant OPA as OPA Engine + participant Router as Local Router + participant Backend as Backend (e.g., LM Studio) + + Agent->>Proxy: CONNECT api.openai.com:443 + Proxy->>OPA: evaluate_network_action(input) + OPA-->>Proxy: InspectForInference + Proxy-->>Agent: 200 Connection Established + Proxy->>Proxy: TLS terminate (ephemeral CA) + Agent->>Proxy: POST /v1/chat/completions + Proxy->>Proxy: detect_inference_pattern() + Proxy->>Router: route to matching backend + Router->>Backend: POST /v1/chat/completions + Backend-->>Router: 200 OK + Router-->>Proxy: response + Proxy-->>Agent: HTTP 200 OK (re-encrypted) +``` + +## Creating Inference Routes + +Create a route that maps a routing hint to a backend: + +```console +$ nemoclaw inference create \ + --routing-hint local \ + --base-url https://my-llm.example.com \ + --model-id my-model-v1 \ + --api-key sk-abc123 +``` + +If `--protocol` is omitted, the CLI auto-detects by probing the endpoint. + +| Flag | Description | +|------|-------------| +| `--routing-hint` (required) | Name used in sandbox policy to reference this route. | +| `--base-url` (required) | Backend inference endpoint URL. | +| `--model-id` (required) | Model identifier sent to the backend. | +| `--api-key` | API key for the backend endpoint. | +| `--protocol` | Supported protocol(s): `openai_chat_completions`, `openai_completions`, `anthropic_messages` (repeatable, auto-detected if omitted). | +| `--disabled` | Create the route in disabled state. | + +## Managing Routes + +```console +$ nemoclaw inference list +$ nemoclaw inference update my-route --routing-hint local --base-url https://new-url.example.com +$ nemoclaw inference delete my-route +``` + +## Connecting Sandboxes to Inference Routes + +Add the routing hint to the sandbox policy's `inference.allowed_routes`: + +```yaml +inference: + allowed_routes: + - local +``` + +Then create the sandbox with that policy: + +```console +$ nemoclaw sandbox create --policy ./policy-with-inference.yaml -- claude +``` + +## Key Design Properties + +- **Zero agent code changes** — standard SDK calls work transparently. +- **Inference privacy** — prompts and responses stay on your infrastructure when routed to local backends. +- **Credential isolation** — the sandbox never sees the real API key for the backend, protecting your credentials. +- **Policy-controlled** — `inference.allowed_routes` determines which routes a sandbox can use. +- **Hot-reloadable** — the `inference` policy field is dynamic and can be updated on a running sandbox. +- **Automatic cache refresh** — in cluster mode, the sandbox refreshes its route cache from the gateway every 30 seconds. + +## Supported API Patterns + +The proxy detects these inference API patterns: + +| Pattern | Method | Path | +|---------|--------|------| +| `openai_chat_completions` | POST | `/v1/chat/completions` | +| `openai_completions` | POST | `/v1/completions` | +| `anthropic_messages` | POST | `/v1/messages` | + +If an intercepted request does not match any known pattern, it is denied with a descriptive error. diff --git a/docs/observability/index.md b/docs/observability/index.md index 31d92605..90248629 100644 --- a/docs/observability/index.md +++ b/docs/observability/index.md @@ -3,4 +3,83 @@ SPDX-License-Identifier: Apache-2.0 --> -# Observability +# About Observability + +NemoClaw provides log streaming and monitoring for sandboxes and the gateway. + +## Sandbox Logs + +View recent logs from a sandbox: + +```console +$ nemoclaw sandbox logs my-sandbox +``` + +### Live Streaming + +Stream logs in real time: + +```console +$ nemoclaw sandbox logs my-sandbox --tail +``` + +### Filtering + +Filter by source, level, and time range: + +```console +$ nemoclaw sandbox logs my-sandbox --tail --source sandbox --level warn +$ nemoclaw sandbox logs my-sandbox --since 5m +$ nemoclaw sandbox logs my-sandbox --source gateway --level error +``` + +| Flag | Description | +|------|-------------| +| `--tail` | Stream live logs (does not exit). | +| `--source` | Filter by source: `gateway`, `sandbox`, or `all` (repeatable). | +| `--level` | Minimum log level: `error`, `warn`, `info`, `debug`, `trace`. | +| `--since` | Show logs from this duration ago (e.g., `5m`, `1h`, `30s`). | +| `-n ` | Number of log lines to fetch (default: 200). | + +### Log Sources + +| Source | Content | +|--------|---------| +| `gateway` | Gateway-side events: sandbox lifecycle, gRPC calls, pod management. | +| `sandbox` | Sandbox-side events: proxy decisions, policy evaluation, connection allows/denies. | + +## Monitoring Denied Actions + +When iterating on sandbox policies, the most useful view is sandbox-level deny events: + +```console +$ nemoclaw sandbox logs my-sandbox --tail --source sandbox +``` + +Deny log entries include: + +- **Destination host and port** — what the agent tried to reach. +- **Binary path** — which program attempted the connection. +- **Deny reason** — why the connection was blocked (no matching policy, binary mismatch, etc.). + +This information drives the [policy iteration loop](../security/policies.md#the-policy-iteration-loop). + +## Log Architecture + +Sandbox logs are pushed from the sandbox process to the gateway using a background batching layer. The sandbox collects log entries from its tracing subscriber and streams them to the gateway via gRPC in batches. The gateway stores log entries and makes them available via the CLI's `logs` command. + +This push-based model means logs are available even if you are not actively streaming — you can always retrieve recent logs after the fact. + +## Cluster Health + +### CLI + +```console +$ nemoclaw cluster status +``` + +Shows gateway connectivity and version. + +### Gator TUI + +The [Gator TUI](../gator/index.md) dashboard polls cluster health every 2 seconds, displaying real-time status: Healthy, Degraded, or Unhealthy. diff --git a/docs/reference/architecture.md b/docs/reference/architecture.md new file mode 100644 index 00000000..083bdfa5 --- /dev/null +++ b/docs/reference/architecture.md @@ -0,0 +1,88 @@ + + +# System Architecture + +This page provides a high-level view of NemoClaw's system architecture and component interactions. + +## Architecture Diagram + +```{mermaid} +flowchart TB + subgraph USER["User's Machine"] + CLI["Command-Line Interface"] + end + + subgraph CLUSTER["Kubernetes Cluster (single Docker container)"] + SERVER["Gateway / Control Plane"] + DB["Database (SQLite or Postgres)"] + + subgraph SBX["Sandbox Pod"] + SUPERVISOR["Sandbox Supervisor"] + PROXY["Network Proxy"] + CHILD["Agent Process (restricted)"] + OPA["Policy Engine (OPA)"] + end + end + + subgraph EXT["External Services"] + HOSTS["Allowed Hosts"] + BACKEND["Inference Backends"] + end + + CLI -- "gRPC / HTTPS" --> SERVER + CLI -- "SSH over HTTP CONNECT" --> SERVER + SERVER -- "CRUD + Watch" --> DB + SERVER -- "Create / Delete Pods" --> SBX + SUPERVISOR -- "Fetch Policy + Credentials" --> SERVER + SUPERVISOR -- "Spawn + Restrict" --> CHILD + CHILD -- "All network traffic" --> PROXY + PROXY -- "Evaluate request" --> OPA + PROXY -- "Allowed traffic only" --> HOSTS + PROXY -- "Inference reroute" --> SERVER + SERVER -- "Proxied inference" --> BACKEND +``` + +## Component Summary + +| Component | Description | +|-----------|-------------| +| **CLI** (`nemoclaw`) | Primary user interface. Manages clusters, sandboxes, providers, and inference routes. | +| **Gateway** | Central control plane. Provides gRPC and HTTP APIs, manages sandbox lifecycle in Kubernetes, stores data in SQLite/Postgres. | +| **Sandbox Supervisor** | Runs inside each sandbox pod. Sets up isolation (Landlock, seccomp, netns), runs the proxy, spawns the agent. | +| **Network Proxy** | HTTP CONNECT proxy inside the sandbox. Evaluates every outbound connection against the OPA policy. | +| **OPA Engine** | Embedded Rego policy evaluator (regorus crate). No external OPA daemon. | +| **Gator TUI** | Terminal dashboard for real-time cluster and sandbox monitoring. | + +## Container Images + +NemoClaw produces three container images: + +| Image | Purpose | +|-------|---------| +| **Sandbox** | Runs inside each sandbox pod. Contains the supervisor binary, Python runtime, and agent tooling. | +| **Gateway** | Runs the control plane. Contains the gateway binary, database migrations, and SSH client. | +| **Cluster** | Airgapped Kubernetes image with k3s, pre-loaded sandbox/gateway images, Helm charts, and API gateway. This is the single container users deploy. | + +## Communication Protocols + +| Path | Protocol | Description | +|------|----------|-------------| +| CLI to Gateway | gRPC over mTLS | Sandbox CRUD, provider management, inference routes, session creation. | +| CLI to Sandbox | SSH over HTTP CONNECT | Interactive shells, command execution, file sync. Tunneled through the gateway. | +| Sandbox to Gateway | gRPC over mTLS | Policy fetching, credential retrieval, inference bundle delivery, log push, policy status reporting. | +| Proxy to External | HTTPS | Outbound connections from the sandbox, filtered by policy. | +| Proxy to Backend | HTTP/HTTPS | Inference requests rerouted to configured backends. | + +## Project Structure + +| Path | Purpose | +|------|---------| +| `crates/` | Rust crates (CLI, gateway, sandbox, TUI, bootstrap, router, core, providers). | +| `python/` | Python SDK and bindings. | +| `proto/` | Protocol buffer definitions. | +| `deploy/` | Dockerfiles, Helm chart, Kubernetes manifests. | +| `architecture/` | Internal architecture documentation. | +| `tasks/` | `mise` task definitions. | diff --git a/docs/reference/cli.md b/docs/reference/cli.md new file mode 100644 index 00000000..f8b0cab9 --- /dev/null +++ b/docs/reference/cli.md @@ -0,0 +1,179 @@ + + +# CLI Reference + +The `nemoclaw` CLI (also available as `ncl`) is the primary interface for managing sandboxes, providers, inference routes, and clusters. + +:::{tip} +The CLI has comprehensive built-in help. Use `nemoclaw --help` at any level to discover commands and flags. +::: + +## Global Options + +| Flag | Description | +|------|-------------| +| `-v`, `--verbose` | Increase verbosity (`-v` = info, `-vv` = debug, `-vvv` = trace). | +| `-c`, `--cluster ` | Cluster to operate on (also via `NEMOCLAW_CLUSTER` env var). | + +## Command Tree + +``` +nemoclaw (ncl) +├── cluster +│ ├── status # Check gateway connectivity +│ ├── use # Set active cluster +│ ├── list # List all clusters +│ └── admin +│ ├── deploy [opts] # Provision or restart cluster +│ ├── stop [opts] # Stop cluster (preserve state) +│ ├── destroy [opts] # Destroy cluster permanently +│ ├── info [--name] # Show deployment details +│ └── tunnel [opts] # SSH tunnel for kubectl access +├── sandbox +│ ├── create [opts] [-- CMD...] # Create sandbox and connect +│ ├── get # Show sandbox details +│ ├── list [opts] # List sandboxes +│ ├── delete ... # Delete sandboxes +│ ├── connect # SSH into sandbox +│ ├── sync {--up|--down} # Sync files +│ ├── logs [opts] # View/stream logs +│ ├── ssh-config # Print SSH config block +│ ├── forward +│ │ ├── start [-d] # Start port forward +│ │ ├── stop # Stop port forward +│ │ └── list # List active forwards +│ ├── image +│ │ └── push [opts] # Build and push custom image +│ └── policy +│ ├── set --policy # Update live policy +│ ├── get [--full] # Show current policy +│ └── list # Policy revision history +├── provider +│ ├── create --name --type [opts] # Create provider +│ ├── get # Show provider details +│ ├── list [opts] # List providers +│ ├── update --type [opts] # Update provider +│ └── delete ... # Delete providers +├── inference +│ ├── create [opts] # Create inference route +│ ├── update [opts] # Update inference route +│ ├── delete ... # Delete inference routes +│ └── list [opts] # List inference routes +├── gator # Launch TUI +└── completions # Generate shell completions +``` + +## Cluster Commands + +### `nemoclaw cluster admin deploy` + +Provision or start a cluster (local or remote). + +| Flag | Default | Description | +|------|---------|-------------| +| `--name ` | `nemoclaw` | Cluster name. | +| `--remote ` | — | SSH destination for remote deployment. | +| `--ssh-key ` | — | SSH private key for remote deployment. | +| `--port ` | 8080 | Host port mapped to gateway. | +| `--kube-port [PORT]` | — | Expose K8s control plane on host port. | + +### `nemoclaw cluster admin stop` + +Stop a cluster container (preserves state for later restart). + +### `nemoclaw cluster admin destroy` + +Destroy a cluster and all its state permanently. + +### `nemoclaw cluster admin info` + +Show deployment details: endpoint, kubeconfig path, kube port, remote host. + +### `nemoclaw cluster admin tunnel` + +Start or print an SSH tunnel for kubectl access to a remote cluster. + +## Sandbox Commands + +### `nemoclaw sandbox create [OPTIONS] [-- COMMAND...]` + +Create a sandbox, wait for readiness, then connect or execute the trailing command. + +| Flag | Description | +|------|-------------| +| `--name ` | Sandbox name (auto-generated if omitted). | +| `--image ` | Custom container image (BYOC). | +| `--sync` | Sync local git-tracked files to `/sandbox`. | +| `--keep` | Keep sandbox alive after command exits. | +| `--provider ` | Provider to attach (repeatable). | +| `--policy ` | Path to custom policy YAML. | +| `--forward ` | Forward local port to sandbox (implies `--keep`). | +| `--remote ` | SSH destination for auto-bootstrap. | + +### `nemoclaw sandbox logs ` + +| Flag | Default | Description | +|------|---------|-------------| +| `-n ` | 200 | Number of log lines. | +| `--tail` | — | Stream live logs. | +| `--since ` | — | Logs from this duration ago (e.g., `5m`, `1h`). | +| `--source ` | `all` | Filter: `gateway`, `sandbox`, or `all`. | +| `--level ` | — | Minimum level: `error`, `warn`, `info`, `debug`, `trace`. | + +### `nemoclaw sandbox sync {--up|--down} [dest]` + +Sync files to/from a sandbox. + +### `nemoclaw sandbox forward start ` + +Start forwarding a local port to a sandbox. `-d` runs in background. + +## Policy Commands + +### `nemoclaw sandbox policy set --policy ` + +Update the policy on a live sandbox. Only dynamic fields can change at runtime. + +| Flag | Description | +|------|-------------| +| `--wait` | Wait for sandbox to confirm policy is loaded. | +| `--timeout ` | Timeout for `--wait` (default: 60). | + +### `nemoclaw sandbox policy get ` + +| Flag | Description | +|------|-------------| +| `--rev ` | Show a specific revision (default: latest). | +| `--full` | Print full policy as YAML (round-trips with `--policy`). | + +### `nemoclaw sandbox policy list ` + +Show policy revision history. + +## Provider Commands + +### `nemoclaw provider create --name --type ` + +| Flag | Description | +|------|-------------| +| `--from-existing` | Discover credentials from local machine. | +| `--credential KEY[=VALUE]` | Credential pair (repeatable). Bare `KEY` reads from env var. | +| `--config KEY=VALUE` | Config key/value pair (repeatable). | + +Supported types: `claude`, `opencode`, `codex`, `generic`, `nvidia`, `gitlab`, `github`, `outlook`. + +## Inference Commands + +### `nemoclaw inference create` + +| Flag | Description | +|------|-------------| +| `--routing-hint ` (required) | Routing hint for policy matching. | +| `--base-url ` (required) | Backend endpoint URL. | +| `--model-id ` (required) | Model identifier. | +| `--api-key ` | API key for the endpoint. | +| `--protocol ` | Protocol (auto-detected if omitted, repeatable). | +| `--disabled` | Create in disabled state. | diff --git a/docs/reference/environment-variables.md b/docs/reference/environment-variables.md new file mode 100644 index 00000000..97ace48b --- /dev/null +++ b/docs/reference/environment-variables.md @@ -0,0 +1,43 @@ + + +# Environment Variables + +## CLI Variables + +| Variable | Description | +|----------|-------------| +| `NEMOCLAW_CLUSTER` | Override the active cluster name (same as `--cluster` flag). | +| `NEMOCLAW_SANDBOX_POLICY` | Path to default sandbox policy YAML (fallback when `--policy` is not provided). | + +## Sandbox Variables + +These variables are set inside sandbox processes automatically: + +| Variable | Description | +|----------|-------------| +| `NEMOCLAW_SANDBOX` | Set to `1` inside all sandbox processes. | +| `HTTP_PROXY` | Proxy URL for HTTP traffic (set in proxy mode). | +| `HTTPS_PROXY` | Proxy URL for HTTPS traffic (set in proxy mode). | +| `ALL_PROXY` | Proxy URL for all traffic (set in proxy mode). | +| `SSL_CERT_FILE` | Path to the combined CA bundle (system CAs + sandbox ephemeral CA). | +| `NODE_EXTRA_CA_CERTS` | Same CA bundle path, for Node.js applications. | +| `REQUESTS_CA_BUNDLE` | Same CA bundle path, for Python requests library. | + +Provider credentials are also injected as environment variables. The specific variables depend on which providers are attached (e.g., `ANTHROPIC_API_KEY` for Claude, `GITHUB_TOKEN` for GitHub). + +## Sandbox Supervisor Variables + +These are used by the sandbox supervisor process and are not typically set by users: + +| Variable | Description | +|----------|-------------| +| `NEMOCLAW_SANDBOX_ID` | Sandbox ID (set by gateway in pod spec). | +| `NEMOCLAW_ENDPOINT` | Gateway gRPC endpoint (set by gateway in pod spec). | +| `NEMOCLAW_POLICY_RULES` | Path to `.rego` file (file mode only). | +| `NEMOCLAW_POLICY_DATA` | Path to YAML policy data file (file mode only). | +| `NEMOCLAW_INFERENCE_ROUTES` | Path to YAML inference routes file (standalone mode). | +| `NEMOCLAW_POLICY_POLL_INTERVAL_SECS` | Override policy poll interval (default: 30 seconds). | +| `NEMOCLAW_SANDBOX_COMMAND` | Default command when none specified (set to `sleep infinity` by server). | diff --git a/docs/reference/index.md b/docs/reference/index.md index d15068d3..d3f7bca1 100644 --- a/docs/reference/index.md +++ b/docs/reference/index.md @@ -3,4 +3,13 @@ SPDX-License-Identifier: Apache-2.0 --> -# Reference \ No newline at end of file +# About Reference + +Technical reference documentation for NemoClaw. + +## In This Section + +- [CLI Reference](cli.md) — complete command tree with all flags and options. +- [Policy Schema](policy-schema.md) — full YAML policy schema for sandbox policies. +- [Environment Variables](environment-variables.md) — configuration variables for the CLI, sandbox, and gateway. +- [Architecture](architecture.md) — system architecture diagrams and component overview. diff --git a/docs/reference/policy-schema.md b/docs/reference/policy-schema.md new file mode 100644 index 00000000..62715ec7 --- /dev/null +++ b/docs/reference/policy-schema.md @@ -0,0 +1,189 @@ + + +# Policy Schema Reference + +This is the complete YAML schema for NemoClaw sandbox policies. For a guide on using policies, see [Policies](../security/policies.md). + +## Full Schema + +```yaml +filesystem_policy: + read_only: # List of paths — read-only access (Landlock) + - /usr + - /etc + - /lib + read_write: # List of paths — read-write access (auto-created, chowned) + - /sandbox + - /tmp + +landlock: + compatibility: best_effort # best_effort | hard_requirement + +process: + run_as_user: sandbox # Username or UID + run_as_group: sandbox # Group name or GID + +network_policies: # Map of named network policy entries + : + endpoints: + - host: # Destination hostname + port: # Destination port (integer) + l7: # Optional — L7 inspection config + tls_mode: terminate # terminate + enforcement_mode: enforce # enforce | audit + access: # read-only | read-write | full (expands to rules) + rules: # Explicit HTTP rules (mutually exclusive with access) + - method: # HTTP method (GET, POST, PUT, DELETE, etc.) + path_pattern: # URL path pattern (glob) + binaries: + - path_patterns: # List of glob patterns for binary paths + - "**/git" + - "/usr/bin/curl" + +inference: + allowed_routes: # List of routing hint names + - local + - cloud +``` + +## Field Reference + +### `filesystem_policy` + +Controls directory-level access enforced by the Linux Landlock LSM. + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `read_only` | `list[string]` | No | Paths the agent can read but not write. | +| `read_write` | `list[string]` | No | Paths the agent can read and write. Directories are created and ownership is set to the `run_as_user` automatically. | + +**Note:** The working directory (`--workdir`, default `/sandbox`) is automatically added to `read_write` unless `include_workdir` is set to `false`. + +### `landlock` + +| Field | Type | Default | Description | +|-------|------|---------|-------------| +| `compatibility` | `string` | `best_effort` | `best_effort` — use the best available Landlock ABI version. `hard_requirement` — fail startup if the required ABI is not available. | + +### `process` + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `run_as_user` | `string` | No | Username or UID the child process runs as. | +| `run_as_group` | `string` | No | Group name or GID the child process runs as. | + +### `network_policies` + +A map where each key is a policy name and each value defines endpoints and allowed binaries. + +#### Endpoint Fields + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `host` | `string` | Yes | Destination hostname to match. | +| `port` | `integer` | Yes | Destination port to match. | +| `l7` | `object` | No | L7 inspection configuration (see below). | + +#### L7 Fields + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `tls_mode` | `string` | Yes | Must be `terminate` — the proxy terminates TLS and inspects plaintext HTTP. | +| `enforcement_mode` | `string` | No | `enforce` (default) — block non-matching requests. `audit` — log violations but allow traffic. | +| `access` | `string` | No | Preset: `read-only`, `read-write`, or `full`. Mutually exclusive with `rules`. | +| `rules` | `list[object]` | No | Explicit HTTP rules. Mutually exclusive with `access`. | + +#### L7 Rule Fields + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `method` | `string` | Yes | HTTP method (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`, `HEAD`, `OPTIONS`). | +| `path_pattern` | `string` | Yes | URL path pattern (glob matching). | + +#### Access Presets + +| Preset | Expands To | +|--------|-----------| +| `read-only` | `GET`, `HEAD`, `OPTIONS` | +| `read-write` | `GET`, `HEAD`, `OPTIONS`, `POST`, `PUT`, `PATCH`, `DELETE` | +| `full` | All HTTP methods | + +#### Binary Fields + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `path_patterns` | `list[string]` | Yes | Glob patterns matched against the full path of the requesting executable. | + +### `inference` + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `allowed_routes` | `list[string]` | No | List of routing hint names. Routes are created via `nemoclaw inference create`. | + +## Static vs. Dynamic Fields + +| Category | Fields | Updatable at Runtime? | +|----------|--------|----------------------| +| **Static** | `filesystem_policy`, `landlock`, `process` | No — immutable after creation. | +| **Dynamic** | `network_policies`, `inference` | Yes — updated via `nemoclaw sandbox policy set`. | + +## Example: Development Policy + +```yaml +filesystem_policy: + read_only: + - /usr + - /etc + - /lib + - /lib64 + - /bin + - /sbin + read_write: + - /sandbox + - /tmp + - /home/sandbox + +landlock: + compatibility: best_effort + +process: + run_as_user: sandbox + run_as_group: sandbox + +network_policies: + github: + endpoints: + - host: github.com + port: 443 + - host: api.github.com + port: 443 + binaries: + - path_patterns: ["**/git"] + - path_patterns: ["**/ssh"] + - path_patterns: ["**/curl"] + + anthropic: + endpoints: + - host: api.anthropic.com + port: 443 + binaries: + - path_patterns: ["**/claude"] + - path_patterns: ["**/node"] + + pypi: + endpoints: + - host: pypi.org + port: 443 + - host: files.pythonhosted.org + port: 443 + binaries: + - path_patterns: ["**/pip"] + - path_patterns: ["**/python*"] + +inference: + allowed_routes: + - local +``` diff --git a/docs/resources/index.md b/docs/resources/index.md index eb696ad1..f198f337 100644 --- a/docs/resources/index.md +++ b/docs/resources/index.md @@ -3,4 +3,37 @@ SPDX-License-Identifier: Apache-2.0 --> -# Resources +# About Resources + +## Links + +- [NemoClaw on GitHub](https://github.com/NVIDIA/NemoClaw) — source code, issues, and pull requests. +- [Contributing Guide](https://github.com/NVIDIA/NemoClaw/blob/main/CONTRIBUTING.md) — how to build from source and contribute. + +## Related Technologies + +| Technology | How NemoClaw Uses It | +|------------|---------------------| +| [k3s](https://k3s.io/) | Lightweight Kubernetes distribution used for the cluster runtime. | +| [OPA / Rego](https://www.openpolicyagent.org/) | Policy language for sandbox network access control. NemoClaw uses the `regorus` pure-Rust evaluator. | +| [Landlock](https://landlock.io/) | Linux security module for filesystem access control. | +| [seccomp](https://www.kernel.org/doc/html/latest/userspace-api/seccomp_filter.html) | Linux kernel system call filtering. | +| [ratatui](https://ratatui.rs/) | Rust TUI framework powering the Gator terminal dashboard. | +| [russh](https://github.com/warp-tech/russh) | Rust SSH library used for the sandbox embedded SSH server. | +| [Helm](https://helm.sh/) | Kubernetes package manager used for deploying NemoClaw components. | + +## Glossary + +| Term | Definition | +|------|-----------| +| **Sandbox** | An isolated execution environment for an AI agent, enforcing filesystem, network, and syscall restrictions. | +| **Supervisor** | The privileged process inside a sandbox that manages isolation and spawns the agent. | +| **Provider** | A credential store for external services (API keys, tokens). Injected as environment variables at runtime. | +| **Policy** | A YAML document defining what a sandbox can access (filesystem, network, inference). | +| **Gateway** | The central control plane service that manages sandboxes, providers, and routes. | +| **Inference Route** | A mapping from a routing hint to a backend AI model endpoint. | +| **BYOC** | Bring Your Own Container — running custom images as sandboxes. | +| **Gator** | The NemoClaw terminal user interface (TUI). | +| **L7 Inspection** | HTTP-level traffic inspection inside TLS tunnels. | +| **TOFU** | Trust-On-First-Use — the binary integrity verification model used by the proxy. | +| **mTLS** | Mutual TLS — both client and server present certificates. Used for all gateway communication. | diff --git a/docs/sandboxes/create-and-manage.md b/docs/sandboxes/create-and-manage.md new file mode 100644 index 00000000..63b4080d --- /dev/null +++ b/docs/sandboxes/create-and-manage.md @@ -0,0 +1,118 @@ + + +# Create and Manage Sandboxes + +## Creating a Sandbox + +The simplest form creates a sandbox with defaults and drops you into an interactive shell: + +```console +$ nemoclaw sandbox create +``` + +### With an Agent Tool + +When the trailing command is a recognized tool, the CLI auto-creates the required provider from local credentials: + +```console +$ nemoclaw sandbox create -- claude +$ nemoclaw sandbox create -- codex +``` + +### With Options + +```console +$ nemoclaw sandbox create \ + --name my-sandbox \ + --provider my-github \ + --provider my-claude \ + --policy ./my-policy.yaml \ + --sync \ + -- claude +``` + +| Flag | Description | +|------|-------------| +| `--name ` | Sandbox name (auto-generated if omitted). | +| `--provider ` | Provider to attach (repeatable). | +| `--policy ` | Custom policy YAML. Uses the built-in default if omitted. | +| `--sync` | Push local git-tracked files to `/sandbox` in the container. | +| `--keep` | Keep sandbox alive after the command exits. | +| `--forward ` | Forward a local port to the sandbox (implies `--keep`). | +| `--image ` | Custom container image (see [Custom Containers](custom-containers.md)). | + +### Auto-Bootstrap + +If no cluster is running, `sandbox create` offers to bootstrap one automatically. This is equivalent to running `nemoclaw cluster admin deploy` first. + +## Listing Sandboxes + +```console +$ nemoclaw sandbox list +``` + +| Flag | Description | +|------|-------------| +| `--limit ` | Maximum number of sandboxes to return (default: 100). | +| `--offset ` | Pagination offset. | +| `--names` | Print only sandbox names. | + +## Inspecting a Sandbox + +```console +$ nemoclaw sandbox get my-sandbox +``` + +Shows sandbox details including ID, name, namespace, phase, and policy. + +## Connecting to a Sandbox + +```console +$ nemoclaw sandbox connect my-sandbox +``` + +Opens an interactive SSH session. All provider credentials are available as environment variables inside the sandbox. + +### VS Code Remote-SSH + +```console +$ nemoclaw sandbox ssh-config my-sandbox >> ~/.ssh/config +``` + +Then use VS Code's Remote-SSH extension to connect to the host `my-sandbox`. + +## Viewing Logs + +```console +$ nemoclaw sandbox logs my-sandbox +``` + +| Flag | Description | +|------|-------------| +| `-n ` | Number of log lines (default: 200). | +| `--tail` | Stream live logs. | +| `--since ` | Show logs from this duration ago (e.g., `5m`, `1h`). | +| `--source ` | Filter by source: `gateway`, `sandbox`, or `all` (repeatable). | +| `--level ` | Minimum level: `error`, `warn`, `info`, `debug`, `trace`. | + +### Monitoring for Denied Actions + +When iterating on a sandbox policy, watch for denied network requests: + +```console +$ nemoclaw sandbox logs my-sandbox --tail --source sandbox +``` + +Denied actions include the destination host/port, the binary that attempted the connection, and the reason for denial. + +## Deleting Sandboxes + +```console +$ nemoclaw sandbox delete my-sandbox +$ nemoclaw sandbox delete sandbox-1 sandbox-2 sandbox-3 +``` + +Deleting a sandbox also stops any active port forwards. diff --git a/docs/sandboxes/custom-containers.md b/docs/sandboxes/custom-containers.md new file mode 100644 index 00000000..2a989967 --- /dev/null +++ b/docs/sandboxes/custom-containers.md @@ -0,0 +1,81 @@ + + +# Custom Containers (BYOC) + +You can run any Linux container image as a sandbox while keeping the NemoClaw supervisor in control of security enforcement. This is called Bring Your Own Container (BYOC). + +## How It Works + +When you specify `--image`, the server activates **supervisor bootstrap mode**. The `navigator-sandbox` supervisor binary is side-loaded from the default sandbox image via a Kubernetes init container, then mounted read-only into your custom container. This means you do not need to build the supervisor into your image. + +```{mermaid} +flowchart TB + subgraph pod["Pod"] + subgraph init["Init Container · copy-supervisor"] + init_desc["Image: default sandbox image\nCopies navigator-sandbox binary\ninto shared volume"] + end + + init -- "shared volume" --> agent + + subgraph agent["Agent Container"] + agent_desc["Image: your custom image\nRuns navigator-sandbox as entrypoint\nFull sandbox policy enforcement"] + end + end +``` + +## Building and Pushing Images + +Build a custom container image and import it into the cluster: + +```console +$ nemoclaw sandbox image push \ + --dockerfile ./Dockerfile \ + --tag my-app:latest \ + --context . +``` + +The image is built locally via Docker and imported directly into the cluster's containerd runtime. No external registry is needed. + +| Flag | Description | +|------|-------------| +| `--dockerfile` (required) | Path to the Dockerfile. | +| `--tag` | Image name and tag (default: auto-generated timestamp). | +| `--context` | Build context directory (default: Dockerfile parent). | +| `--build-arg KEY=VALUE` | Docker build argument (repeatable). | + +## Creating a Sandbox with a Custom Image + +```console +$ nemoclaw sandbox create --image my-app:latest --keep --name my-app +``` + +When `--image` is set, the CLI clears the default `run_as_user`/`run_as_group` policy, since custom images may not have the default `sandbox` user. + +### With Port Forwarding + +If your container runs a service: + +```console +$ nemoclaw sandbox create --image my-app:latest --forward 8080 --keep -- ./start-server.sh +``` + +The `--forward` flag starts a background port forward before the command runs, so the service is reachable at `localhost:8080` immediately. + +## Updating a Custom Image + +To iterate on your container: + +```console +$ nemoclaw sandbox delete my-app +$ nemoclaw sandbox image push --dockerfile ./Dockerfile --tag my-app:v2 +$ nemoclaw sandbox create --image my-app:v2 --keep --name my-app +``` + +## Limitations + +- **Distroless / `FROM scratch` images are not supported.** The supervisor needs glibc, `/proc`, and a shell. +- **Missing `iproute2` blocks proxy mode.** Network namespace isolation requires `iproute2` and the `CAP_NET_ADMIN`/`CAP_SYS_ADMIN` capabilities. +- The init container assumes the supervisor binary is at a fixed path in the default sandbox image. diff --git a/docs/sandboxes/file-sync.md b/docs/sandboxes/file-sync.md new file mode 100644 index 00000000..ad92774b --- /dev/null +++ b/docs/sandboxes/file-sync.md @@ -0,0 +1,41 @@ + + +# File Sync + +NemoClaw supports syncing files between your local machine and a running sandbox. File sync uses tar-over-SSH through the gateway tunnel — no direct network access to the sandbox pod is needed. + +## Sync at Create Time + +The `--sync` flag pushes local git-tracked files into the sandbox at `/sandbox` before the agent starts: + +```console +$ nemoclaw sandbox create --sync -- claude +``` + +This is useful when you want the agent to work with your current project files. + +## Manual Sync + +### Push Files to a Sandbox + +```console +$ nemoclaw sandbox sync my-sandbox --up ./src /sandbox/src +``` + +This copies local `./src` into `/sandbox/src` inside the sandbox. + +### Pull Files from a Sandbox + +```console +$ nemoclaw sandbox sync my-sandbox --down /sandbox/output ./local-output +``` + +This copies `/sandbox/output` from the sandbox to `./local-output` on your machine. + +### Default Destinations + +- `--up` defaults to `/sandbox` if no destination is specified. +- `--down` defaults to the current directory (`.`). diff --git a/docs/sandboxes/index.md b/docs/sandboxes/index.md new file mode 100644 index 00000000..942a3333 --- /dev/null +++ b/docs/sandboxes/index.md @@ -0,0 +1,61 @@ + + +# About Sandboxes + +A sandbox is a safe, private execution environment for an AI agent. Each sandbox runs inside a Kubernetes pod with multiple layers of protection that prevent unauthorized data access, credential exposure, and network exfiltration: filesystem restrictions (Landlock), system call filtering (seccomp), network namespace isolation, and a privacy-enforcing HTTP CONNECT proxy. + +## Concepts + +### Lifecycle + +A sandbox goes through these phases: + +| Phase | Description | +|-------|-------------| +| **Provisioning** | The pod is being created and the supervisor is starting up. | +| **Ready** | The sandbox is running and accessible via SSH. | +| **Error** | Something went wrong during startup or execution. | +| **Deleting** | The sandbox is being torn down. | + +### Supervisor and Child Process + +Each sandbox runs two processes: + +- The **supervisor** (`navigator-sandbox`) is a privileged process that sets up isolation, starts the proxy, runs the SSH server, and manages the child process. +- The **child process** is the agent (e.g., Claude, Codex) running with restricted privileges — reduced filesystem access, filtered system calls, and all network traffic routed through the proxy. + +### Policy + +Every sandbox is governed by a policy that defines what the agent can do, ensuring your data and credentials stay safe. Policies are written in YAML and control: + +- **Filesystem access** — which directories are readable and writable, protecting sensitive data. +- **Network access** — which hosts each program can connect to, preventing data exfiltration. +- **Inference routing** — which AI model backends are available, keeping inference traffic private. +- **Process privileges** — the user and group the agent runs as, limiting blast radius. + +See [Safety & Privacy](../security/index.md) for details. + +## Quick Reference + +| Task | Command | +|------|---------| +| Create sandbox (interactive) | `nemoclaw sandbox create` | +| Create sandbox with tool | `nemoclaw sandbox create -- claude` | +| Create with custom policy | `nemoclaw sandbox create --policy ./p.yaml --keep` | +| List sandboxes | `nemoclaw sandbox list` | +| Connect to sandbox | `nemoclaw sandbox connect ` | +| Stream live logs | `nemoclaw sandbox logs --tail` | +| Sync files to sandbox | `nemoclaw sandbox sync --up ./src /sandbox/src` | +| Forward a port | `nemoclaw sandbox forward start -d` | +| Delete sandbox | `nemoclaw sandbox delete ` | + +## In This Section + +- [Create and Manage](create-and-manage.md) — sandbox CRUD, connecting, and log viewing. +- [Providers](providers.md) — managing external credentials privately. +- [Custom Containers](custom-containers.md) — bring your own container images. +- [File Sync](file-sync.md) — pushing and pulling files to/from sandboxes. +- [Port Forwarding](port-forwarding.md) — forwarding local ports into sandboxes. diff --git a/docs/sandboxes/port-forwarding.md b/docs/sandboxes/port-forwarding.md new file mode 100644 index 00000000..f0ca2268 --- /dev/null +++ b/docs/sandboxes/port-forwarding.md @@ -0,0 +1,60 @@ + + +# Port Forwarding + +Port forwarding lets you access services running inside a sandbox from your local machine. It uses SSH tunneling through the gateway — sandbox pods are never directly accessible from outside the cluster. + +## Starting a Port Forward + +### Foreground (blocks until interrupted) + +```console +$ nemoclaw sandbox forward start 8080 my-sandbox +``` + +### Background (returns immediately) + +```console +$ nemoclaw sandbox forward start 8080 my-sandbox -d +``` + +The service is now reachable at `localhost:8080`. + +## Managing Port Forwards + +### List Active Forwards + +```console +$ nemoclaw sandbox forward list +``` + +Shows all active port forwards with sandbox name, port, PID, and status. + +### Stop a Forward + +```console +$ nemoclaw sandbox forward stop 8080 my-sandbox +``` + +## Port Forward at Create Time + +You can start a port forward when creating a sandbox: + +```console +$ nemoclaw sandbox create --image my-app:latest --forward 8080 --keep -- ./start-server.sh +``` + +The `--forward` flag implies `--keep` (the sandbox stays alive after the command exits) and starts the forward before the command runs. + +## How It Works + +Port forwarding uses OpenSSH's `-L` flag (`-L :127.0.0.1:`) through the same `ProxyCommand`-based tunnel used by `sandbox connect`. Connections to `127.0.0.1:` on your local machine are forwarded to `127.0.0.1:` inside the sandbox. + +Background forwards are tracked via PID files in `~/.config/nemoclaw/forwards/`. Deleting a sandbox automatically stops any active forwards for that sandbox. + +## Gator TUI + +The Gator TUI also supports port forwarding. When creating a sandbox in Gator, specify ports in the **Ports** field (comma-separated, e.g., `8080,3000`). Forwarded ports appear in the sandbox table's **NOTES** column. diff --git a/docs/sandboxes/providers.md b/docs/sandboxes/providers.md new file mode 100644 index 00000000..5f42a09b --- /dev/null +++ b/docs/sandboxes/providers.md @@ -0,0 +1,85 @@ + + +# Providers + +AI agents typically need credentials to access external services — an API key for the AI model provider, a token for GitHub or GitLab, and so on. NemoClaw manages these credentials as first-class entities called **providers**. + +## How Providers Work + +1. **You configure a provider once** — either by letting the CLI discover credentials from your local machine, or by providing them explicitly. +2. **Credentials are stored on the gateway** — separate from sandbox definitions. They never appear in Kubernetes pod specifications. +3. **Sandboxes receive credentials at runtime** — when a sandbox starts, the supervisor fetches credentials from the gateway and injects them as environment variables into every process it spawns. + +This means you configure credentials once, and every sandbox that needs them receives them automatically. + +## Supported Provider Types + +| Type | Discovered Environment Variables | Discovered Config Paths | +|------|----------------------------------|------------------------| +| `claude` | `ANTHROPIC_API_KEY`, `CLAUDE_API_KEY` | `~/.claude.json`, `~/.claude/credentials.json`, `~/.config/claude/config.json` | +| `codex` | `OPENAI_API_KEY` | `~/.config/codex/config.json`, `~/.codex/config.json` | +| `opencode` | `OPENCODE_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY` | `~/.config/opencode/config.json` | +| `github` | `GITHUB_TOKEN`, `GH_TOKEN` | `~/.config/gh/hosts.yml` | +| `gitlab` | `GITLAB_TOKEN`, `GLAB_TOKEN`, `CI_JOB_TOKEN` | `~/.config/glab-cli/config.yml` | +| `nvidia` | `NVIDIA_API_KEY` | — | +| `generic` | — | — | +| `outlook` | — | — | + +## Creating Providers + +### From Local Credentials (Auto-Discovery) + +The easiest way to create a provider — the CLI scans your machine for existing credentials: + +```console +$ nemoclaw provider create --name my-claude --type claude --from-existing +``` + +### With Explicit Credentials + +```console +$ nemoclaw provider create --name my-api --type generic \ + --credential API_KEY=sk-abc123 \ + --config base_url=https://api.example.com +``` + +A bare key (without `=VALUE`) reads the value from the environment variable of that name: + +```console +$ nemoclaw provider create --name my-api --type generic --credential API_KEY +``` + +### Auto-Creation During Sandbox Create + +When you run `nemoclaw sandbox create -- claude`, the CLI detects that a `claude` provider is needed, discovers local credentials, and creates the provider automatically. You are prompted interactively if credentials are missing. + +## Managing Providers + +```console +$ nemoclaw provider list +$ nemoclaw provider get my-claude +$ nemoclaw provider update my-claude --type claude --from-existing +$ nemoclaw provider delete my-claude +``` + +## Attaching Providers to Sandboxes + +Specify providers at sandbox creation time: + +```console +$ nemoclaw sandbox create --provider my-claude --provider my-github -- claude +``` + +Each attached provider's credentials are injected as environment variables into the sandbox. If multiple providers define the same environment variable, the first provider's value wins. + +## Privacy & Safety + +NemoClaw manages credentials with a privacy-first design: + +- **Credentials stay private** — stored separately from sandbox definitions, never in Kubernetes pod specs or container configurations. +- **Runtime-only injection** — credentials are fetched at runtime by the sandbox supervisor, minimizing exposure surface. +- **No credential leakage** — the CLI never displays credential values in its output. +- **Strict key validation** — only credential keys that are valid environment variable names (`^[A-Za-z_][A-Za-z0-9_]*$`) are injected; invalid keys are silently skipped. diff --git a/docs/security/index.md b/docs/security/index.md new file mode 100644 index 00000000..67364a8f --- /dev/null +++ b/docs/security/index.md @@ -0,0 +1,74 @@ + + +# About Safety and Privacy + +NemoClaw provides defense-in-depth safety and privacy protection for AI agents through multiple independent enforcement layers. Each sandbox is governed by a declarative policy that controls what the agent can access, preventing unauthorized data access, exfiltration, and credential exposure. + +## Safety and Privacy Model + +### How NemoClaw Protects You + +Every sandbox enforces four independent protection layers: + +| Layer | Mechanism | What It Protects | +|-------|-----------|-----------------| +| **Filesystem** | Landlock LSM | Prevents agents from reading sensitive files or writing outside designated directories. Enforced by the Linux kernel. | +| **System calls** | seccomp BPF | Blocks dangerous low-level operations that could bypass safety controls (e.g., raw network socket creation). | +| **Network** | Network namespace + proxy | Prevents data exfiltration — all traffic goes through the proxy, which inspects and authorizes every connection. | +| **Process** | Privilege separation | Prevents privilege escalation — the agent runs as an unprivileged user. | + +These layers are independent — a bypass of one layer does not compromise the others. + +### Data Privacy + +All outbound network traffic from the sandbox is forced through an HTTP CONNECT proxy, ensuring no data leaves without authorization. The proxy: + +1. **Identifies the program** making each connection by inspecting `/proc` — you always know which process is sending data. +2. **Verifies binary integrity** using trust-on-first-use SHA256 hashing — if a binary is tampered with, subsequent requests are denied. +3. **Enforces least-privilege network access** using an embedded OPA engine with per-binary, per-host granularity — only the programs you authorize can reach each endpoint. +4. **Protects private infrastructure** by blocking DNS results pointing to internal IP ranges (RFC 1918, link-local, cloud metadata endpoints), preventing agents from accessing internal services. +5. **Inspects data in transit** when L7 inspection is configured — terminates TLS and examines individual HTTP requests for fine-grained data access control. + +### Credential Privacy + +Credentials are managed with a privacy-first design: + +- API keys and tokens are stored separately from sandbox definitions on the gateway. +- Credentials never appear in Kubernetes pod specs or container configuration. +- Credentials are fetched only at runtime by the sandbox supervisor and injected as environment variables. +- The CLI never displays credential values in its output. + +### Communication Security + +All communication with the NemoClaw gateway is secured by mutual TLS (mTLS). The PKI is bootstrapped automatically during cluster deployment. Every client (CLI, SDK, sandbox pods) must present a valid certificate signed by the cluster CA — there is no unauthenticated path. + +## Policy Overview + +Sandbox behavior is governed by policies written in YAML. Policies give you explicit control over: + +- **Filesystem access** — which directories are readable and writable, protecting sensitive data. +- **Network access** — which remote hosts each program can connect to, preventing data exfiltration. +- **Inference routing** — which AI model backends the sandbox can use, keeping prompts and responses private. +- **Process privileges** — the user and group the agent runs as, limiting blast radius. + +See [Policies](policies.md) for the full guide on writing and managing policies. + +### Static vs. Dynamic Fields + +Policy fields are divided into two categories: + +| Category | Fields | Updatable at Runtime? | +|----------|--------|----------------------| +| **Static** | `filesystem_policy`, `landlock`, `process` | No — applied once at startup, immutable. | +| **Dynamic** | `network_policies`, `inference` | Yes — hot-reloaded within ~30 seconds. | + +Static fields are enforced at the kernel level (Landlock, seccomp) and cannot be changed after the sandbox starts. Dynamic fields are evaluated at runtime by the OPA engine and can be updated using `nemoclaw sandbox policy set`. + +## In This Section + +- [Policies](policies.md) — writing, managing, and iterating on sandbox policies. +- [Network Access Control](network-access.md) — detailed network policy configuration. +- [Policy Schema Reference](../reference/policy-schema.md) — complete YAML schema. diff --git a/docs/security/network-access.md b/docs/security/network-access.md new file mode 100644 index 00000000..abfb374a --- /dev/null +++ b/docs/security/network-access.md @@ -0,0 +1,148 @@ + + +# Network Access Control + +The `network_policies` section of a sandbox policy controls which remote hosts each program in the sandbox can connect to, preventing unauthorized data exfiltration. The proxy evaluates every outbound connection against these rules — no data leaves the sandbox without explicit authorization. + +## Basic Structure + +Network policies are a map of named entries. Each entry specifies endpoints (host + port) and the binaries allowed to connect to them: + +```yaml +network_policies: + github: + endpoints: + - host: github.com + port: 443 + - host: api.github.com + port: 443 + binaries: + - path_patterns: ["**/git"] + - path_patterns: ["**/ssh"] + + anthropic: + endpoints: + - host: api.anthropic.com + port: 443 + binaries: + - path_patterns: ["**/claude"] + - path_patterns: ["**/node"] +``` + +## Endpoints + +Each endpoint specifies a host and port: + +```yaml +endpoints: + - host: api.example.com + port: 443 +``` + +The `host` field matches the hostname in the CONNECT request. The `port` field matches the destination port. + +## Binary Matching + +The `binaries` field specifies which programs are allowed to connect to the endpoints. Each binary entry uses glob patterns matched against the full path of the executable: + +```yaml +binaries: + - path_patterns: ["**/git"] # matches /usr/bin/git, /usr/local/bin/git, etc. + - path_patterns: ["**/node"] # matches any 'node' binary + - path_patterns: ["/usr/bin/curl"] # matches only this specific path +``` + +### Binary Integrity + +The proxy uses a trust-on-first-use (TOFU) model for binary verification. The first time a binary makes a network request, its SHA256 hash is recorded. If the binary changes later (indicating possible tampering), subsequent requests are denied. + +## L7 Inspection + +For endpoints that need deeper inspection, you can configure L7 (HTTP-level) rules. L7 inspection terminates TLS and inspects individual HTTP requests: + +```yaml +network_policies: + api-service: + endpoints: + - host: api.example.com + port: 443 + l7: + tls_mode: terminate + enforcement_mode: enforce + rules: + - method: GET + path_pattern: "/v1/data/*" + - method: POST + path_pattern: "/v1/submit" + binaries: + - path_patterns: ["**/curl"] +``` + +### L7 Fields + +| Field | Description | +|-------|-------------| +| `tls_mode` | `terminate` — proxy terminates TLS and inspects plaintext HTTP. | +| `enforcement_mode` | `enforce` — block requests that don't match any rule. `audit` — log violations but allow traffic. | +| `rules` | List of allowed HTTP method + path patterns. | + +### Access Presets + +Instead of listing individual rules, you can use an `access` preset: + +```yaml +network_policies: + api-service: + endpoints: + - host: api.example.com + port: 443 + l7: + tls_mode: terminate + access: read-only + binaries: + - path_patterns: ["**/curl"] +``` + +| Preset | Allowed Methods | +|--------|----------------| +| `read-only` | `GET`, `HEAD`, `OPTIONS` | +| `read-write` | `GET`, `HEAD`, `OPTIONS`, `POST`, `PUT`, `PATCH`, `DELETE` | +| `full` | All HTTP methods | + +Presets are expanded into explicit rules at policy load time. + +## SSRF Protection + +Even when a hostname is allowed by policy, the proxy resolves DNS before connecting and blocks any result that points to a private network address. This prevents SSRF attacks where an allowed hostname could be redirected to internal infrastructure. + +Blocked IP ranges include: + +- Loopback (`127.0.0.0/8`, `::1`) +- RFC 1918 private ranges (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`) +- Link-local (`169.254.0.0/16`, `fe80::/10`) +- Cloud metadata endpoints (e.g., `169.254.169.254`) + +## Network Modes + +The sandbox supports three network modes, determined at creation time: + +| Mode | Description | +|------|-------------| +| **Proxy** | All traffic goes through the policy-enforcing proxy. Activated when `network_policies` is non-empty. | +| **Block** | No network access at all. System calls for network sockets are blocked by seccomp. | +| **Allow** | Unrestricted network access. No proxy, no seccomp filtering. | + +The network mode cannot change after sandbox creation. Adding `network_policies` to a sandbox created without them (or removing all policies from a sandbox that has them) is rejected. + +## Tri-State Routing Decision + +When a connection request arrives at the proxy, the OPA engine returns one of three actions: + +| Action | Condition | Behavior | +|--------|-----------|----------| +| **Allow** | Endpoint + binary matched a `network_policies` entry. | Connection proceeds directly. | +| **Inspect for Inference** | No policy match, but `inference.allowed_routes` is non-empty. | TLS-terminate and check for inference API patterns. See [Inference Routing](../inference/index.md). | +| **Deny** | No match and no inference routing configured. | Connection is rejected. | diff --git a/docs/security/policies.md b/docs/security/policies.md new file mode 100644 index 00000000..8185e03d --- /dev/null +++ b/docs/security/policies.md @@ -0,0 +1,190 @@ + + +# Policies + +Sandbox policies are YAML documents that define what an agent can do. Every sandbox has a policy — either the built-in default or a custom one provided at creation time. + +## Using Policies + +### Create a Sandbox with a Custom Policy + +```console +$ nemoclaw sandbox create --policy ./my-policy.yaml --keep -- claude +``` + +### Set a Default Policy via Environment Variable + +```console +$ export NEMOCLAW_SANDBOX_POLICY=./my-policy.yaml +$ nemoclaw sandbox create -- claude +``` + +## Policy Structure + +A policy has four top-level sections: + +```yaml +filesystem_policy: + read_only: + - /usr + - /etc + read_write: + - /sandbox + - /tmp + +landlock: + compatibility: best_effort + +process: + run_as_user: sandbox + run_as_group: sandbox + +network_policies: + github: + endpoints: + - host: github.com + port: 443 + - host: api.github.com + port: 443 + binaries: + - path_patterns: ["**/git"] + - path_patterns: ["**/ssh"] + +inference: + allowed_routes: + - local +``` + +### `filesystem_policy` (Static) + +Controls which directories the agent can access. Enforced by the Linux Landlock LSM. + +| Field | Description | +|-------|-------------| +| `read_only` | List of paths the agent can read but not write. | +| `read_write` | List of paths the agent can read and write. Directories are created and chowned automatically. | + +### `landlock` (Static) + +| Field | Description | +|-------|-------------| +| `compatibility` | `best_effort` (default) — use the best available Landlock ABI. `hard_requirement` — fail if the required ABI is not available. | + +### `process` (Static) + +| Field | Description | +|-------|-------------| +| `run_as_user` | Username or UID the agent runs as. | +| `run_as_group` | Group name or GID the agent runs as. | + +### `network_policies` (Dynamic) + +A map of named network policy entries. Each entry defines which endpoints a set of binaries can reach. See [Network Access Control](network-access.md) for the full specification. + +### `inference` (Dynamic) + +| Field | Description | +|-------|-------------| +| `allowed_routes` | List of routing hint names that this sandbox can use for inference. Routes are created separately via `nemoclaw inference create`. | + +## Live Policy Updates + +Dynamic fields (`network_policies` and `inference`) can be updated on a running sandbox without restarting it. + +### The Policy Iteration Loop + +``` +Create sandbox with initial policy + │ + ▼ + Monitor logs ◄──────────────────┐ + │ │ + ▼ │ + Observe denied actions │ + │ │ + ▼ │ + Pull current policy │ + │ │ + ▼ │ + Modify policy YAML │ + │ │ + ▼ │ + Push updated policy │ + │ │ + ▼ │ + Verify reload succeeded ─────────┘ +``` + +### Step 1: Monitor logs for denied actions + +```console +$ nemoclaw sandbox logs my-sandbox --tail --source sandbox +``` + +Look for `action: deny` log lines — these show the destination host/port, the binary that attempted the connection, and the denial reason. + +### Step 2: Pull the current policy + +```console +$ nemoclaw sandbox policy get my-sandbox --full > current-policy.yaml +``` + +The `--full` flag outputs valid YAML that can be directly re-submitted. + +### Step 3: Modify and push the updated policy + +Edit `current-policy.yaml`, then: + +```console +$ nemoclaw sandbox policy set my-sandbox --policy current-policy.yaml --wait +``` + +The `--wait` flag blocks until the sandbox confirms the policy is loaded. Exit codes: + +| Code | Meaning | +|------|---------| +| 0 | Policy loaded successfully. | +| 1 | Policy load failed. | +| 124 | Timeout (default: 60 seconds). | + +### Step 4: Verify + +```console +$ nemoclaw sandbox policy list my-sandbox +``` + +Check that the latest revision shows status `loaded`. + +## Policy Revision History + +Each policy update creates a new revision. View the history: + +```console +$ nemoclaw sandbox policy list my-sandbox --limit 50 +``` + +Fetch a specific historical revision: + +```console +$ nemoclaw sandbox policy get my-sandbox --rev 3 --full +``` + +### Revision Statuses + +| Status | Meaning | +|--------|---------| +| `pending` | Accepted by the server; not yet loaded by the sandbox. | +| `loaded` | Successfully applied by the sandbox. | +| `failed` | Sandbox attempted to load but validation failed; previous policy remains active. | +| `superseded` | A newer revision was submitted before the sandbox loaded this one. | + +## Last-Known-Good Behavior + +If a new policy version fails validation, the sandbox keeps the previous (last-known-good) policy active. This provides safe rollback semantics — a bad policy push does not break a running sandbox. + +## Idempotent Updates + +Submitting the same policy content again does not create a new revision. The CLI detects this and prints "Policy unchanged." diff --git a/docs/troubleshooting/index.md b/docs/troubleshooting/index.md index 093695e1..ccb61fd6 100644 --- a/docs/troubleshooting/index.md +++ b/docs/troubleshooting/index.md @@ -3,4 +3,121 @@ SPDX-License-Identifier: Apache-2.0 --> -# Troubleshooting +# About Troubleshooting + +Common issues and how to resolve them. + +## Cluster Issues + +### Cluster Deploy Fails + +**Symptom:** `nemoclaw cluster admin deploy` exits with an error. + +**Check:** +1. Is Docker running? The cluster requires Docker to be active. +2. Is the port already in use? Try a different port: `--port 8081`. +3. Does a stale container exist? Destroy and redeploy: `nemoclaw cluster admin destroy && nemoclaw cluster admin deploy`. + +### Cluster Not Reachable + +**Symptom:** `nemoclaw cluster status` fails to connect. + +**Check:** +1. Is the cluster container running? `docker ps | grep nemoclaw`. +2. Was the cluster stopped? Redeploy: `nemoclaw cluster admin deploy`. +3. For remote clusters, is the SSH connection working? + +### Health Check Fails During Deploy + +**Symptom:** Deploy hangs or times out waiting for health checks. + +**Check:** +1. View container logs: `docker logs nemoclaw-cluster`. +2. Check if k3s started: the bootstrap process waits up to 180 attempts (6 minutes) for cluster readiness. +3. Look for resource constraints — k3s needs sufficient memory and disk. + +## Sandbox Issues + +### Sandbox Stuck in Provisioning + +**Symptom:** Sandbox shows `Provisioning` status and does not become `Ready`. + +**Check:** +1. View sandbox logs: `nemoclaw sandbox logs --source gateway`. +2. Check if the container image can be pulled. +3. For custom images, verify the image was pushed: `nemoclaw sandbox image push`. + +### Cannot Connect to Sandbox + +**Symptom:** `nemoclaw sandbox connect ` fails. + +**Check:** +1. Is the sandbox in `Ready` state? `nemoclaw sandbox get `. +2. Is SSH accessible? The tunnel goes through the gateway — verify cluster connectivity first. + +### Network Requests Denied + +**Symptom:** The agent cannot reach a remote host. + +**Check:** +1. Stream sandbox logs: `nemoclaw sandbox logs --tail --source sandbox`. +2. Look for `deny` actions — they include the destination, binary, and reason. +3. Update the policy to allow the blocked endpoint. See [Policy Iteration Loop](../security/policies.md#the-policy-iteration-loop). + +### Policy Update Fails + +**Symptom:** `nemoclaw sandbox policy set` returns an error or the status shows `failed`. + +**Check:** +1. Are you changing a static field? `filesystem_policy`, `landlock`, and `process` cannot change after creation. +2. Are you adding/removing `network_policies` to change the network mode? This is not allowed — the mode is fixed at creation. +3. Check the error message in `nemoclaw sandbox policy list `. + +## Provider Issues + +### Provider Discovery Finds No Credentials + +**Symptom:** `--from-existing` creates a provider with no credentials. + +**Check:** +1. Are the expected environment variables set? (e.g., `ANTHROPIC_API_KEY` for Claude). +2. Do the expected config files exist? (e.g., `~/.claude.json`). +3. Try explicit credentials: `--credential ANTHROPIC_API_KEY=sk-...`. + +### Sandbox Missing Credentials + +**Symptom:** Environment variables for a provider are not set inside the sandbox. + +**Check:** +1. Was the provider attached? `nemoclaw sandbox get ` — check the providers list. +2. Does the provider have credentials? `nemoclaw provider get `. +3. Are the credential keys valid env var names? Keys with dots, dashes, or spaces are silently skipped. + +## Custom Container Issues + +### Custom Image Fails to Start + +**Symptom:** Sandbox with `--image` goes to `Error` state. + +**Check:** +1. Is the image pushed to the cluster? `nemoclaw sandbox image push --dockerfile ./Dockerfile --tag my-image`. +2. Does the image have glibc and `/proc`? Distroless / `FROM scratch` images are not supported. +3. For proxy mode, does the image have `iproute2`? Network namespace setup requires it. + +## Port Forwarding Issues + +### Port Forward Not Working + +**Symptom:** `localhost:` does not connect to the sandbox service. + +**Check:** +1. Is the forward running? `nemoclaw sandbox forward list`. +2. Is the service listening on that port inside the sandbox? +3. Is the sandbox still in `Ready` state? +4. Try stopping and restarting: `nemoclaw sandbox forward stop && nemoclaw sandbox forward start -d`. + +## Getting More Information + +- Increase CLI verbosity: `nemoclaw -vvv ` for trace-level output. +- View gateway-side logs: `nemoclaw sandbox logs --source gateway`. +- View sandbox-side logs: `nemoclaw sandbox logs --source sandbox --level debug`. From 85d69c834d255fbfee69e75d12eb40384d096091 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 5 Mar 2026 08:50:13 -0800 Subject: [PATCH 02/39] improvements --- docs/get-started/first-sandbox.md | 12 +++- docs/get-started/index.md | 108 +++++++++++++++++++++-------- docs/get-started/installation.md | 8 +++ docs/index.md | 109 ++++++++++++++++++++++++++++-- 4 files changed, 201 insertions(+), 36 deletions(-) diff --git a/docs/get-started/first-sandbox.md b/docs/get-started/first-sandbox.md index 2074fe28..1336cb81 100644 --- a/docs/get-started/first-sandbox.md +++ b/docs/get-started/first-sandbox.md @@ -9,7 +9,7 @@ This walkthrough takes you from a fresh install to an interactive sandbox sessio ## Step 1: Bootstrap a Cluster -If you don't have a cluster running yet: +NemoClaw runs sandboxes on a lightweight Kubernetes cluster. If you don't have a cluster running yet, deploy one with a single command. ```console $ nemoclaw cluster admin deploy @@ -25,6 +25,8 @@ $ nemoclaw cluster admin deploy --remote user@host --ssh-key ~/.ssh/id_rsa ### Verify the Cluster +Check that the cluster is running and healthy before you continue. + ```console $ nemoclaw cluster status ``` @@ -59,6 +61,8 @@ This creates a sandbox with defaults, auto-discovers and uploads your Claude cre ### With More Options +You can name the sandbox, attach multiple providers, and sync your local project files in a single command. + ```console $ nemoclaw sandbox create \ --name my-sandbox \ @@ -90,7 +94,7 @@ The sandbox enforces its safety and privacy policy: ## Step 5: Connect from Another Terminal -If you exited the sandbox or want a second session: +You can reconnect to a running sandbox at any time. This is useful if you closed your terminal or need a second session. ```console $ nemoclaw sandbox connect my-sandbox @@ -106,12 +110,16 @@ Then connect via VS Code's Remote-SSH extension to the host `my-sandbox`. ## Step 6: Clean Up +Delete the sandbox when you are finished to free cluster resources. + ```console $ nemoclaw sandbox delete my-sandbox ``` ## Next Steps +Now that you have a working sandbox, explore these areas to go further. + - [Sandboxes](../sandboxes/index.md) — full sandbox lifecycle management. - [Providers](../sandboxes/providers.md) — managing credentials. - [Safety & Privacy](../security/index.md) — understanding and customizing sandbox policies. diff --git a/docs/get-started/index.md b/docs/get-started/index.md index d881162c..abe2f800 100644 --- a/docs/get-started/index.md +++ b/docs/get-started/index.md @@ -1,50 +1,100 @@ +--- +title: + page: "About Getting Started with NemoClaw" + nav: "About Getting Started" + card: "About Getting Started" +description: "Install the CLI, bootstrap a cluster, and launch your first sandbox in minutes." +topics: +- Get Started +tags: +- Installation +- Quickstart +- Sandbox +- CLI +content: + type: get_started + difficulty: technical_beginner + audience: + - engineer + - ai_engineer + - devops +--- + -# About Getting Started +# About Getting Started with NemoClaw + +NemoClaw is designed for minimal setup with safety and privacy built in from the start. Docker is the only prerequisite. Three commands take you from zero to a running, policy-enforced sandbox. -NemoClaw is designed for minimal setup with safety and privacy built in from the start. Docker is the only prerequisite. +::::{grid} 1 1 2 2 +:gutter: 3 -## Quickstart +:::{grid-item-card} Installation +:link: installation +:link-type: doc -**Step 1: Install the CLI.** +Prerequisites, install methods, shell completions, and verification steps for the NemoClaw CLI. ++++ +{bdg-secondary}`Get Started` +::: -```console -$ pip install nemoclaw -``` +:::{grid-item-card} Your First Sandbox +:link: first-sandbox +:link-type: doc -See [Installation](installation.md) for detailed prerequisites and alternative install methods. +Step-by-step walkthrough from cluster bootstrap to an interactive sandbox session with policy enforcement. ++++ +{bdg-secondary}`Tutorial` +::: -**Step 2: Create a sandbox.** +:::: -```console -$ nemoclaw sandbox create -- claude -``` +--- -If no cluster exists, the CLI automatically bootstraps one. It provisions a local Kubernetes cluster inside a Docker container, discovers your AI provider credentials from local configuration files, uploads them to the gateway, and launches a sandbox — all from a single command. +## Next Steps -**Step 3: Connect to a running sandbox.** +After you have a sandbox running, explore the following areas. -```console -$ nemoclaw sandbox connect -``` +::::{grid} 1 1 2 2 +:gutter: 3 -This opens an interactive SSH session into the sandbox, with all provider credentials available as environment variables. +:::{grid-item-card} Sandboxes +:link: ../sandboxes/index +:link-type: doc -## What Happens Under the Hood +Create, connect to, and manage sandboxes. Configure providers, sync files, forward ports, and bring your own containers. ++++ +{bdg-secondary}`How To` +::: -When you run `nemoclaw sandbox create -- claude`, the CLI: +:::{grid-item-card} Safety and Privacy +:link: ../security/index +:link-type: doc -1. Checks for a running cluster. If none exists, it bootstraps one automatically (a k3s cluster inside a Docker container). -2. Scans your local machine for Claude credentials (`ANTHROPIC_API_KEY`, `~/.claude.json`, etc.) and uploads them to the gateway as a provider. -3. Creates a sandbox pod with the default policy and attaches the discovered provider. -4. Waits for the sandbox to reach `Ready` state. -5. Opens an interactive SSH session into the sandbox. +Understand how NemoClaw keeps your data safe and private — and write policies that control filesystem, network, and inference access. ++++ +{bdg-secondary}`Concept` +::: -## Next Steps +:::{grid-item-card} Inference Routing +:link: ../inference/index +:link-type: doc + +Route AI API calls to local or self-hosted backends without modifying agent code. ++++ +{bdg-secondary}`How To` +::: + +:::{grid-item-card} Reference +:link: ../reference/index +:link-type: doc + +CLI command reference, policy schema, environment variables, and system architecture diagrams. ++++ +{bdg-secondary}`Reference` +::: -- [Installation](installation.md) — detailed prerequisites and install methods. -- [Your First Sandbox](first-sandbox.md) — a step-by-step walkthrough. -- [Sandboxes](../sandboxes/index.md) — full sandbox management guide. +:::: diff --git a/docs/get-started/installation.md b/docs/get-started/installation.md index 255f9925..f44f1bd4 100644 --- a/docs/get-started/installation.md +++ b/docs/get-started/installation.md @@ -5,13 +5,19 @@ # Installation +Install the NemoClaw CLI to create and manage sandboxes from your terminal. + ## Prerequisites +Confirm that the following dependencies are available on your machine before you install the CLI. + - **Docker** — must be installed and running. This is the only runtime dependency. - **Python 3.12+** — required for `pip install`. ## Install the CLI +Install the latest release from PyPI. + ```console $ pip install nemoclaw ``` @@ -20,6 +26,8 @@ This installs the `nemoclaw` command (also available as `ncl`). ### Verify the Installation +Run the help command to confirm that the CLI is on your path and working. + ```console $ nemoclaw --help ``` diff --git a/docs/index.md b/docs/index.md index 1acd4a53..e700dcd7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,3 +1,22 @@ +--- +title: + page: "NVIDIA NemoClaw Developer Guide" + nav: "NVIDIA NemoClaw" + card: "NVIDIA NemoClaw" +description: "NemoClaw is the safe, private runtime for autonomous AI agents. Run agents in sandboxed environments that protect your data, credentials, and infrastructure." +topics: +- Generative AI +- Cybersecurity +tags: +- AI Agents +- Sandboxing +- Security +- Privacy +- Inference Routing +content: + type: index +--- + - -# Your First Sandbox - -This walkthrough takes you from a fresh install to an interactive sandbox session. By the end, you will have a running AI agent inside an isolated environment with full policy enforcement. - -## Step 1: Bootstrap a Cluster - -NemoClaw runs sandboxes on a lightweight Kubernetes cluster. If you don't have a cluster running yet, deploy one with a single command. - -```console -$ nemoclaw cluster admin deploy -``` - -This provisions a local k3s cluster inside a Docker container. The cluster is automatically set as the active cluster. - -For remote deployment (running the cluster on a different machine): - -```console -$ nemoclaw cluster admin deploy --remote user@host --ssh-key ~/.ssh/id_rsa -``` - -### Verify the Cluster - -Check that the cluster is running and healthy before you continue. - -```console -$ nemoclaw cluster status -``` - -You should see the cluster version and a healthy status. - -## Step 2: Set Up Providers - -Providers supply credentials to sandboxes (API keys, tokens, etc.). When you use `nemoclaw sandbox create -- claude`, the CLI auto-discovers local Claude credentials and creates a provider for you. You can also set up providers manually: - -```console -$ nemoclaw provider create --name my-claude --type claude --from-existing -``` - -The `--from-existing` flag scans your local machine for credentials (environment variables like `ANTHROPIC_API_KEY`, config files like `~/.claude.json`). - -To see what providers you have: - -```console -$ nemoclaw provider list -``` - -## Step 3: Create a Sandbox - -The simplest way to get a sandbox running: - -```console -$ nemoclaw sandbox create -- claude -``` - -This creates a sandbox with defaults, auto-discovers and uploads your Claude credentials, and drops you into an interactive shell. - -### With More Options - -You can name the sandbox, attach multiple providers, and sync your local project files in a single command. - -```console -$ nemoclaw sandbox create \ - --name my-sandbox \ - --provider my-claude \ - --provider my-github \ - --sync \ - -- claude -``` - -- `--name` — give the sandbox a specific name. -- `--provider` — attach providers explicitly (repeatable). -- `--sync` — push local git-tracked files to `/sandbox` in the container. - -## Step 4: Work Inside the Sandbox - -Once connected, you are inside an isolated environment. All provider credentials are available as environment variables: - -```console -sandbox@my-sandbox:~$ echo $ANTHROPIC_API_KEY -sk-ant-... - -sandbox@my-sandbox:~$ claude -``` - -The sandbox enforces its safety and privacy policy: -- Your data is protected — filesystem access is restricted to allowed directories. -- No data leaves unmonitored — network connections go through the privacy-enforcing proxy. -- Only explicitly permitted hosts and programs can reach the internet. - -## Step 5: Connect from Another Terminal - -You can reconnect to a running sandbox at any time. This is useful if you closed your terminal or need a second session. - -```console -$ nemoclaw sandbox connect my-sandbox -``` - -For VS Code Remote-SSH access: - -```console -$ nemoclaw sandbox ssh-config my-sandbox >> ~/.ssh/config -``` - -Then connect via VS Code's Remote-SSH extension to the host `my-sandbox`. - -## Step 6: Clean Up - -Delete the sandbox when you are finished to free cluster resources. - -```console -$ nemoclaw sandbox delete my-sandbox -``` - -## Next Steps - -Now that you have a working sandbox, explore these areas to go further. - -- [Sandboxes](../sandboxes/index.md) — full sandbox lifecycle management. -- [Providers](../sandboxes/providers.md) — managing credentials. -- [Safety & Privacy](../security/index.md) — understanding and customizing sandbox policies. diff --git a/docs/get-started/index.md b/docs/get-started/index.md index abe2f800..da4f5ef5 100644 --- a/docs/get-started/index.md +++ b/docs/get-started/index.md @@ -41,8 +41,8 @@ Prerequisites, install methods, shell completions, and verification steps for th {bdg-secondary}`Get Started` ::: -:::{grid-item-card} Your First Sandbox -:link: first-sandbox +:::{grid-item-card} Tutorials +:link: tutorials/index :link-type: doc Step-by-step walkthrough from cluster bootstrap to an interactive sandbox session with policy enforcement. diff --git a/docs/get-started/tutorials/index.md b/docs/get-started/tutorials/index.md new file mode 100644 index 00000000..00f638ee --- /dev/null +++ b/docs/get-started/tutorials/index.md @@ -0,0 +1,35 @@ +# Tutorials + +This section contains tutorials that help you get started with NemoClaw. + +::::{grid} 1 1 2 2 +:gutter: 3 + +:::{grid-item-card} Run OpenClaw Safely +:link: run-openclaw +:link-type: doc + +Launch OpenClaw inside a NemoClaw sandbox with inference routing and policy enforcement. ++++ +{bdg-secondary}`Tutorial` +::: + +:::{grid-item-card} Run Claude Safely +:link: run-claude +:link-type: doc + +Run Anthropic Claude as a coding agent with credential management, inference routing, and policy enforcement. ++++ +{bdg-secondary}`Tutorial` +::: + +:::: + +```{toctree} +:hidden: +:maxdepth: 2 + +Run OpenClaw Safely +Run Claude Safely +Run Any Agent Safely +``` diff --git a/docs/get-started/tutorials/run-agents.md b/docs/get-started/tutorials/run-agents.md new file mode 100644 index 00000000..ca6506ee --- /dev/null +++ b/docs/get-started/tutorials/run-agents.md @@ -0,0 +1,200 @@ + + +# Run AI Agents Safely inside NemoClaw + +This tutorial shows how to run OpenClaw inside NemoClaw with zero code changes. You will learn how the platform delivers safe, autonomous, long-running agent execution through isolation, privacy routing, and declarative policy. + +## Prerequisites + +Before you begin, ensure the following are in place. + +- NemoClaw CLI installed. Refer to [Installation](../installation.md). +- A running cluster. Run `nemoclaw cluster admin deploy` to create one. + +## Why NemoClaw + +Coding agents like OpenClaw run for hours, maintain state across sessions, spawn subagents, and build their own tools on the fly. Giving an agent persistent shell access, common developer tools, and the ability to spawn subagents against APIs that touch sensitive data is productive — but without an infrastructure layer, accumulated sensitive context leaks to a frontier model, unreviewed skills get filesystem and network access, and subagents inherit permissions they were never meant to have. + +NemoClaw solves this by running any agent inside an isolated sandbox with zero code changes. Agents are isolated by default and controlled by policy. + +## Run OpenClaw in One Command + +You can run OpenClaw inside a NemoClaw sandbox with a single command. The sandbox image includes OpenClaw, the onboarding flow, and a helper script that configures the gateway and prints the access URL. + +```console +$ nemoclaw sandbox create --forward 18789 -- openclaw-start +``` + +- `--forward 18789` — forwards sandbox port 18789 to your machine so the OpenClaw UI is available locally. +- `openclaw-start` — a script pre-installed in the sandbox that runs `openclaw onboard`, starts the gateway in the background, and prints the UI URL and token. + +The CLI returns when the script finishes; the port forward keeps running in the background. Once it completes: + +- **Control UI:** `http://127.0.0.1:18789/` (use the token printed during onboarding). +- **Health:** `openclaw health` from your host or inside the sandbox. + +No changes are required in OpenClaw itself; it runs as-is inside the sandbox. + +### What `openclaw-start` Does + +Under the hood, the helper script does: + +```bash +openclaw onboard +nohup openclaw gateway run > /tmp/gateway.log 2>&1 & +# Prints UI URL and token from ~/.openclaw/openclaw.json +``` + +### Step-by-Step Alternative + +If you prefer to drive steps yourself (for example, for automation or debugging): + +```console +$ nemoclaw sandbox create --keep --forward 18789 +``` + +Then inside the sandbox: + +```bash +openclaw onboard +nohup openclaw gateway run > /tmp/gateway.log 2>&1 & +exit +``` + +The sandbox stays up with the `--keep` flag, and the `--forward` flag gives you local access to the gateway. + +## Long-Lived Sandboxes and File Sync + +For development workflows, you can keep a sandbox running, sync in your repo, and run commands against it. + +```console +$ nemoclaw sandbox create --name --keep --sync -- python main.py +``` + +- `--name `: Name of the sandbox for reuse with `nemoclaw sandbox connect `. +- `--sync`: Syncs git-tracked files into `/sandbox` before running the command. +- `--keep`: Leaves the sandbox running after the command (for example, for interactive use). + +You can reconnect to the same environment later: + +```console +$ nemoclaw sandbox connect my-agent +``` + +## How NemoClaw Delivers Safety + +NemoClaw organizes controls around Access, Privacy, and Skills. Four primitives implement them. + +### Gateway — Control Plane and Auth + +The *Gateway* is the control-plane API that coordinates sandbox lifecycle and state, acts as the auth boundary, and brokers requests. Everything flows through it: sandbox create/delete, policy updates, inference route management, and policy and route delivery to sandboxes. + +When you run `nemoclaw sandbox create -- openclaw-start`, the CLI talks to the Gateway to create the sandbox, attach policy, and (optionally) set up port forwarding. Sandboxes fetch their policy and inference bundle from the Gateway and report policy load status back. + +### Sandbox — Isolation and Policy at the Edge + +The *Sandbox* is the execution environment for long-running agents. It provides skill development and verification, programmable system and network isolation, and isolated execution so agents can break things without touching the host. + +The sandbox is a supervised child process with: + +- **Filesystem isolation** — Landlock with a policy-defined allowlist: read-only versus read-write paths (for example, `/sandbox` and `/tmp` writable; `/usr` and `/etc` read-only). +- **Process identity** — runs as an unprivileged user/group (for example, `sandbox:sandbox`). +- **Network** — in Proxy mode, the sandbox gets an isolated network namespace. All outbound TCP goes through an in-sandbox HTTP CONNECT proxy. Every connection is evaluated by the Policy Engine. +- **Policy updates** — the sandbox polls the Gateway for policy updates and applies them live at sandbox scope (network and inference rules only; filesystem/process are fixed at create time). You can approve new endpoints or routes without restarting the agent. + +### Privacy Router and Inference Routing + +The *Privacy Router* is a privacy-aware LLM routing layer that keeps sensitive context on sandbox (or on-prem) compute. Only non-sensitive work goes to frontier cloud models. + +NemoClaw implements this as inference routing: + +1. The sandbox intercepts outbound HTTPS from the agent (for example, OpenAI SDK, Anthropic SDK). +2. The proxy TLS-terminates, parses the request, and detects inference API patterns (for example, `POST /v1/chat/completions`, `POST /v1/messages`). +3. A route configuration maps a routing hint (for example, `local`) to a backend: base URL, model ID, protocol, and API key. +4. The proxy forwards the request to the allowed backend and returns the response to the agent. The agent's code does not change; it still targets `api.openai.com` or similar — NemoClaw rewrites destination and model as per policy. + +You can point `local` to an on-prem model for private work and use other routes for cloud reasoning/planning. The router decides based on your cost and privacy policy, not the agent's. + +#### Create an Inference Route + +Use the CLI to create a route: + +```console +$ nemoclaw inference create \ + --routing-hint local \ + --base-url https://integrate.api.nvidia.com/ \ + --model-id nvidia/nemotron-3-nano-30b-a3b \ + --api-key $NVIDIA_API_KEY +``` + +Then allow the route in sandbox policy: + +```yaml +inference: + allowed_routes: + - local +``` + +Only routes listed in `allowed_routes` are available to that sandbox. Refer to [Inference Routing](../../inference/index.md) for the full configuration reference. + +### Policy Engine — Granular, Explainable Enforcement + +The *Policy Engine* handles policy definition and enforcement for filesystem, network, and process. Enforcement is out-of-process: the proxy and OPA/Rego run in the sandbox supervisor, not inside the agent process. The thing being guarded cannot bypass the guardrails; the constraints are structural, not behavioral. + +Policy is expressed in a YAML file with five sections. + +- `filesystem_policy`: lists directories the agent can read (`read_only`) or read and write (`read_write`). Set `include_workdir` to make the current working directory writable automatically. +- `landlock`: controls Linux Landlock LSM behavior. Use `compatibility: best_effort` to run with the best available kernel ABI. +- `process`: sets the unprivileged user and group the agent runs as (`run_as_user`, `run_as_group`). +- `network_policies`: defines named `network_policies` that pair specific binaries with the endpoints they may reach, identified by host, port, and protocol. Endpoints can include L7 HTTP rules that restrict allowed methods and paths, TLS termination, and an enforcement mode. +- `inference`: specifies which routing hints the sandbox may use through `allowed_routes`. + +Every outbound connection is evaluated by destination, method, path, and binary. When inference routing is enabled, connections that do not match any network policy are inspected for inference. If they match a known inference API pattern, they are routed according to the inference configuration. + +#### An Example of a Minimal Policy + +```yaml +version: 1 +filesystem_policy: + include_workdir: true + read_only: [/usr, /lib, /etc, /app, /var/log] + read_write: [/sandbox, /tmp, /dev/null] +landlock: + compatibility: best_effort +process: + run_as_user: sandbox + run_as_group: sandbox +inference: + allowed_routes: + - local +``` + +In this example, there are no `network_policies`, which means no explicit allowlist. With `inference.allowed_routes` set, the engine treats unknown endpoints as "inspect for inference," and only inference-shaped traffic is allowed and routed. + +Create a sandbox with this policy: + +```console +$ nemoclaw sandbox create --policy ./policy-with-inference.yaml -- claude +``` + +## Live Policy Iteration + +You can update network and inference policy on a running sandbox without restarting it. + +```console +$ nemoclaw sandbox policy get my-agent --full > current-policy.yaml +# Edit current-policy.yaml to add a network_policy or inference route +$ nemoclaw sandbox policy set my-agent --policy current-policy.yaml --wait +``` + +Refer to [Policies](../../security/policies.md) for the full policy iteration workflow. + +## Next Steps + +- [Sandboxes](../../sandboxes/index.md) — full sandbox lifecycle management. +- [Inference Routing](../../inference/index.md) — route AI API calls to local or self-hosted backends. +- [Safety & Privacy](../../security/index.md) — understanding and customizing sandbox policies. +- [Network Access Control](../../security/network-access.md) — per-binary, per-endpoint network rules. diff --git a/docs/get-started/tutorials/run-claude.md b/docs/get-started/tutorials/run-claude.md new file mode 100644 index 00000000..50e58242 --- /dev/null +++ b/docs/get-started/tutorials/run-claude.md @@ -0,0 +1,235 @@ + + +# Run Claude Safely + +Run Anthropic Claude as a coding agent inside a NemoClaw sandbox. This tutorial takes you from a fresh cluster to an interactive Claude session with credential management, inference routing, and policy enforcement. + +## Prerequisites + +- NemoClaw CLI installed. Refer to [Installation](../installation.md). +- Docker installed and running. +- An Anthropic API key available as `ANTHROPIC_API_KEY` in your environment or in `~/.claude.json`. + +## Step 1: Deploy a Cluster + +NemoClaw runs sandboxes on a lightweight Kubernetes cluster packaged in a single Docker container. + +```console +$ nemoclaw cluster admin deploy +``` + +Verify that the cluster is healthy. + +```console +$ nemoclaw cluster status +``` + +You should see the cluster version and a healthy status. If you already have a running cluster, skip this step. + +## Step 2: Create a Claude Sandbox + +The simplest way to start Claude in a sandbox auto-discovers your local credentials and drops you into an interactive shell. + +```console +$ nemoclaw sandbox create --name my-claude -- claude +``` + +- `--name my-claude` — gives the sandbox a name for reconnection and management. +- `-- claude` — tells NemoClaw to auto-discover Anthropic credentials (`ANTHROPIC_API_KEY`, `CLAUDE_API_KEY`, `~/.claude.json`) and launch Claude inside the sandbox. + +The CLI creates a provider from your local credentials, uploads them to the gateway, and opens an interactive SSH session into the sandbox. + +### With File Sync and Additional Providers + +For working on a project with GitHub access: + +```console +$ nemoclaw sandbox create \ + --name my-claude \ + --provider my-github \ + --sync \ + -- claude +``` + +- `--provider my-github` — attaches a previously created GitHub provider (repeatable for multiple providers). +- `--sync` — pushes local git-tracked files to `/sandbox` in the container. + +## Step 3: Work Inside the Sandbox + +Once connected, you are inside an isolated environment. Provider credentials are available as environment variables. + +```console +sandbox@my-claude:~$ echo $ANTHROPIC_API_KEY +sk-ant-... + +sandbox@my-claude:~$ claude +``` + +The sandbox enforces its safety and privacy policy: + +- Filesystem access is restricted to allowed directories. +- All network connections go through the policy-enforcing proxy. +- Only explicitly permitted hosts and programs can reach the internet. + +## Step 4: Route Inference to a Private Model + +By default, Claude's API calls go through the sandbox proxy. You can reroute them to a private or self-hosted model to keep prompts and responses on your own infrastructure. + +### Create the Route + +```console +$ nemoclaw inference create \ + --routing-hint local \ + --base-url https://integrate.api.nvidia.com/ \ + --model-id nvidia/nemotron-3-nano-30b-a3b \ + --api-key $NVIDIA_API_KEY +``` + +### Apply a Policy with the Route + +Create a policy file `claude-policy.yaml`: + +```yaml +version: 1 +filesystem_policy: + include_workdir: true + read_only: [/usr, /lib, /etc, /app, /var/log] + read_write: [/sandbox, /tmp, /dev/null] +landlock: + compatibility: best_effort +process: + run_as_user: sandbox + run_as_group: sandbox +network_policies: + anthropic: + endpoints: + - host: api.anthropic.com + port: 443 + binaries: + - path_patterns: ["**/claude"] + - path_patterns: ["**/node"] +inference: + allowed_routes: + - local +``` + +This policy explicitly allows the Claude binary to reach `api.anthropic.com` and routes any other inference-shaped traffic to the `local` backend. + +Update the running sandbox with the new policy. + +```console +$ nemoclaw sandbox policy set my-claude --policy claude-policy.yaml --wait +``` + +Claude continues to work as normal — it still calls the Anthropic SDK as usual, but NemoClaw controls which requests go to the cloud and which are routed to your private model. + +## Step 5: Monitor and Iterate on Policy + +Watch sandbox logs to see which connections are allowed or denied. + +```console +$ nemoclaw sandbox logs my-claude --tail --source sandbox +``` + +If Claude needs access to additional endpoints (for example, GitHub for code retrieval or npm for package installation), pull the current policy, add the missing entry, and push it back. + +```console +$ nemoclaw sandbox policy get my-claude --full > current-policy.yaml +``` + +Edit `current-policy.yaml` to add a `network_policies` entry, then push it. + +```console +$ nemoclaw sandbox policy set my-claude --policy current-policy.yaml --wait +``` + +Refer to [Policies](../../security/policies.md) for the full policy iteration workflow. + +## Step 6: Reconnect or Open a Second Session + +You can reconnect to the sandbox from any terminal. + +```console +$ nemoclaw sandbox connect my-claude +``` + +For VS Code Remote-SSH access: + +```console +$ nemoclaw sandbox ssh-config my-claude >> ~/.ssh/config +``` + +Then connect via VS Code's Remote-SSH extension to the host `my-claude`. + +## Step 7: Verify Policy Enforcement + +With Claude running inside the sandbox, confirm that the policy is doing its job. + +### Test a Blocked Action + +From inside the sandbox, attempt to reach an endpoint that is not in the policy. + +```console +sandbox@my-claude:~$ curl https://example.com +``` + +The proxy blocks the connection because `example.com` is not in any `network_policies` entry and the request is not an inference API pattern. You should see a connection-refused or proxy-denied error. + +### Test a Blocked File Access + +Try to write to a read-only directory. + +```console +sandbox@my-claude:~$ touch /usr/test-file +touch: cannot touch '/usr/test-file': Permission denied +``` + +Landlock prevents writes outside the `read_write` paths defined in your policy. + +### Check the Denial in Logs + +From your host, view the sandbox logs to see the deny entries. + +```console +$ nemoclaw sandbox logs my-claude --tail --source sandbox +``` + +Look for log lines with `action: deny` showing the destination host, port, binary, and the reason. This confirms that the policy engine is evaluating every outbound connection and only allowing traffic that matches your policy. + +### Confirm Claude Works Through Policy + +Ask Claude to perform a task — for example, reading a file in `/sandbox` or writing code. Claude operates normally within the boundaries of the policy. If you configured an inference route in Step 4, the logs show whether inference calls were intercepted and routed to your private backend. + +```console +sandbox@my-claude:~$ claude "List the files in /sandbox" +``` + +## Step 8: Clean Up + +Delete the sandbox when you are finished to free cluster resources. + +```console +$ nemoclaw sandbox delete my-claude +``` + +## Quick Reference + +| Goal | How | +| ---- | --- | +| Launch Claude | `nemoclaw sandbox create --name my-claude -- claude` | +| Launch with file sync | `nemoclaw sandbox create --name my-claude --sync -- claude` | +| Reconnect | `nemoclaw sandbox connect my-claude` | +| Route inference to a private model | `nemoclaw inference create --routing-hint local --base-url --model-id --api-key ` and set `inference.allowed_routes: [local]` in policy | +| Update policy live | `nemoclaw sandbox policy set my-claude --policy updated.yaml --wait` | +| View logs | `nemoclaw sandbox logs my-claude --tail --source sandbox` | +| Delete | `nemoclaw sandbox delete my-claude` | + +## Next Steps + +- [Sandboxes](../../sandboxes/index.md) — full sandbox lifecycle management. +- [Providers](../../sandboxes/providers.md) — managing credentials and auto-discovery. +- [Inference Routing](../../inference/index.md) — route AI API calls to local or self-hosted backends. +- [Safety & Privacy](../../security/index.md) — understanding and customizing sandbox policies. diff --git a/docs/get-started/tutorials/run-openclaw.md b/docs/get-started/tutorials/run-openclaw.md new file mode 100644 index 00000000..7b0651d8 --- /dev/null +++ b/docs/get-started/tutorials/run-openclaw.md @@ -0,0 +1,201 @@ + + +# Run OpenClaw Safely + +Run OpenClaw inside a NemoClaw sandbox with zero code changes. This tutorial takes you from a fresh cluster to an OpenClaw instance with inference routing and policy enforcement. + +## Prerequisites + +- NemoClaw CLI installed. Refer to [Installation](../installation.md). +- Docker installed and running. + +## Step 1: Deploy a Cluster + +NemoClaw runs sandboxes on a lightweight Kubernetes cluster packaged in a single Docker container. + +```console +$ nemoclaw cluster admin deploy +``` + +Verify that the cluster is healthy. + +```console +$ nemoclaw cluster status +``` + +You should see the cluster version and a healthy status. If you already have a running cluster, skip this step. + +## Step 2: Launch OpenClaw + +The sandbox image includes OpenClaw, the onboarding flow, and a helper script that configures the gateway and prints the access URL. One command starts everything. + +```console +$ nemoclaw sandbox create --name my-openclaw --forward 18789 -- openclaw-start +``` + +- `--name my-openclaw` — gives the sandbox a name for reconnection and management. +- `--forward 18789` — forwards sandbox port 18789 to your machine so the OpenClaw UI is reachable locally. +- `openclaw-start` — runs `openclaw onboard`, starts the OpenClaw gateway in the background, and prints the UI URL and token. + +The CLI returns when the script finishes. The port forward keeps running in the background. + +## Step 3: Access the OpenClaw UI + +Once the sandbox is ready, open the Control UI and verify health. + +- **Control UI:** `http://127.0.0.1:18789/` — use the token printed during onboarding. +- **Health check:** run `openclaw health` from your host or inside the sandbox. + +No changes are required in OpenClaw itself. It runs as-is inside the sandbox with full isolation. + +### What `openclaw-start` Does + +Under the hood, the helper script runs: + +```bash +openclaw onboard +nohup openclaw gateway run > /tmp/gateway.log 2>&1 & +``` + +It then prints the UI URL and token from `~/.openclaw/openclaw.json`. + +## Step 4: Route Inference to a Private Model + +By default, the sandbox blocks outbound traffic that does not match an explicit network policy. To route OpenClaw's inference calls to a private or self-hosted model, create an inference route and allow it in sandbox policy. + +### Create the Route + +```console +$ nemoclaw inference create \ + --routing-hint local \ + --base-url https://integrate.api.nvidia.com/ \ + --model-id nvidia/nemotron-3-nano-30b-a3b \ + --api-key $NVIDIA_API_KEY +``` + +### Apply a Policy with the Route + +Create a policy file `openclaw-policy.yaml`: + +```yaml +version: 1 +filesystem_policy: + include_workdir: true + read_only: [/usr, /lib, /etc, /app, /var/log] + read_write: [/sandbox, /tmp, /dev/null] +landlock: + compatibility: best_effort +process: + run_as_user: sandbox + run_as_group: sandbox +inference: + allowed_routes: + - local +``` + +Update the running sandbox with the new policy. + +```console +$ nemoclaw sandbox policy set my-openclaw --policy openclaw-policy.yaml --wait +``` + +OpenClaw's inference calls are now transparently intercepted and routed to the configured backend. The agent's code does not change — it still targets the original API, and NemoClaw rewrites the destination and model per policy. + +## Step 5: Monitor and Iterate on Policy + +Watch sandbox logs to see which connections are allowed or denied. + +```console +$ nemoclaw sandbox logs my-openclaw --tail --source sandbox +``` + +If you see denied actions that should be allowed, pull the current policy, add the missing network policy entry, and push it back. + +```console +$ nemoclaw sandbox policy get my-openclaw --full > current-policy.yaml +``` + +Edit `current-policy.yaml` to add a `network_policies` entry for the denied endpoint, then push it. + +```console +$ nemoclaw sandbox policy set my-openclaw --policy current-policy.yaml --wait +``` + +Refer to [Policies](../../security/policies.md) for the full policy iteration workflow. + +## Step 6: Reconnect or Open a Second Session + +You can reconnect to the sandbox from any terminal. + +```console +$ nemoclaw sandbox connect my-openclaw +``` + +For VS Code Remote-SSH access: + +```console +$ nemoclaw sandbox ssh-config my-openclaw >> ~/.ssh/config +``` + +Then connect via VS Code's Remote-SSH extension to the host `my-openclaw`. + +## Step 7: Verify Policy Enforcement + +With the sandbox running and the OpenClaw UI accessible, confirm that the policy is doing its job. + +### Confirm the UI Is Accessible + +Open `http://127.0.0.1:18789/` in your browser and sign in with the token printed during onboarding. You should see the OpenClaw control dashboard. + +### Test a Blocked Action + +From inside the sandbox, attempt to reach an endpoint that is not in the policy. + +```console +sandbox@my-openclaw:~$ curl https://example.com +``` + +The proxy blocks the connection because `example.com` is not in any `network_policies` entry and the request is not an inference API pattern. You should see a connection-refused or proxy-denied error. + +### Check the Denial in Logs + +From your host, view the sandbox logs to see the deny entry. + +```console +$ nemoclaw sandbox logs my-openclaw --tail --source sandbox +``` + +Look for a log line with `action: deny` showing the destination host, port, binary (`curl`), and the reason. This confirms that the policy engine is evaluating every outbound connection and only allowing traffic that matches your policy. + +### Confirm Inference Routing + +If you configured an inference route in Step 4, ask OpenClaw to perform a task that triggers an inference call through the UI. The logs show whether the request was intercepted and routed to your configured backend rather than the original API endpoint. + +## Step 8: Clean Up + +Delete the sandbox when you are finished to free cluster resources. + +```console +$ nemoclaw sandbox delete my-openclaw +``` + +## Quick Reference + +| Goal | How | +| ---- | --- | +| Launch OpenClaw | `nemoclaw sandbox create --name my-openclaw --forward 18789 -- openclaw-start` | +| Reconnect | `nemoclaw sandbox connect my-openclaw` | +| Route inference to a private model | `nemoclaw inference create --routing-hint local --base-url --model-id --api-key ` and set `inference.allowed_routes: [local]` in policy | +| Update policy live | `nemoclaw sandbox policy set my-openclaw --policy updated.yaml --wait` | +| View logs | `nemoclaw sandbox logs my-openclaw --tail --source sandbox` | +| Delete | `nemoclaw sandbox delete my-openclaw` | + +## Next Steps + +- [Sandboxes](../../sandboxes/index.md) — full sandbox lifecycle management. +- [Inference Routing](../../inference/index.md) — route AI API calls to local or self-hosted backends. +- [Safety & Privacy](../../security/index.md) — understanding and customizing sandbox policies. +- [Network Access Control](../../security/network-access.md) — per-binary, per-endpoint network rules. diff --git a/docs/index.md b/docs/index.md index e700dcd7..dfcf8c65 100644 --- a/docs/index.md +++ b/docs/index.md @@ -87,8 +87,8 @@ Install the CLI, bootstrap a cluster, and launch your first sandbox in minutes. {bdg-secondary}`Get Started` ::: -:::{grid-item-card} Sandboxes -:link: sandboxes/index +:::{grid-item-card} Tutorials +:link: get-started/tutorials/index :link-type: doc Create, connect to, and manage sandboxes. Configure providers, sync files, forward ports, and bring your own containers. @@ -192,7 +192,7 @@ Links to the GitHub repository, related projects, and additional learning materi :caption: About :hidden: -about/index +Overview about/how-it-works about/support-matrix about/release-notes @@ -204,7 +204,7 @@ about/release-notes get-started/index get-started/installation -get-started/first-sandbox +get-started/tutorials/index ``` ```{toctree} From 6b2447c05b8680c604934db17ee5e2500b7a1cee Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 5 Mar 2026 15:07:22 -0800 Subject: [PATCH 04/39] pull in Kirit's content and polish --- docs/about/how-it-works.md | 2 +- docs/about/index.md | 6 +- docs/get-started/index.md | 100 ------- docs/get-started/installation.md | 72 +++-- docs/get-started/tutorials/index.md | 14 +- docs/get-started/tutorials/run-agents.md | 6 +- docs/get-started/tutorials/run-claude.md | 4 +- docs/get-started/tutorials/run-openclaw.md | 6 +- docs/get-started/tutorials/run-opencode.md | 265 +++++++++++++++++ docs/index.md | 34 ++- docs/inference/connect-sandboxes.md | 62 ++++ docs/inference/create-routes.md | 49 ++++ docs/inference/index.md | 49 +--- docs/inference/manage-routes.md | 46 +++ docs/observability/index.md | 2 +- docs/reference/architecture.md | 238 ++++++++++----- docs/reference/cli.md | 272 ++++++++--------- docs/reference/policy-schema.md | 273 ++++++++++-------- docs/safety-and-privacy/index.md | 50 ++++ .../network-access-rules.md | 215 ++++++++++++++ docs/safety-and-privacy/policies.md | 226 +++++++++++++++ docs/safety-and-privacy/security-model.md | 87 ++++++ docs/sandboxes/community-sandboxes.md | 93 ++++++ docs/sandboxes/create-and-manage.md | 205 +++++++++---- docs/sandboxes/custom-containers.md | 6 +- docs/sandboxes/file-sync.md | 41 --- docs/sandboxes/index.md | 13 +- docs/sandboxes/providers.md | 78 ++++- docs/sandboxes/terminal.md | 106 +++++++ docs/security/index.md | 74 ----- docs/security/network-access.md | 148 ---------- docs/security/policies.md | 190 ------------ docs/troubleshooting/cluster-issues.md | 35 +++ .../custom-container-issues.md | 17 ++ .../getting-more-information.md | 12 + docs/troubleshooting/index.md | 123 -------- .../troubleshooting/port-forwarding-issues.md | 18 ++ docs/troubleshooting/provider-issues.md | 26 ++ docs/troubleshooting/sandbox-issues.md | 43 +++ 39 files changed, 2143 insertions(+), 1163 deletions(-) delete mode 100644 docs/get-started/index.md create mode 100644 docs/get-started/tutorials/run-opencode.md create mode 100644 docs/inference/connect-sandboxes.md create mode 100644 docs/inference/create-routes.md create mode 100644 docs/inference/manage-routes.md create mode 100644 docs/safety-and-privacy/index.md create mode 100644 docs/safety-and-privacy/network-access-rules.md create mode 100644 docs/safety-and-privacy/policies.md create mode 100644 docs/safety-and-privacy/security-model.md create mode 100644 docs/sandboxes/community-sandboxes.md delete mode 100644 docs/sandboxes/file-sync.md create mode 100644 docs/sandboxes/terminal.md delete mode 100644 docs/security/index.md delete mode 100644 docs/security/network-access.md delete mode 100644 docs/security/policies.md create mode 100644 docs/troubleshooting/cluster-issues.md create mode 100644 docs/troubleshooting/custom-container-issues.md create mode 100644 docs/troubleshooting/getting-more-information.md delete mode 100644 docs/troubleshooting/index.md create mode 100644 docs/troubleshooting/port-forwarding-issues.md create mode 100644 docs/troubleshooting/provider-issues.md create mode 100644 docs/troubleshooting/sandbox-issues.md diff --git a/docs/about/how-it-works.md b/docs/about/how-it-works.md index 125b0632..9463e00c 100644 --- a/docs/about/how-it-works.md +++ b/docs/about/how-it-works.md @@ -60,7 +60,7 @@ Each sandbox runs inside a container as two processes: a privileged **supervisor - **Network namespace isolation** — the agent is placed in a separate network where the only reachable destination is the proxy, preventing data exfiltration. - **Process privilege separation** — the agent runs as an unprivileged user, protecting against privilege escalation. -All restrictions are driven by a YAML **policy** evaluated by an embedded OPA/Rego engine. See [Safety & Privacy](../security/index.md). +All restrictions are driven by a YAML **policy** evaluated by an embedded OPA/Rego engine. See [Safety & Privacy](../safety-and-privacy/index.md). ### Network Proxy diff --git a/docs/about/index.md b/docs/about/index.md index eaabb4c9..29fd8da6 100644 --- a/docs/about/index.md +++ b/docs/about/index.md @@ -75,7 +75,7 @@ AI API calls (OpenAI, Anthropic) are transparently intercepted by the proxy and :::{dropdown} Declarative Policies -YAML policies define what each sandbox can access — filesystems, network endpoints, inference routes, and credential bindings. Policies can be updated on running sandboxes without restart: push a new policy revision and the OPA engine reloads atomically within 30 seconds. Refer to [Policies](../security/policies.md) for the schema and examples. +YAML policies define what each sandbox can access — filesystems, network endpoints, inference routes, and credential bindings. Policies can be updated on running sandboxes without restart: push a new policy revision and the OPA engine reloads atomically within 30 seconds. Refer to [Policies](../safety-and-privacy/policies.md) for the schema and examples. ::: :::{dropdown} Zero-Config Deployment @@ -87,7 +87,7 @@ nemoclaw cluster admin deploy nemoclaw sandbox create -- claude ``` -No Kubernetes expertise is required. Refer to [Get Started](../get-started/index.md) for full installation steps. +No Kubernetes expertise is required. Refer to [Get Started](../get-started/installation.md) for full installation steps. ::: ## Use Cases @@ -106,4 +106,4 @@ No Kubernetes expertise is required. Refer to [Get Started](../get-started/index - [How It Works](how-it-works.md): Explore the architecture, major subsystems, and the end-to-end flow from cluster bootstrap to running sandbox. - [Support Matrix](support-matrix.md): Find platform requirements, supported providers, agent tools, and compatibility details. - [Release Notes](release-notes.md): Track what changed in each version. -- [Get Started](../get-started/index.md): Install the CLI, bootstrap a cluster, and launch your first sandbox. +- [Get Started](../get-started/installation.md): Install the CLI and launch your first sandbox. diff --git a/docs/get-started/index.md b/docs/get-started/index.md deleted file mode 100644 index da4f5ef5..00000000 --- a/docs/get-started/index.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: - page: "About Getting Started with NemoClaw" - nav: "About Getting Started" - card: "About Getting Started" -description: "Install the CLI, bootstrap a cluster, and launch your first sandbox in minutes." -topics: -- Get Started -tags: -- Installation -- Quickstart -- Sandbox -- CLI -content: - type: get_started - difficulty: technical_beginner - audience: - - engineer - - ai_engineer - - devops ---- - - - -# About Getting Started with NemoClaw - -NemoClaw is designed for minimal setup with safety and privacy built in from the start. Docker is the only prerequisite. Three commands take you from zero to a running, policy-enforced sandbox. - -::::{grid} 1 1 2 2 -:gutter: 3 - -:::{grid-item-card} Installation -:link: installation -:link-type: doc - -Prerequisites, install methods, shell completions, and verification steps for the NemoClaw CLI. -+++ -{bdg-secondary}`Get Started` -::: - -:::{grid-item-card} Tutorials -:link: tutorials/index -:link-type: doc - -Step-by-step walkthrough from cluster bootstrap to an interactive sandbox session with policy enforcement. -+++ -{bdg-secondary}`Tutorial` -::: - -:::: - ---- - -## Next Steps - -After you have a sandbox running, explore the following areas. - -::::{grid} 1 1 2 2 -:gutter: 3 - -:::{grid-item-card} Sandboxes -:link: ../sandboxes/index -:link-type: doc - -Create, connect to, and manage sandboxes. Configure providers, sync files, forward ports, and bring your own containers. -+++ -{bdg-secondary}`How To` -::: - -:::{grid-item-card} Safety and Privacy -:link: ../security/index -:link-type: doc - -Understand how NemoClaw keeps your data safe and private — and write policies that control filesystem, network, and inference access. -+++ -{bdg-secondary}`Concept` -::: - -:::{grid-item-card} Inference Routing -:link: ../inference/index -:link-type: doc - -Route AI API calls to local or self-hosted backends without modifying agent code. -+++ -{bdg-secondary}`How To` -::: - -:::{grid-item-card} Reference -:link: ../reference/index -:link-type: doc - -CLI command reference, policy schema, environment variables, and system architecture diagrams. -+++ -{bdg-secondary}`Reference` -::: - -:::: diff --git a/docs/get-started/installation.md b/docs/get-started/installation.md index f44f1bd4..dad8ac91 100644 --- a/docs/get-started/installation.md +++ b/docs/get-started/installation.md @@ -1,56 +1,78 @@ +--- +title: + page: "About Getting Started with NemoClaw" + nav: "About Getting Started" + card: "About Getting Started" +description: "Install the CLI, bootstrap a cluster, and launch your first sandbox in minutes." +topics: +- Get Started +tags: +- Installation +- Quickstart +- Sandbox +- CLI +content: + type: get_started + difficulty: technical_beginner + audience: + - engineer + - ai_engineer + - devops +--- + -# Installation +# Install and Create a Sandbox -Install the NemoClaw CLI to create and manage sandboxes from your terminal. +NemoClaw is designed for minimal setup with safety and privacy built in from the start. Two commands take you from zero to a running, policy-enforced sandbox. ## Prerequisites -Confirm that the following dependencies are available on your machine before you install the CLI. +The following are the prerequisites for the NemoClaw CLI. -- **Docker** — must be installed and running. This is the only runtime dependency. -- **Python 3.12+** — required for `pip install`. +- Docker must be running. +- Python 3.12+ is required. ## Install the CLI -Install the latest release from PyPI. - ```console $ pip install nemoclaw ``` -This installs the `nemoclaw` command (also available as `ncl`). - -### Verify the Installation +## Create a Sandbox -Run the help command to confirm that the CLI is on your path and working. +::::{tab-set} +:::{tab-item} Claude Code ```console -$ nemoclaw --help +$ nemoclaw sandbox create -- claude ``` -You should see the top-level help with command groups: `cluster`, `sandbox`, `provider`, `inference`, and `gator`. +```text +✓ Runtime ready +✓ Discovered Claude credentials (ANTHROPIC_API_KEY) +✓ Created sandbox: keen-fox +✓ Policy loaded (4 protection layers active) -## Shell Completions +Connecting to keen-fox... +``` -Generate shell completions for tab-completion support: +Claude Code works out of the box with the default policy. +::: +:::{tab-item} Community Sandbox ```console -$ nemoclaw completions bash >> ~/.bashrc -$ nemoclaw completions zsh >> ~/.zshrc -$ nemoclaw completions fish >> ~/.config/fish/completions/nemoclaw.fish +$ nemoclaw sandbox create --from openclaw ``` -## For Contributors +The `--from` flag pulls from the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) catalog --- a collection of domain-specific sandbox images bundled with their own containers, policies, and skills. +::: -If you are developing NemoClaw itself, see the [Contributing Guide](https://github.com/NVIDIA/NemoClaw/blob/main/CONTRIBUTING.md) for building from source using `mise`. +:::: -The contributor workflow uses a local shortcut script at `scripts/bin/nemoclaw` that automatically builds the CLI from source. With `mise` active, you can run `nemoclaw` directly from the repository. +The agent runs with filesystem, network, process, and inference protection active. Credentials stay inside the sandbox, network access follows your policy, and inference traffic remains private. A single YAML policy controls all four protection layers and is hot-reloadable on a running sandbox. -```console -$ mise trust -$ mise run sandbox -``` +For opencode or Codex, see the [Tutorials](tutorials/index.md) for agent-specific setup. diff --git a/docs/get-started/tutorials/index.md b/docs/get-started/tutorials/index.md index 00f638ee..cd5ecb14 100644 --- a/docs/get-started/tutorials/index.md +++ b/docs/get-started/tutorials/index.md @@ -1,6 +1,8 @@ # Tutorials -This section contains tutorials that help you get started with NemoClaw. +Each tutorial walks through an end-to-end workflow from bootstrapping a cluster to running an agent inside a policy-enforced sandbox. Pick the tutorial that matches your agent and follow along. + +All tutorials assume you have [installed the CLI](../installation.md) and have Docker running. ::::{grid} 1 1 2 2 :gutter: 3 @@ -23,6 +25,15 @@ Run Anthropic Claude as a coding agent with credential management, inference rou {bdg-secondary}`Tutorial` ::: +:::{grid-item-card} Run Opencode with NVIDIA Inference +:link: run-opencode +:link-type: doc + +Set up opencode with NVIDIA inference routing, custom policies, and the full policy iteration loop. ++++ +{bdg-secondary}`Tutorial` +::: + :::: ```{toctree} @@ -31,5 +42,6 @@ Run Anthropic Claude as a coding agent with credential management, inference rou Run OpenClaw Safely Run Claude Safely +Run Opencode with NVIDIA Inference Run Any Agent Safely ``` diff --git a/docs/get-started/tutorials/run-agents.md b/docs/get-started/tutorials/run-agents.md index ca6506ee..428ffd05 100644 --- a/docs/get-started/tutorials/run-agents.md +++ b/docs/get-started/tutorials/run-agents.md @@ -190,11 +190,11 @@ $ nemoclaw sandbox policy get my-agent --full > current-policy.yaml $ nemoclaw sandbox policy set my-agent --policy current-policy.yaml --wait ``` -Refer to [Policies](../../security/policies.md) for the full policy iteration workflow. +Refer to [Policies](../../safety-and-privacy/policies.md) for the full policy iteration workflow. ## Next Steps - [Sandboxes](../../sandboxes/index.md) — full sandbox lifecycle management. - [Inference Routing](../../inference/index.md) — route AI API calls to local or self-hosted backends. -- [Safety & Privacy](../../security/index.md) — understanding and customizing sandbox policies. -- [Network Access Control](../../security/network-access.md) — per-binary, per-endpoint network rules. +- [Safety & Privacy](../../safety-and-privacy/index.md) — understanding and customizing sandbox policies. +- [Network Access Control](../../safety-and-privacy/network-access-rules.md) — per-binary, per-endpoint network rules. diff --git a/docs/get-started/tutorials/run-claude.md b/docs/get-started/tutorials/run-claude.md index 50e58242..1818ef35 100644 --- a/docs/get-started/tutorials/run-claude.md +++ b/docs/get-started/tutorials/run-claude.md @@ -146,7 +146,7 @@ Edit `current-policy.yaml` to add a `network_policies` entry, then push it. $ nemoclaw sandbox policy set my-claude --policy current-policy.yaml --wait ``` -Refer to [Policies](../../security/policies.md) for the full policy iteration workflow. +Refer to [Policies](../../safety-and-privacy/policies.md) for the full policy iteration workflow. ## Step 6: Reconnect or Open a Second Session @@ -232,4 +232,4 @@ $ nemoclaw sandbox delete my-claude - [Sandboxes](../../sandboxes/index.md) — full sandbox lifecycle management. - [Providers](../../sandboxes/providers.md) — managing credentials and auto-discovery. - [Inference Routing](../../inference/index.md) — route AI API calls to local or self-hosted backends. -- [Safety & Privacy](../../security/index.md) — understanding and customizing sandbox policies. +- [Safety & Privacy](../../safety-and-privacy/index.md) — understanding and customizing sandbox policies. diff --git a/docs/get-started/tutorials/run-openclaw.md b/docs/get-started/tutorials/run-openclaw.md index 7b0651d8..f384461f 100644 --- a/docs/get-started/tutorials/run-openclaw.md +++ b/docs/get-started/tutorials/run-openclaw.md @@ -124,7 +124,7 @@ Edit `current-policy.yaml` to add a `network_policies` entry for the denied endp $ nemoclaw sandbox policy set my-openclaw --policy current-policy.yaml --wait ``` -Refer to [Policies](../../security/policies.md) for the full policy iteration workflow. +Refer to [Policies](../../safety-and-privacy/policies.md) for the full policy iteration workflow. ## Step 6: Reconnect or Open a Second Session @@ -197,5 +197,5 @@ $ nemoclaw sandbox delete my-openclaw - [Sandboxes](../../sandboxes/index.md) — full sandbox lifecycle management. - [Inference Routing](../../inference/index.md) — route AI API calls to local or self-hosted backends. -- [Safety & Privacy](../../security/index.md) — understanding and customizing sandbox policies. -- [Network Access Control](../../security/network-access.md) — per-binary, per-endpoint network rules. +- [Safety & Privacy](../../safety-and-privacy/index.md) — understanding and customizing sandbox policies. +- [Network Access Control](../../safety-and-privacy/network-access-rules.md) — per-binary, per-endpoint network rules. diff --git a/docs/get-started/tutorials/run-opencode.md b/docs/get-started/tutorials/run-opencode.md new file mode 100644 index 00000000..7c952cc0 --- /dev/null +++ b/docs/get-started/tutorials/run-opencode.md @@ -0,0 +1,265 @@ + + +# Run opencode with NVIDIA Inference + +This tutorial walks through a realistic setup where you run [opencode](https://opencode.ai) inside a NemoClaw sandbox with inference routed to NVIDIA API endpoints. Along the way, you will hit policy problems, diagnose them from logs, write a custom policy, and configure inference routing --- the full policy iteration loop. + +**What you will learn:** + +- Creating a provider manually with `--from-existing` +- Writing a custom policy to replace the defaults +- Reading sandbox logs to diagnose denied actions +- The difference between agent traffic and userland inference +- Setting up inference routes for code running inside the sandbox + +## Prerequisites + +Before you begin: + +- **`NVIDIA_API_KEY` environment variable** set on your host machine with a valid NVIDIA API key +- **NemoClaw CLI** installed (`pip install nemoclaw`) +- Docker installed and running. + +## Step 1: Create the Provider + +Unlike the Claude Code tutorial where the CLI auto-discovered credentials, here you create a provider explicitly. This gives you control over the provider name and type. + +```console +$ nemoclaw provider create --name nvidia --type nvidia --from-existing +``` + +The `--from-existing` flag tells the CLI to discover credentials from your local environment. It finds `NVIDIA_API_KEY` and stores it securely. The provider is now available to attach to any sandbox. + +Verify it was created: + +```console +$ nemoclaw provider list +``` + +## Step 2: Create the Sandbox + +Create a sandbox with the NVIDIA provider attached and opencode as the startup command: + +```console +$ nemoclaw sandbox create --name opencode-sandbox --provider nvidia --keep -- opencode +``` + +The `--keep` flag keeps the sandbox alive after you exit, which you will need for the iteration steps ahead. The CLI creates the sandbox with the default policy, injects the NVIDIA credentials, and starts opencode. + +## Step 3: Hit a Problem + +Try using opencode inside the sandbox. You will likely find that calls to NVIDIA inference endpoints fail or behave unexpectedly. The default policy is designed around Claude Code, not opencode. + +Open a second terminal and check the logs: + +```console +$ nemoclaw sandbox logs opencode-sandbox --tail +``` + +Or launch the NemoClaw Terminal for a live view: + +```console +$ nemoclaw gator +``` + +Look for lines like these in the output: + +``` +action=deny host=integrate.api.nvidia.com binary=/usr/local/bin/opencode reason="no matching network policy" +action=deny host=opencode.ai binary=/usr/bin/node reason="no matching network policy" +action=inspect_for_inference host=integrate.api.nvidia.com binary=/bin/bash +``` + +These log entries tell you exactly what is being blocked and why. + +## Step 4: Understand Why + +The default policy has a `nvidia_inference` network policy entry, but it is configured for a narrow set of binaries --- typically `/usr/local/bin/claude` and `/usr/bin/node`. If opencode makes HTTP calls through a different binary (its own binary, `curl`, or a shell subprocess), those connections do not match any policy rule and get denied. + +There are two separate problems: + +1. **opencode's own traffic.** opencode contacts `opencode.ai` for its API and `integrate.api.nvidia.com` for inference. Neither of these endpoints has a matching policy entry for the binaries opencode uses. +2. **No opencode.ai endpoint.** The default policy has no entry for `opencode.ai` at all. Even if the binary matched, the destination is not listed. + +This is the expected behavior --- NemoClaw denies by default. You need to write a policy that explicitly allows what opencode needs. + +## Step 5: Write a Custom Policy + +Create a file called `opencode-policy.yaml` with the following content: + +```yaml +version: 1 +inference: + allowed_routes: + - nvidia +filesystem_policy: + include_workdir: true + read_only: + - /usr + - /lib + - /proc + - /dev/urandom + - /app + - /etc + - /var/log + read_write: + - /sandbox + - /tmp + - /dev/null +landlock: + compatibility: best_effort +process: + run_as_user: sandbox + run_as_group: sandbox +network_policies: + opencode_api: + name: opencode-api + endpoints: + - host: opencode.ai + port: 443 + protocol: rest + tls: terminate + enforcement: enforce + access: full + binaries: + - path: /usr/local/bin/opencode + - path: /usr/bin/node + nvidia_inference: + name: nvidia-inference + endpoints: + - host: integrate.api.nvidia.com + port: 443 + protocol: rest + tls: terminate + enforcement: enforce + access: full + binaries: + - path: /usr/local/bin/opencode + - path: /usr/bin/node + - path: /usr/bin/curl + - path: /bin/bash + npm_registry: + name: npm-registry + endpoints: + - host: registry.npmjs.org + port: 443 + binaries: + - path: /usr/bin/npm + - path: /usr/bin/node + - path: /usr/local/bin/npm + - path: /usr/local/bin/node + github_rest_api: + name: github-rest-api + endpoints: + - host: api.github.com + port: 443 + protocol: rest + tls: terminate + enforcement: enforce + access: read-only + binaries: + - path: /usr/local/bin/opencode + - path: /usr/bin/node + - path: /usr/bin/gh + github_ssh_over_https: + name: github-ssh-over-https + endpoints: + - host: github.com + port: 443 + protocol: rest + tls: terminate + enforcement: enforce + rules: + - allow: + method: GET + path: "/**/info/refs*" + - allow: + method: POST + path: "/**/git-upload-pack" + binaries: + - path: /usr/bin/git +``` + +Compared to the default policy, this adds: + +- **`opencode_api`** --- allows opencode and Node.js to reach `opencode.ai:443` +- **Broader `nvidia_inference` binaries** --- adds `/usr/local/bin/opencode`, `/usr/bin/curl`, and `/bin/bash` so opencode's subprocesses can reach the NVIDIA endpoint +- **`inference.allowed_routes`** --- includes `nvidia` so inference routing works for userland code +- **GitHub access** scoped for opencode's git operations + +:::{warning} +The `filesystem_policy`, `landlock`, and `process` sections are static --- they are set at sandbox creation time and cannot be changed on a running sandbox. If you need to modify these, you must delete and recreate the sandbox. The `network_policies` and `inference` sections are dynamic and can be hot-reloaded. +::: + +## Step 6: Push the Policy + +Apply your custom policy to the running sandbox: + +```console +$ nemoclaw sandbox policy set opencode-sandbox --policy opencode-policy.yaml --wait +``` + +The `--wait` flag blocks until the sandbox confirms the policy is loaded. You will see output indicating success or failure. + +Verify the policy revision was accepted: + +```console +$ nemoclaw sandbox policy list opencode-sandbox +``` + +The latest revision should show status `loaded`. + +## Step 7: Set Up Inference Routing + +So far, you have allowed the opencode *agent* to reach `integrate.api.nvidia.com` directly via network policy. But what about code that opencode writes and runs inside the sandbox? If that code calls an LLM API, it goes through the privacy router --- a separate mechanism. + +Create an inference route so userland code can access NVIDIA models: + +```console +$ nemoclaw inference create \ + --routing-hint nvidia \ + --base-url https://integrate.api.nvidia.com \ + --model-id z-ai/glm5 \ + --api-key $NVIDIA_API_KEY +``` + +The policy you wrote in Step 5 already includes `nvidia` in `inference.allowed_routes`, so you do not need to push a policy update. If you had not included it, you would add it to the policy and push again: + +```console +$ nemoclaw sandbox policy set opencode-sandbox --policy opencode-policy.yaml --wait +``` + +:::{note} +The distinction matters: **network policies** control which hosts the agent binary can reach directly. **Inference routes** control where LLM API calls from userland code (scripts, notebooks, applications the agent writes) get routed. They are two separate enforcement points. +::: + +## Step 8: Verify + +Tail the logs again: + +```console +$ nemoclaw sandbox logs opencode-sandbox --tail +``` + +You should no longer see `action=deny` lines for the endpoints you added. Connections to `opencode.ai`, `integrate.api.nvidia.com`, and GitHub should show `action=allow`. + +If you still see denials, read the log line carefully --- it tells you the exact host, port, and binary that was blocked. Add the missing entry to your policy and push again. This observe-modify-push cycle is the policy iteration loop, and it is the normal workflow for getting a new tool running in NemoClaw. + +## Clean Up + +When you are done: + +```console +$ nemoclaw sandbox delete opencode-sandbox +``` + +## Next Steps + +- [Policies](../../safety-and-privacy/policies.md) --- full reference on policy YAML structure, static vs dynamic fields, and enforcement modes +- [Network Access Control](../../safety-and-privacy/network-access-rules.md) --- how the proxy evaluates network rules, L4 vs L7 inspection, and TLS termination +- [Inference Routing](../../inference/index.md) --- inference route configuration, protocol detection, and transparent rerouting +- [Providers](../../sandboxes/providers.md) --- provider types, credential discovery, and manual vs automatic creation +- [Security Model](../../safety-and-privacy/security-model.md) --- the four protection layers and how they interact diff --git a/docs/index.md b/docs/index.md index dfcf8c65..28a2b412 100644 --- a/docs/index.md +++ b/docs/index.md @@ -24,7 +24,12 @@ content: # NVIDIA NemoClaw Developer Guide -NemoClaw is the safe, private runtime for autonomous AI agents. It provides sandboxed execution environments that protect your data, credentials, and infrastructure — agents run with exactly the permissions they need and nothing more, governed by declarative policies that prevent unauthorized file access, data exfiltration, and uncontrolled network activity. +NemoClaw is the safe, private runtime for autonomous AI agents. It provides sandboxed execution environments +that protect your data, credentials, and infrastructure — agents run with exactly the permissions they need and +nothing more, governed by declarative policies that prevent unauthorized file access, data exfiltration, and +uncontrolled network activity. + +--- ## About NemoClaw @@ -79,7 +84,7 @@ Install the CLI, bootstrap a cluster, and create your first sandbox. :gutter: 3 :::{grid-item-card} About Getting Started -:link: get-started/index +:link: get-started/installation :link-type: doc Install the CLI, bootstrap a cluster, and launch your first sandbox in minutes. @@ -106,7 +111,7 @@ Configure safety policies, route inference traffic, manage clusters, and monitor :gutter: 3 :::{grid-item-card} Safety and Privacy -:link: security/index +:link: safety-and-privacy/index :link-type: doc Understand how NemoClaw keeps your data safe and private — and write policies that control filesystem, network, and inference access. @@ -169,7 +174,7 @@ CLI command reference, policy schema, environment variables, and system architec ::: :::{grid-item-card} Troubleshooting -:link: troubleshooting/index +:link: troubleshooting/cluster-issues :link-type: doc Diagnose common issues with clusters, sandboxes, and networking. @@ -202,7 +207,6 @@ about/release-notes :caption: Get Started :hidden: -get-started/index get-started/installation get-started/tutorials/index ``` @@ -215,17 +219,19 @@ sandboxes/index sandboxes/create-and-manage sandboxes/providers sandboxes/custom-containers -sandboxes/file-sync +sandboxes/community-sandboxes sandboxes/port-forwarding +sandboxes/terminal ``` ```{toctree} :caption: Safety and Privacy :hidden: -security/index -security/policies -security/network-access +safety-and-privacy/index +safety-and-privacy/security-model +safety-and-privacy/policies +safety-and-privacy/network-access-rules ``` ```{toctree} @@ -233,6 +239,9 @@ security/network-access :hidden: inference/index +inference/create-routes +inference/manage-routes +inference/connect-sandboxes ``` ```{toctree} @@ -272,7 +281,12 @@ reference/architecture :caption: Troubleshooting :hidden: -troubleshooting/index +troubleshooting/cluster-issues +troubleshooting/sandbox-issues +troubleshooting/provider-issues +troubleshooting/custom-container-issues +troubleshooting/port-forwarding-issues +troubleshooting/getting-more-information ``` ```{toctree} diff --git a/docs/inference/connect-sandboxes.md b/docs/inference/connect-sandboxes.md new file mode 100644 index 00000000..99db55d7 --- /dev/null +++ b/docs/inference/connect-sandboxes.md @@ -0,0 +1,62 @@ + + +# Connect Sandboxes to Inference Routes + +Inference routes take effect only when a sandbox policy references the route's `routing_hint` in its `inference.allowed_routes` list. This page shows how to wire them together. + +## Step 1: Add the Routing Hint to Your Policy + +In your policy YAML, include the routing hint that matches the route you created: + +```yaml +inference: + allowed_routes: + - local +``` + +## Step 2: Create or Update the Sandbox with That Policy + +When creating a new sandbox: + +```console +$ nemoclaw sandbox create --policy ./my-policy.yaml --keep -- claude +``` + +Or, if the sandbox is already running, push an updated policy: + +```console +$ nemoclaw sandbox policy set --policy ./my-policy.yaml --wait +``` + +The `inference` section is a dynamic field, so you can add or remove routing hints on a running sandbox without recreating it. + +## How It Works + +Once a sandbox has `allowed_routes` configured, the proxy intercepts outbound connections that do not match any explicit `network_policies` entry. If the request matches a known inference API pattern (e.g., `POST /v1/chat/completions`), the proxy: + +1. TLS-terminates the connection. +2. Strips the original authorization header. +3. Selects a route whose `routing_hint` appears in the sandbox's `allowed_routes`. +4. Injects the route's API key and model ID. +5. Forwards the request to the route's backend. + +The agent's code sees a normal HTTP response as if it came from the original API. + +:::{tip} +To avoid passing `--policy` every time, set a default policy via environment variable: + +```console +$ export NEMOCLAW_SANDBOX_POLICY=./my-policy.yaml +$ nemoclaw sandbox create --keep -- claude +``` +::: + +## Next Steps + +- {doc}`create-routes` --- register new inference backends. +- {doc}`manage-routes` --- list, update, and delete routes. +- [Policies](../safety-and-privacy/policies.md) --- the full policy iteration workflow. +- [Network Access Control](../safety-and-privacy/network-access-rules.md) --- how agent traffic differs from userland inference traffic. diff --git a/docs/inference/create-routes.md b/docs/inference/create-routes.md new file mode 100644 index 00000000..9a776950 --- /dev/null +++ b/docs/inference/create-routes.md @@ -0,0 +1,49 @@ + + +# Create Inference Routes + +Use `nemoclaw inference create` to register a new inference backend that sandboxes can route AI API calls to. + +:::{note} +Inference routes are for **userland code** --- scripts and programs that the agent writes and executes inside the sandbox. The agent's own API traffic flows directly through network policies, not through inference routing. See {doc}`../safety-and-privacy/network-access-rules` for the distinction between agent traffic and userland traffic. +::: + +## Create a Route + +```console +$ nemoclaw inference create \ + --routing-hint local \ + --base-url https://my-llm.example.com \ + --model-id my-model-v1 \ + --api-key sk-abc123 +``` + +This creates a route named after the routing hint. Any sandbox whose policy includes `local` in its `inference.allowed_routes` list can use this route. If you omit `--protocol`, the CLI probes the endpoint and auto-detects the supported protocol (see [Supported API Patterns](index.md#supported-api-patterns)). + +## Flags + +| Flag | Description | +|------|-------------| +| `--routing-hint` (required) | Name used in sandbox policy to reference this route. | +| `--base-url` (required) | Backend inference endpoint URL. | +| `--model-id` (required) | Model identifier sent to the backend. | +| `--api-key` | API key for the backend endpoint. | +| `--protocol` | Supported protocol(s): `openai_chat_completions`, `openai_completions`, `anthropic_messages` (repeatable, auto-detected if omitted). | +| `--disabled` | Create the route in a disabled state. | + +See the [CLI Reference](../reference/cli.md#inference-commands) for the full command specification. + +## Good to Know + +- **Cluster-level** --- routes are shared across all sandboxes in the cluster, not scoped to one sandbox. +- **Per-model** --- each route maps to one model. Create multiple routes with the same `--routing-hint` but different `--model-id` values to expose multiple models. +- **Hot-reloadable** --- routes can be created, updated, or deleted at any time without restarting sandboxes. + +## Next Steps + +- {doc}`manage-routes` --- list, update, and delete inference routes. +- {doc}`connect-sandboxes` --- connect a sandbox to inference routes via policy. +- {doc}`index` --- understand the inference routing architecture and interception sequence. diff --git a/docs/inference/index.md b/docs/inference/index.md index 614ac0c8..2080d3fc 100644 --- a/docs/inference/index.md +++ b/docs/inference/index.md @@ -41,52 +41,11 @@ sequenceDiagram Proxy-->>Agent: HTTP 200 OK (re-encrypted) ``` -## Creating Inference Routes +## Working with Inference Routes -Create a route that maps a routing hint to a backend: - -```console -$ nemoclaw inference create \ - --routing-hint local \ - --base-url https://my-llm.example.com \ - --model-id my-model-v1 \ - --api-key sk-abc123 -``` - -If `--protocol` is omitted, the CLI auto-detects by probing the endpoint. - -| Flag | Description | -|------|-------------| -| `--routing-hint` (required) | Name used in sandbox policy to reference this route. | -| `--base-url` (required) | Backend inference endpoint URL. | -| `--model-id` (required) | Model identifier sent to the backend. | -| `--api-key` | API key for the backend endpoint. | -| `--protocol` | Supported protocol(s): `openai_chat_completions`, `openai_completions`, `anthropic_messages` (repeatable, auto-detected if omitted). | -| `--disabled` | Create the route in disabled state. | - -## Managing Routes - -```console -$ nemoclaw inference list -$ nemoclaw inference update my-route --routing-hint local --base-url https://new-url.example.com -$ nemoclaw inference delete my-route -``` - -## Connecting Sandboxes to Inference Routes - -Add the routing hint to the sandbox policy's `inference.allowed_routes`: - -```yaml -inference: - allowed_routes: - - local -``` - -Then create the sandbox with that policy: - -```console -$ nemoclaw sandbox create --policy ./policy-with-inference.yaml -- claude -``` +- {doc}`create-routes` --- register a new inference backend with `nemoclaw inference create`. +- {doc}`manage-routes` --- list, update, and delete inference routes. +- {doc}`connect-sandboxes` --- connect a sandbox to inference routes via policy. ## Key Design Properties diff --git a/docs/inference/manage-routes.md b/docs/inference/manage-routes.md new file mode 100644 index 00000000..992dabdd --- /dev/null +++ b/docs/inference/manage-routes.md @@ -0,0 +1,46 @@ + + +# Manage Inference Routes + +List, update, and delete inference routes across your cluster. + +## List All Routes + +```console +$ nemoclaw inference list +``` + +## Update a Route + +Change any field on an existing route: + +```console +$ nemoclaw inference update --base-url https://new-backend.example.com +``` + +```console +$ nemoclaw inference update --model-id updated-model-v2 --api-key sk-new-key +``` + +## Delete a Route + +```console +$ nemoclaw inference delete +``` + +Deleting a route that is referenced by running sandboxes does not interrupt those sandboxes immediately. Future inference requests that would have matched the deleted route will be denied. + +## Behavior Notes + +- Routes are **cluster-level** --- they are shared across all sandboxes in the cluster, not scoped to one sandbox. +- Each route maps to **one model**. Create multiple routes with the same `--routing-hint` but different `--model-id` values to expose multiple models. +- Route changes are **hot-reloadable** --- sandboxes pick up new, updated, or deleted routes without restarting. + +## Next Steps + +- {doc}`create-routes` --- register a new inference backend. +- {doc}`connect-sandboxes` --- connect a sandbox to inference routes via policy. +- [CLI Reference](../reference/cli.md#inference-commands) --- full command specification for all inference commands. diff --git a/docs/observability/index.md b/docs/observability/index.md index 90248629..4d309365 100644 --- a/docs/observability/index.md +++ b/docs/observability/index.md @@ -62,7 +62,7 @@ Deny log entries include: - **Binary path** — which program attempted the connection. - **Deny reason** — why the connection was blocked (no matching policy, binary mismatch, etc.). -This information drives the [policy iteration loop](../security/policies.md#the-policy-iteration-loop). +This information drives the [policy iteration loop](../safety-and-privacy/policies.md#the-policy-iteration-loop). ## Log Architecture diff --git a/docs/reference/architecture.md b/docs/reference/architecture.md index 083bdfa5..6d7a00b3 100644 --- a/docs/reference/architecture.md +++ b/docs/reference/architecture.md @@ -3,86 +3,180 @@ SPDX-License-Identifier: Apache-2.0 --> -# System Architecture +# Architecture -This page provides a high-level view of NemoClaw's system architecture and component interactions. +NemoClaw runs as a [k3s](https://k3s.io/) Kubernetes cluster inside a Docker +container. Sandboxes are Kubernetes pods managed by the NemoClaw control plane. +The system has four core components. -## Architecture Diagram +| Component | Role | +|---|---| +| **Gateway** | Control-plane API that coordinates sandbox lifecycle and state, acts as the auth boundary, and brokers requests across the platform. | +| **Sandbox** | Isolated runtime that includes container supervision and general L7 egress routing. | +| **Policy Engine** | Policy definition and enforcement layer for filesystem, network, and process constraints. Defense in depth enforces policies from the application layer down to infrastructure and kernel layers. | +| **Privacy Router** | Privacy-aware LLM routing layer that keeps sensitive context on sandbox compute and routes based on cost/privacy policy. | + +## Component Diagram ```{mermaid} -flowchart TB - subgraph USER["User's Machine"] - CLI["Command-Line Interface"] +graph TB + subgraph docker["Docker Container"] + subgraph k3s["k3s Cluster"] + gw["Gateway"] + pr["Privacy Router"] + + subgraph pod1["Sandbox"] + sup1["Supervisor"] + proxy1["L7 Proxy"] + pe1["Policy Engine"] + agent1["Agent"] + + sup1 --> proxy1 + sup1 --> agent1 + proxy1 --> pe1 + end + + subgraph pod2["Sandbox"] + sup2["Supervisor"] + proxy2["L7 Proxy"] + pe2["Policy Engine"] + agent2["Agent"] + + sup2 --> proxy2 + sup2 --> agent2 + proxy2 --> pe2 + end + + gw -- "credentials,
policies" --> sup1 + gw -- "credentials,
policies" --> sup2 + end end - subgraph CLUSTER["Kubernetes Cluster (single Docker container)"] - SERVER["Gateway / Control Plane"] - DB["Database (SQLite or Postgres)"] + cli["nemoclaw CLI"] -- "gRPC" --> gw + agent1 -- "all outbound
traffic" --> proxy1 + agent2 -- "all outbound
traffic" --> proxy2 + proxy1 -- "policy-approved
traffic" --> internet["External Services"] + proxy2 -- "policy-approved
traffic" --> internet + proxy1 -- "inference traffic" --> pr + proxy2 -- "inference traffic" --> pr + pr -- "routed requests" --> backend["LLM Backend"] +``` - subgraph SBX["Sandbox Pod"] - SUPERVISOR["Sandbox Supervisor"] - PROXY["Network Proxy"] - CHILD["Agent Process (restricted)"] - OPA["Policy Engine (OPA)"] - end - end +## Gateway - subgraph EXT["External Services"] - HOSTS["Allowed Hosts"] - BACKEND["Inference Backends"] - end +The gateway is the central control-plane API. It coordinates sandbox lifecycle +and state, acts as the auth boundary, and brokers all requests across the +platform. It exposes a gRPC API consumed by the CLI and handles: + +- Sandbox lifecycle --- creates, monitors, and deletes sandbox pods. +- Provider storage --- stores encrypted provider credentials. +- Policy distribution --- delivers policy YAML to sandboxes at startup and on + hot-reload. +- SSH termination --- terminates SSH tunnels from the CLI and routes them to + the correct sandbox. + +The CLI never talks to sandbox pods directly. All commands go through the +gateway. + +## Sandbox + +Each sandbox is an isolated runtime that includes container supervision and +general L7 egress routing. It runs as a Kubernetes pod containing a supervisor +process, an L7 proxy, and the agent. + +### Supervisor + +The supervisor is the sandbox's init process. It establishes all isolation +boundaries before starting the agent: + +1. **Fetch credentials** from the gateway for all attached providers. +2. **Set up the network namespace.** The sandbox gets its own network stack + with no default route. All outbound traffic is redirected through the proxy. +3. **Apply Landlock** filesystem restrictions based on the policy. +4. **Apply seccomp** filters to restrict available system calls. +5. **Start the L7 proxy** in the sandbox's network namespace. +6. **Start the SSH server** for interactive access. +7. **Start the agent** as a child process with credentials injected as + environment variables. + +### L7 Proxy + +Every outbound TCP connection from any process in the sandbox is routed through +the proxy. For each connection, the proxy: + +1. **Resolves the calling binary** via `/proc//exe`, ancestor process + walking, and `/proc//cmdline`. +2. **Queries the policy engine** with the destination host, port, and resolved + binary path. +3. **Acts on the decision** --- allow the connection directly, hand it to the + privacy router for inference routing, or deny it. See + [How the Proxy Evaluates Connections](../safety-and-privacy/network-access-rules.md#how-the-proxy-evaluates-connections) + for the full decision model. + +For endpoints configured with `protocol: rest` and `tls: terminate`, the proxy +performs full L7 inspection: it decrypts TLS, reads the HTTP method and path, +evaluates access rules, then re-encrypts and forwards the request. + +## Policy Engine - CLI -- "gRPC / HTTPS" --> SERVER - CLI -- "SSH over HTTP CONNECT" --> SERVER - SERVER -- "CRUD + Watch" --> DB - SERVER -- "Create / Delete Pods" --> SBX - SUPERVISOR -- "Fetch Policy + Credentials" --> SERVER - SUPERVISOR -- "Spawn + Restrict" --> CHILD - CHILD -- "All network traffic" --> PROXY - PROXY -- "Evaluate request" --> OPA - PROXY -- "Allowed traffic only" --> HOSTS - PROXY -- "Inference reroute" --> SERVER - SERVER -- "Proxied inference" --> BACKEND +The policy engine is the definition and enforcement layer for filesystem, +network, and process constraints. Defense in depth enforces policies from the +application layer down to infrastructure and kernel layers. + +The engine evaluates policies compiled from the sandbox's policy YAML. It is +queried synchronously by the proxy on every outbound connection. Policy updates +delivered via hot-reload are compiled and loaded without restarting the proxy. + +## Privacy Router + +The privacy router is a privacy-aware LLM routing layer that keeps sensitive +context on sandbox compute and routes based on cost/privacy policy. + +When the policy engine determines that a connection should be inspected for +inference, the privacy router: + +1. Reads the intercepted HTTP request. +2. Checks whether the method and path match a recognized inference API pattern + (`/v1/chat/completions`, `/v1/completions`, `/v1/messages`). +3. Selects a route whose `routing_hint` appears in the sandbox policy's + `allowed_routes`. +4. Strips the original authorization header. +5. Injects the route's API key and model ID. +6. Forwards the request to the route's backend URL. + +The router refreshes its route list periodically from the gateway, so routes +created with `nemoclaw inference create` become available without restarting +sandboxes. + +## Remote Deployment + +NemoClaw can deploy the cluster to a remote host via SSH. This is useful for +shared team environments or running sandboxes on machines with more resources. + +### Deploy + +```console +$ nemoclaw cluster admin deploy --remote user@host --ssh-key ~/.ssh/id_rsa +``` + +The CLI connects to the remote machine over SSH, installs k3s, deploys the +NemoClaw control plane, and registers the cluster locally. The remote machine +needs Docker installed. + +### Tunnel + +After deploying to a remote host, set up a tunnel for CLI access: + +```console +$ nemoclaw cluster admin tunnel ``` -## Component Summary - -| Component | Description | -|-----------|-------------| -| **CLI** (`nemoclaw`) | Primary user interface. Manages clusters, sandboxes, providers, and inference routes. | -| **Gateway** | Central control plane. Provides gRPC and HTTP APIs, manages sandbox lifecycle in Kubernetes, stores data in SQLite/Postgres. | -| **Sandbox Supervisor** | Runs inside each sandbox pod. Sets up isolation (Landlock, seccomp, netns), runs the proxy, spawns the agent. | -| **Network Proxy** | HTTP CONNECT proxy inside the sandbox. Evaluates every outbound connection against the OPA policy. | -| **OPA Engine** | Embedded Rego policy evaluator (regorus crate). No external OPA daemon. | -| **Gator TUI** | Terminal dashboard for real-time cluster and sandbox monitoring. | - -## Container Images - -NemoClaw produces three container images: - -| Image | Purpose | -|-------|---------| -| **Sandbox** | Runs inside each sandbox pod. Contains the supervisor binary, Python runtime, and agent tooling. | -| **Gateway** | Runs the control plane. Contains the gateway binary, database migrations, and SSH client. | -| **Cluster** | Airgapped Kubernetes image with k3s, pre-loaded sandbox/gateway images, Helm charts, and API gateway. This is the single container users deploy. | - -## Communication Protocols - -| Path | Protocol | Description | -|------|----------|-------------| -| CLI to Gateway | gRPC over mTLS | Sandbox CRUD, provider management, inference routes, session creation. | -| CLI to Sandbox | SSH over HTTP CONNECT | Interactive shells, command execution, file sync. Tunneled through the gateway. | -| Sandbox to Gateway | gRPC over mTLS | Policy fetching, credential retrieval, inference bundle delivery, log push, policy status reporting. | -| Proxy to External | HTTPS | Outbound connections from the sandbox, filtered by policy. | -| Proxy to Backend | HTTP/HTTPS | Inference requests rerouted to configured backends. | - -## Project Structure - -| Path | Purpose | -|------|---------| -| `crates/` | Rust crates (CLI, gateway, sandbox, TUI, bootstrap, router, core, providers). | -| `python/` | Python SDK and bindings. | -| `proto/` | Protocol buffer definitions. | -| `deploy/` | Dockerfiles, Helm chart, Kubernetes manifests. | -| `architecture/` | Internal architecture documentation. | -| `tasks/` | `mise` task definitions. | +This establishes an SSH tunnel from your local machine to the remote cluster's +API server. All subsequent CLI commands route through this tunnel transparently. + +### Remote Architecture + +The architecture is identical to a local deployment. The only difference is +that the Docker container runs on the remote host instead of your workstation. +The CLI communicates with the gateway over the SSH tunnel. Sandbox SSH +connections are also tunneled through the gateway. diff --git a/docs/reference/cli.md b/docs/reference/cli.md index f8b0cab9..dbe014b4 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -5,175 +5,187 @@ # CLI Reference -The `nemoclaw` CLI (also available as `ncl`) is the primary interface for managing sandboxes, providers, inference routes, and clusters. - -:::{tip} -The CLI has comprehensive built-in help. Use `nemoclaw --help` at any level to discover commands and flags. -::: - -## Global Options - -| Flag | Description | -|------|-------------| -| `-v`, `--verbose` | Increase verbosity (`-v` = info, `-vv` = debug, `-vvv` = trace). | -| `-c`, `--cluster ` | Cluster to operate on (also via `NEMOCLAW_CLUSTER` env var). | +Complete command reference for the `nemoclaw` CLI. Every subcommand, flag, and option is documented here. ## Command Tree -``` -nemoclaw (ncl) +```text +nemoclaw ├── cluster -│ ├── status # Check gateway connectivity -│ ├── use # Set active cluster -│ ├── list # List all clusters +│ ├── status +│ ├── use +│ ├── list │ └── admin -│ ├── deploy [opts] # Provision or restart cluster -│ ├── stop [opts] # Stop cluster (preserve state) -│ ├── destroy [opts] # Destroy cluster permanently -│ ├── info [--name] # Show deployment details -│ └── tunnel [opts] # SSH tunnel for kubectl access +│ ├── deploy +│ ├── stop +│ ├── destroy +│ ├── info +│ └── tunnel ├── sandbox -│ ├── create [opts] [-- CMD...] # Create sandbox and connect -│ ├── get # Show sandbox details -│ ├── list [opts] # List sandboxes -│ ├── delete ... # Delete sandboxes -│ ├── connect # SSH into sandbox -│ ├── sync {--up|--down} # Sync files -│ ├── logs [opts] # View/stream logs -│ ├── ssh-config # Print SSH config block +│ ├── create +│ ├── get +│ ├── list +│ ├── delete +│ ├── connect +│ ├── sync +│ ├── logs +│ ├── ssh-config │ ├── forward -│ │ ├── start [-d] # Start port forward -│ │ ├── stop # Stop port forward -│ │ └── list # List active forwards -│ ├── image -│ │ └── push [opts] # Build and push custom image +│ │ ├── start +│ │ ├── stop +│ │ └── list │ └── policy -│ ├── set --policy # Update live policy -│ ├── get [--full] # Show current policy -│ └── list # Policy revision history +│ ├── set +│ ├── get +│ └── list ├── provider -│ ├── create --name --type [opts] # Create provider -│ ├── get # Show provider details -│ ├── list [opts] # List providers -│ ├── update --type [opts] # Update provider -│ └── delete ... # Delete providers +│ ├── create +│ ├── get +│ ├── list +│ ├── update +│ └── delete ├── inference -│ ├── create [opts] # Create inference route -│ ├── update [opts] # Update inference route -│ ├── delete ... # Delete inference routes -│ └── list [opts] # List inference routes -├── gator # Launch TUI -└── completions # Generate shell completions +│ ├── create +│ ├── update +│ ├── delete +│ └── list +├── gator +└── completions ``` ## Cluster Commands -### `nemoclaw cluster admin deploy` - -Provision or start a cluster (local or remote). - -| Flag | Default | Description | -|------|---------|-------------| -| `--name ` | `nemoclaw` | Cluster name. | -| `--remote ` | — | SSH destination for remote deployment. | -| `--ssh-key ` | — | SSH private key for remote deployment. | -| `--port ` | 8080 | Host port mapped to gateway. | -| `--kube-port [PORT]` | — | Expose K8s control plane on host port. | - -### `nemoclaw cluster admin stop` - -Stop a cluster container (preserves state for later restart). - -### `nemoclaw cluster admin destroy` - -Destroy a cluster and all its state permanently. - -### `nemoclaw cluster admin info` - -Show deployment details: endpoint, kubeconfig path, kube port, remote host. - -### `nemoclaw cluster admin tunnel` +Manage the NemoClaw runtime cluster. -Start or print an SSH tunnel for kubectl access to a remote cluster. +| Command | Description | +|---|---| +| `nemoclaw cluster status` | Show the health and status of the active cluster. | +| `nemoclaw cluster use ` | Set the active cluster. All subsequent commands target this cluster. | +| `nemoclaw cluster list` | List all registered clusters. | +| `nemoclaw cluster admin deploy` | Deploy a new cluster. Add `--remote user@host` for remote deployment. | +| `nemoclaw cluster admin stop` | Stop the active cluster, preserving state. | +| `nemoclaw cluster admin destroy` | Permanently remove the cluster and all its data. | +| `nemoclaw cluster admin info` | Show detailed information about the cluster. | +| `nemoclaw cluster admin tunnel` | Set up a kubectl tunnel to a remote cluster. | ## Sandbox Commands -### `nemoclaw sandbox create [OPTIONS] [-- COMMAND...]` - -Create a sandbox, wait for readiness, then connect or execute the trailing command. +Create and manage isolated agent execution environments. + +| Command | Description | +|---|---| +| `nemoclaw sandbox create` | Create a new sandbox. See flag reference below. | +| `nemoclaw sandbox get ` | Show detailed information about a sandbox. | +| `nemoclaw sandbox list` | List all sandboxes in the active cluster. | +| `nemoclaw sandbox delete ` | Delete one or more sandboxes by name. | +| `nemoclaw sandbox connect ` | Open an interactive SSH session into a running sandbox. | +| `nemoclaw sandbox sync ` | Sync files between host and sandbox. Use `--up` or `--down`. | +| `nemoclaw sandbox logs ` | View sandbox logs. Use `--tail` for streaming, `--source` and `--level` to filter. | +| `nemoclaw sandbox ssh-config ` | Print SSH config for a sandbox. Append to `~/.ssh/config` for VS Code Remote-SSH. | +| `nemoclaw sandbox forward start ` | Forward a sandbox port to the host. Add `-d` for background mode. | +| `nemoclaw sandbox forward stop ` | Stop an active port forward. | +| `nemoclaw sandbox forward list` | List all active port forwards. | +| `nemoclaw sandbox policy set ` | Apply or update a policy on a running sandbox. Pass `--policy `. | +| `nemoclaw sandbox policy get ` | Show the active policy for a sandbox. Add `--full` for the complete policy with metadata. | +| `nemoclaw sandbox policy list ` | List all policy versions applied to a sandbox, with status. | + +### `sandbox create` Flags | Flag | Description | -|------|-------------| -| `--name ` | Sandbox name (auto-generated if omitted). | -| `--image ` | Custom container image (BYOC). | -| `--sync` | Sync local git-tracked files to `/sandbox`. | -| `--keep` | Keep sandbox alive after command exits. | -| `--provider ` | Provider to attach (repeatable). | -| `--policy ` | Path to custom policy YAML. | -| `--forward ` | Forward local port to sandbox (implies `--keep`). | -| `--remote ` | SSH destination for auto-bootstrap. | +|---|---| +| `--name` | Assign a human-readable name to the sandbox. Auto-generated if omitted. | +| `--provider` | Attach a credential provider. Repeatable for multiple providers. | +| `--policy` | Path to a policy YAML file to apply at creation time. | +| `--sync` | Sync local files into the sandbox before running. | +| `--keep` | Keep the sandbox alive after the trailing command exits. | +| `--forward` | Forward a local port into the sandbox at startup. | +| `--from` | Build from a community sandbox name, local Dockerfile directory, or container image reference. | +| `-- ` | The command to run inside the sandbox. Everything after `--` is passed as the agent command. | -### `nemoclaw sandbox logs ` +## Provider Commands -| Flag | Default | Description | -|------|---------|-------------| -| `-n ` | 200 | Number of log lines. | -| `--tail` | — | Stream live logs. | -| `--since ` | — | Logs from this duration ago (e.g., `5m`, `1h`). | -| `--source ` | `all` | Filter: `gateway`, `sandbox`, or `all`. | -| `--level ` | — | Minimum level: `error`, `warn`, `info`, `debug`, `trace`. | +Manage credential providers that inject secrets into sandboxes. -### `nemoclaw sandbox sync {--up|--down} [dest]` +| Command | Description | +|---|---| +| `nemoclaw provider create` | Create a new credential provider. See flag reference below. | +| `nemoclaw provider get ` | Show details of a provider. | +| `nemoclaw provider list` | List all providers in the active cluster. | +| `nemoclaw provider update ` | Update a provider's credentials or configuration. | +| `nemoclaw provider delete ` | Delete a provider. | -Sync files to/from a sandbox. +### `provider create` Flags -### `nemoclaw sandbox forward start ` +| Flag | Description | +|---|---| +| `--name` | Name for the provider. | +| `--type` | Provider type: `claude`, `codex`, `opencode`, `github`, `gitlab`, `nvidia`, `generic`, `outlook`. | +| `--from-existing` | Discover credentials from your current shell environment variables. | +| `--credential` | Set a credential explicitly. Format: `KEY=VALUE` or bare `KEY` to read from env. Repeatable. | +| `--config` | Set a configuration value. Format: `KEY=VALUE`. Repeatable. | -Start forwarding a local port to a sandbox. `-d` runs in background. +## Inference Commands -## Policy Commands +Manage inference routes that intercept and reroute LLM API calls from userland code. -### `nemoclaw sandbox policy set --policy ` +| Command | Description | +|---|---| +| `nemoclaw inference create` | Create a new inference route. See flag reference below. | +| `nemoclaw inference update ` | Update an existing route's configuration. | +| `nemoclaw inference delete ` | Delete an inference route. | +| `nemoclaw inference list` | List all inference routes in the active cluster. | -Update the policy on a live sandbox. Only dynamic fields can change at runtime. +### `inference create` Flags | Flag | Description | -|------|-------------| -| `--wait` | Wait for sandbox to confirm policy is loaded. | -| `--timeout ` | Timeout for `--wait` (default: 60). | +|---|---| +| `--routing-hint` | Short label that identifies this route (e.g., `local`, `nvidia`, `staging`). Referenced by `allowed_routes` in sandbox policies. | +| `--base-url` | Base URL of the inference backend (e.g., `https://vllm.internal:8000`). | +| `--model-id` | Model identifier to send to the backend (e.g., `meta/llama-3.1-8b`). | +| `--api-key` | API key for authenticating with the backend. | +| `--protocol` | API protocol: `openai` or `anthropic`. Defaults to `openai`. | +| `--disabled` | Create the route in a disabled state. | -### `nemoclaw sandbox policy get ` +## NemoClaw Terminal -| Flag | Description | -|------|-------------| -| `--rev ` | Show a specific revision (default: latest). | -| `--full` | Print full policy as YAML (round-trips with `--policy`). | +`nemoclaw gator` launches the NemoClaw Terminal, a dashboard that shows sandbox +status, live logs, and policy decisions in a single view. Navigate with `j`/`k`, +press `f` to follow live output, `s` to filter by source, and `q` to quit. -### `nemoclaw sandbox policy list ` +See {doc}`/sandboxes/terminal` for the full guide — including how to read log +entries, diagnose blocked connections, and interpret inference interception. -Show policy revision history. +## Environment Variables -## Provider Commands +| Variable | Description | +|---|---| +| `NEMOCLAW_CLUSTER` | Name of the cluster to operate on. Overrides the active cluster set by `nemoclaw cluster use`. | +| `NEMOCLAW_SANDBOX_POLICY` | Default path to a policy YAML file. When set, `nemoclaw sandbox create` uses this policy if no `--policy` flag is provided. | -### `nemoclaw provider create --name --type ` +## Shell Completions -| Flag | Description | -|------|-------------| -| `--from-existing` | Discover credentials from local machine. | -| `--credential KEY[=VALUE]` | Credential pair (repeatable). Bare `KEY` reads from env var. | -| `--config KEY=VALUE` | Config key/value pair (repeatable). | +Generate shell completion scripts for tab completion: -Supported types: `claude`, `opencode`, `codex`, `generic`, `nvidia`, `gitlab`, `github`, `outlook`. +```console +$ nemoclaw completions bash +$ nemoclaw completions zsh +$ nemoclaw completions fish +``` -## Inference Commands +Pipe the output to your shell's config file: -### `nemoclaw inference create` +```console +$ nemoclaw completions zsh >> ~/.zshrc +$ source ~/.zshrc +``` -| Flag | Description | -|------|-------------| -| `--routing-hint ` (required) | Routing hint for policy matching. | -| `--base-url ` (required) | Backend endpoint URL. | -| `--model-id ` (required) | Model identifier. | -| `--api-key ` | API key for the endpoint. | -| `--protocol ` | Protocol (auto-detected if omitted, repeatable). | -| `--disabled` | Create in disabled state. | +## Self-Teaching + +Every command and subcommand includes built-in help. Use `--help` at any level to see available subcommands, flags, and usage examples: + +```console +$ nemoclaw --help +$ nemoclaw sandbox --help +$ nemoclaw sandbox create --help +$ nemoclaw cluster admin --help +``` diff --git a/docs/reference/policy-schema.md b/docs/reference/policy-schema.md index 62715ec7..4654662b 100644 --- a/docs/reference/policy-schema.md +++ b/docs/reference/policy-schema.md @@ -5,185 +5,208 @@ # Policy Schema Reference -This is the complete YAML schema for NemoClaw sandbox policies. For a guide on using policies, see [Policies](../security/policies.md). +Complete field reference for the sandbox policy YAML. Each field is documented with its type, whether it is required, and whether it is static (locked at sandbox creation) or dynamic (hot-reloadable on a running sandbox). -## Full Schema +## Top-Level Structure + +```yaml +version: 1 +filesystem_policy: { ... } +landlock: { ... } +process: { ... } +network_policies: { ... } +inference: { ... } +``` + +| Field | Type | Required | Category | Description | +|---|---|---|---|---| +| `version` | integer | Yes | -- | Policy schema version. Must be `1`. | +| `filesystem_policy` | object | No | Static | Controls which directories the agent can read and write. | +| `landlock` | object | No | Static | Configures Landlock LSM enforcement behavior. | +| `process` | object | No | Static | Sets the user and group the agent process runs as. | +| `network_policies` | map | No | Dynamic | Declares which binaries can reach which network endpoints. | +| `inference` | object | No | Dynamic | Controls which inference routing backends are available. | + +Static fields are set at sandbox creation time. Changing them requires destroying and recreating the sandbox. Dynamic fields can be updated on a running sandbox with `nemoclaw sandbox policy set` and take effect without restarting. + +## `version` + +| Field | Type | Required | Description | +|---|---|---|---| +| `version` | integer | Yes | Schema version number. Currently must be `1`. | + +## `filesystem_policy` + +**Category:** Static + +Controls filesystem access inside the sandbox. Paths not listed in either `read_only` or `read_write` are inaccessible. + +| Field | Type | Required | Description | +|---|---|---|---| +| `include_workdir` | bool | No | When `true`, automatically adds the agent's working directory to `read_write`. | +| `read_only` | list of strings | No | Paths the agent can read but not modify. Typically system directories like `/usr`, `/lib`, `/etc`. | +| `read_write` | list of strings | No | Paths the agent can read and write. Typically `/sandbox` (working directory) and `/tmp`. | + +Example: ```yaml filesystem_policy: - read_only: # List of paths — read-only access (Landlock) + include_workdir: true + read_only: - /usr - - /etc - /lib - read_write: # List of paths — read-write access (auto-created, chowned) + - /proc + - /dev/urandom + - /etc + read_write: - /sandbox - /tmp + - /dev/null +``` -landlock: - compatibility: best_effort # best_effort | hard_requirement +## `landlock` -process: - run_as_user: sandbox # Username or UID - run_as_group: sandbox # Group name or GID +**Category:** Static -network_policies: # Map of named network policy entries - : - endpoints: - - host: # Destination hostname - port: # Destination port (integer) - l7: # Optional — L7 inspection config - tls_mode: terminate # terminate - enforcement_mode: enforce # enforce | audit - access: # read-only | read-write | full (expands to rules) - rules: # Explicit HTTP rules (mutually exclusive with access) - - method: # HTTP method (GET, POST, PUT, DELETE, etc.) - path_pattern: # URL path pattern (glob) - binaries: - - path_patterns: # List of glob patterns for binary paths - - "**/git" - - "/usr/bin/curl" +Configures [Landlock LSM](https://docs.kernel.org/security/landlock.html) enforcement at the kernel level. Landlock provides mandatory filesystem access control below what UNIX permissions allow. -inference: - allowed_routes: # List of routing hint names - - local - - cloud +| Field | Type | Required | Values | Description | +|---|---|---|---|---| +| `compatibility` | string | No | `best_effort`, `hard_requirement` | How NemoClaw handles kernel ABI differences. `best_effort` uses the highest Landlock ABI the host kernel supports. `hard_requirement` fails if the required ABI is unavailable. | + +Example: + +```yaml +landlock: + compatibility: best_effort ``` -## Field Reference +## `process` -### `filesystem_policy` +**Category:** Static -Controls directory-level access enforced by the Linux Landlock LSM. +Sets the OS-level identity for the agent process inside the sandbox. | Field | Type | Required | Description | -|-------|------|----------|-------------| -| `read_only` | `list[string]` | No | Paths the agent can read but not write. | -| `read_write` | `list[string]` | No | Paths the agent can read and write. Directories are created and ownership is set to the `run_as_user` automatically. | - -**Note:** The working directory (`--workdir`, default `/sandbox`) is automatically added to `read_write` unless `include_workdir` is set to `false`. +|---|---|---|---| +| `run_as_user` | string | No | The user name or UID the agent process runs as. Default: `sandbox`. | +| `run_as_group` | string | No | The group name or GID the agent process runs as. Default: `sandbox`. | -### `landlock` +Example: -| Field | Type | Default | Description | -|-------|------|---------|-------------| -| `compatibility` | `string` | `best_effort` | `best_effort` — use the best available Landlock ABI version. `hard_requirement` — fail startup if the required ABI is not available. | +```yaml +process: + run_as_user: sandbox + run_as_group: sandbox +``` -### `process` +## `network_policies` -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `run_as_user` | `string` | No | Username or UID the child process runs as. | -| `run_as_group` | `string` | No | Group name or GID the child process runs as. | +**Category:** Dynamic -### `network_policies` +A map of named network policy entries. Each entry declares a set of endpoints and a set of binaries. Only the listed binaries are permitted to connect to the listed endpoints. The map key is a logical identifier; the `name` field inside the entry is the display name used in logs. -A map where each key is a policy name and each value defines endpoints and allowed binaries. - -#### Endpoint Fields +### Network Policy Entry | Field | Type | Required | Description | -|-------|------|----------|-------------| -| `host` | `string` | Yes | Destination hostname to match. | -| `port` | `integer` | Yes | Destination port to match. | -| `l7` | `object` | No | L7 inspection configuration (see below). | - -#### L7 Fields +|---|---|---|---| +| `name` | string | No | Display name for the policy entry. Used in log output. Defaults to the map key. | +| `endpoints` | list of endpoint objects | Yes | Hosts and ports this entry permits. | +| `binaries` | list of binary objects | Yes | Executables allowed to connect to these endpoints. | -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `tls_mode` | `string` | Yes | Must be `terminate` — the proxy terminates TLS and inspects plaintext HTTP. | -| `enforcement_mode` | `string` | No | `enforce` (default) — block non-matching requests. `audit` — log violations but allow traffic. | -| `access` | `string` | No | Preset: `read-only`, `read-write`, or `full`. Mutually exclusive with `rules`. | -| `rules` | `list[object]` | No | Explicit HTTP rules. Mutually exclusive with `access`. | +### Endpoint Object -#### L7 Rule Fields +Each endpoint defines a reachable destination and optional inspection rules. | Field | Type | Required | Description | -|-------|------|----------|-------------| -| `method` | `string` | Yes | HTTP method (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`, `HEAD`, `OPTIONS`). | -| `path_pattern` | `string` | Yes | URL path pattern (glob matching). | +|---|---|---|---| +| `host` | string | Yes | Hostname or IP address. Supports wildcards: `*.example.com` matches any subdomain. | +| `port` | integer | Yes | TCP port number. | +| `protocol` | string | No | Set to `rest` to enable L7 (HTTP) inspection. Omit for L4-only (TCP passthrough). | +| `tls` | string | No | TLS handling mode. `terminate` decrypts TLS at the proxy for inspection. `passthrough` forwards encrypted traffic without inspection. Only relevant when `protocol` is `rest`. | +| `enforcement` | string | No | `enforce` actively blocks disallowed requests. `audit` logs violations but allows traffic through. | +| `access` | string | No | HTTP access level. One of `read-only`, `read-write`, or `full`. See table below. Mutually exclusive with `rules`. | +| `rules` | list of rule objects | No | Fine-grained per-method, per-path allow rules. Mutually exclusive with `access`. | -#### Access Presets +#### Access Levels -| Preset | Expands To | -|--------|-----------| -| `read-only` | `GET`, `HEAD`, `OPTIONS` | -| `read-write` | `GET`, `HEAD`, `OPTIONS`, `POST`, `PUT`, `PATCH`, `DELETE` | -| `full` | All HTTP methods | +| Value | Allowed HTTP Methods | +|---|---| +| `full` | All methods and paths. | +| `read-only` | `GET`, `HEAD`, `OPTIONS`. | +| `read-write` | `GET`, `HEAD`, `OPTIONS`, `POST`, `PUT`, `PATCH`. | -#### Binary Fields - -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `path_patterns` | `list[string]` | Yes | Glob patterns matched against the full path of the requesting executable. | +#### Rule Object -### `inference` +Used when `access` is not set. Each rule explicitly allows a method and path combination. | Field | Type | Required | Description | -|-------|------|----------|-------------| -| `allowed_routes` | `list[string]` | No | List of routing hint names. Routes are created via `nemoclaw inference create`. | +|---|---|---|---| +| `allow.method` | string | Yes | HTTP method to allow (e.g., `GET`, `POST`). | +| `allow.path` | string | Yes | URL path pattern. Supports `*` and `**` glob syntax. | -## Static vs. Dynamic Fields +Example with rules: -| Category | Fields | Updatable at Runtime? | -|----------|--------|----------------------| -| **Static** | `filesystem_policy`, `landlock`, `process` | No — immutable after creation. | -| **Dynamic** | `network_policies`, `inference` | Yes — updated via `nemoclaw sandbox policy set`. | +```yaml +rules: + - allow: + method: GET + path: /**/info/refs* + - allow: + method: POST + path: /**/git-upload-pack +``` -## Example: Development Policy +### Binary Object -```yaml -filesystem_policy: - read_only: - - /usr - - /etc - - /lib - - /lib64 - - /bin - - /sbin - read_write: - - /sandbox - - /tmp - - /home/sandbox +Identifies an executable that is permitted to use the associated endpoints. -landlock: - compatibility: best_effort +| Field | Type | Required | Description | +|---|---|---|---| +| `path` | string | Yes | Filesystem path to the executable. Supports glob patterns with `*` and `**`. For example, `/sandbox/.vscode-server/**` matches any executable under that directory tree. | -process: - run_as_user: sandbox - run_as_group: sandbox +### Full Example +```yaml network_policies: - github: + github_rest_api: + name: github-rest-api endpoints: - - host: github.com - port: 443 - host: api.github.com port: 443 + protocol: rest + tls: terminate + enforcement: enforce + access: read-only binaries: - - path_patterns: ["**/git"] - - path_patterns: ["**/ssh"] - - path_patterns: ["**/curl"] - - anthropic: + - path: /usr/local/bin/claude + - path: /usr/bin/node + - path: /usr/bin/gh + npm_registry: + name: npm-registry endpoints: - - host: api.anthropic.com + - host: registry.npmjs.org port: 443 binaries: - - path_patterns: ["**/claude"] - - path_patterns: ["**/node"] + - path: /usr/bin/npm + - path: /usr/bin/node +``` - pypi: - endpoints: - - host: pypi.org - port: 443 - - host: files.pythonhosted.org - port: 443 - binaries: - - path_patterns: ["**/pip"] - - path_patterns: ["**/python*"] +## `inference` + +**Category:** Dynamic + +Controls which inference routing backends userland code may access. The `allowed_routes` list names route types that the privacy router will accept. Traffic matching an inference API pattern that targets a route type not in this list is denied. +| Field | Type | Required | Description | +|---|---|---|---| +| `allowed_routes` | list of strings | No | Routing hint labels (e.g., `local`, `nvidia`, `staging`) that this sandbox may use. Must match the `routing_hint` of inference routes created with `nemoclaw inference create`. | + +Example: + +```yaml inference: allowed_routes: - local + - nvidia ``` diff --git a/docs/safety-and-privacy/index.md b/docs/safety-and-privacy/index.md new file mode 100644 index 00000000..3c8ada70 --- /dev/null +++ b/docs/safety-and-privacy/index.md @@ -0,0 +1,50 @@ + + +# About Safety and Privacy + +NemoClaw wraps every sandbox in four independent protection layers. No single +point of failure can compromise your environment --- each layer covers gaps the +others cannot. + +```{mermaid} +graph TB + subgraph runtime["NemoClaw Runtime"] + direction TB + + subgraph layers["Protection Layers"] + direction TB + + fs["Filesystem — Landlock LSM"] + net["Network — Proxy + Policy Engine"] + proc["Process — seccomp + Unprivileged User"] + inf["Inference — Privacy Router"] + + subgraph sandbox["Sandbox"] + agent(["AI Agent"]) + end + end + end + + agent -- "read /sandbox ✔" --> fs + agent -- "read /etc/shadow ✘" --> fs + agent -- "curl approved.com ✔" --> net + agent -- "curl evil.com ✘" --> net + agent -- "sudo install pkg ✘" --> proc + agent -- "call api.openai.com" --> inf + inf -- "reroute → your backend ✔" --> net +``` + +You control all four layers through a single YAML policy. Network and inference +rules are hot-reloadable on a running sandbox; filesystem and process +restrictions are locked at creation time. + +- **{doc}`security-model`** --- threat scenarios (data exfiltration, credential + theft, unauthorized API calls, privilege escalation) and how NemoClaw + addresses each one. +- **{doc}`policies`** --- author policies, monitor for blocked actions, and + iterate on rules without restarting sandboxes. +- **{doc}`network-access-rules`** --- configure endpoint rules, binary matching, + L7 inspection, and access presets. diff --git a/docs/safety-and-privacy/network-access-rules.md b/docs/safety-and-privacy/network-access-rules.md new file mode 100644 index 00000000..5224db7b --- /dev/null +++ b/docs/safety-and-privacy/network-access-rules.md @@ -0,0 +1,215 @@ + + +# Network Access Rules + +Every outbound connection from a sandbox passes through NemoClaw's transparent +proxy. Nothing leaves the sandbox directly. The proxy identifies which binary +initiated the connection, evaluates the active policy, and decides what happens +next. + +## How the Proxy Evaluates Connections + +Each outbound connection resolves to one of three outcomes: + +| Outcome | When it applies | What happens | +|------------------------|-----------------------------------------------------------------------------|-----------------------------------------------------------------------------| +| **Allow** | A `network_policies` entry matches the destination host *and* the calling binary. | Traffic flows directly to the destination. The agent's own API key is used. | +| **InspectForInference**| No network policy matches, but `inference.allowed_routes` is configured. | The proxy intercepts the connection and hands it to the privacy router, which reroutes it to a configured backend. The route's API key is used. | +| **Deny** | No network policy matches and no inference route applies. | The connection is blocked. The calling process receives a 403 or connection reset. | + +:::{note} +This is the most important distinction in NemoClaw's network model. + +**Agent traffic** is the coding agent (Claude, opencode, Codex) calling its own API to get completions. This traffic matches a `network_policies` entry because the policy declares both the endpoint (for example, `api.anthropic.com:443`) and the binary (for example, `/usr/local/bin/claude`). The proxy allows it through directly. The agent's own API key --- injected by the provider --- is used as-is. + +**Userland traffic** is code that the agent *writes* making inference calls. A Python script calling the OpenAI-compatible API, a data pipeline hitting an LLM endpoint, a test harness querying a model. This traffic does *not* match any network policy because the calling binary (`/usr/bin/python3`) is not listed in the agent's policy entry. The proxy intercepts it, the privacy router reroutes it to a configured backend, and the route's API key is substituted in. The agent's code never touches your real API key. +::: + +```{mermaid} +flowchart TD + A["Outbound connection from sandbox"] --> B["Proxy resolves calling binary\n(/proc/pid/exe, ancestors, cmdline)"] + B --> C{"Network policy matches\n(endpoint + binary)?"} + C -- Yes --> D["Allow: forward directly\nto destination"] + C -- No --> E{"Inference routes\nconfigured?"} + E -- Yes --> F["InspectForInference:\nTLS terminate, check for\ninference pattern"] + F --> G{"Matches inference\npattern?"} + G -- Yes --> H["Route to configured\ninference backend"] + G -- No --> I["Deny: 403"] + E -- No --> I +``` + +## Structure of a Network Policy Entry + +Each entry in the `network_policies` section pairs a set of endpoints with a set of binaries. Only the listed binaries can connect to the listed endpoints: + +```yaml +network_policies: + my_rule: + name: my-rule + endpoints: + - host: api.example.com + port: 443 + protocol: rest + tls: terminate + enforcement: enforce + access: full + binaries: + - path: /usr/local/bin/my-agent +``` + +The key (`my_rule`) is a logical name for reference. The `name` field is the human-readable label that appears in logs and the NemoClaw Terminal. + +## Endpoints + +Each endpoint entry controls access to a single host-port combination. See [Endpoint Object](../reference/policy-schema.md#endpoint-object) for the full field reference. + +The `access` field provides presets: `full` (all methods), `read-only` (`GET`, `HEAD`, `OPTIONS`), or `read-write` (`GET`, `HEAD`, `OPTIONS`, `POST`, `PUT`, `PATCH`). + +### Custom Rules + +When access presets are not granular enough, define explicit allow rules. Each rule specifies a method and a path pattern: + +```yaml +endpoints: + - host: github.com + port: 443 + protocol: rest + tls: terminate + enforcement: enforce + rules: + - allow: + method: GET + path: /**/info/refs* + - allow: + method: POST + path: /**/git-upload-pack +``` + +This example allows Git fetch operations (read-only clone and pull) while blocking push operations. Path patterns use glob syntax. + +If a request does not match any rule, it is denied (in `enforce` mode) or logged (in `audit` mode). + +## Binaries + +The `binaries` list specifies which executables are permitted to use the endpoint. Each entry has a `path` field that the proxy matches against the calling process. + +The proxy resolves the calling binary through several mechanisms, evaluated in order: + +| Match type | Example | Description | +|-------------------|---------|-------------| +| Exact path | `/usr/local/bin/claude` | Matches the binary at exactly this path. | +| Ancestor process | `/usr/local/bin/claude` | Matches if any ancestor in the process tree has this path. A Node.js subprocess spawned by Claude matches a `claude` entry. | +| Cmdline path | `/usr/local/bin/opencode` | Matches against `/proc/pid/cmdline` for interpreted languages where the `exe` link points to the interpreter. | +| Glob pattern | `/sandbox/.vscode-server/**` | Matches any executable under the directory tree. | + +```yaml +binaries: + - path: /usr/local/bin/claude + - path: /usr/bin/node + - path: /sandbox/.vscode-server/** +``` + +## L7 Inspection + +To inspect HTTPS traffic at the HTTP level, you need both `protocol: rest` and `tls: terminate` on the endpoint: + +```yaml +endpoints: + - host: api.example.com + port: 443 + protocol: rest + tls: terminate + enforcement: enforce + access: full +``` + +With both fields set, the proxy terminates the TLS connection, decrypts the HTTP request, evaluates it against the `access` preset or custom `rules`, and re-encrypts before forwarding to the destination. + +:::{warning} +Without `tls: terminate` on port 443, the proxy cannot decrypt the traffic. L7 rules (`access`, `rules`) are not evaluated because the HTTP payload is encrypted. The connection is handled at L4 only --- allowed or denied based on host and port, with no HTTP-level access control. +::: + +### Bare Endpoints (L4-Only) + +Endpoints declared without `protocol` or `tls` are L4-only: + +```yaml +endpoints: + - host: registry.npmjs.org + port: 443 +``` + +The proxy allows the TCP connection through to the destination without decrypting or inspecting the payload. Use L4-only entries for non-HTTP traffic, package registries where you need connectivity but not method-level control, or endpoints where TLS termination is not desired. + +:::{warning} +With L4-only rules, you have no control over *what* is sent to the endpoint --- only *whether* the connection is allowed. Any binary listed in the entry can send any data to the host. If you need to restrict HTTP methods or paths, add `protocol: rest` and `tls: terminate`. +::: + +## Enforcement Modes + +Each endpoint can operate in one of two enforcement modes: + +| Mode | Behavior on violation | +|-----------|-----------------------| +| `enforce` | Blocks the request and returns HTTP 403 to the calling process. The violation is logged. | +| `audit` | Logs the violation but forwards the traffic to the destination. The agent is not interrupted. | + +:::{tip} +Start with `enforcement: audit` when developing a new policy. Audit mode shows you what *would* be blocked without actually breaking the agent. Once the policy is correct and you have confirmed that no legitimate traffic is flagged, switch to `enforcement: enforce`. +::: + +## Putting It Together + +Here is a realistic policy snippet for an agent that needs to reach its own API, clone Git repositories (read-only), and install npm packages: + +```yaml +network_policies: + agent_api: + name: agent-api + endpoints: + - host: api.anthropic.com + port: 443 + protocol: rest + tls: terminate + enforcement: enforce + access: full + binaries: + - path: /usr/local/bin/claude + - path: /usr/bin/node + + github: + name: github + endpoints: + - host: github.com + port: 443 + protocol: rest + tls: terminate + enforcement: enforce + rules: + - allow: + method: GET + path: /**/info/refs* + - allow: + method: POST + path: /**/git-upload-pack + binaries: + - path: /usr/bin/git + + npm_registry: + name: npm-registry + endpoints: + - host: registry.npmjs.org + port: 443 + binaries: + - path: /usr/bin/npm + - path: /usr/bin/node + - path: /usr/local/bin/npm + - path: /usr/local/bin/node +``` + +## Next Steps + +- [Write Sandbox Policies](policies.md) --- the full iterative workflow for authoring, testing, and updating policies. diff --git a/docs/safety-and-privacy/policies.md b/docs/safety-and-privacy/policies.md new file mode 100644 index 00000000..629ad617 --- /dev/null +++ b/docs/safety-and-privacy/policies.md @@ -0,0 +1,226 @@ + + +# Write Sandbox Policies + +This guide covers how to author, iterate, and manage sandbox policies that control what an agent can do inside a NemoClaw sandbox. You will learn to create sandboxes with custom policies, monitor denied traffic to discover missing rules, and push policy updates without restarting the sandbox. + +## Policy Structure + +A policy is a YAML document with five sections. Static fields (`filesystem_policy`, `landlock`, `process`) are locked at sandbox creation and require recreation to change. Dynamic fields (`network_policies`, `inference`) are hot-reloadable on a running sandbox. + +```yaml +version: 1 + +# --- STATIC FIELDS (require sandbox recreation to change) --- + +filesystem_policy: + # Directories the agent can read but not modify. + read_only: + - /usr + - /lib + - /proc + - /dev/urandom + - /etc + - /var/log + # Directories the agent can read and write. + read_write: + - /sandbox # the agent's working directory + - /tmp + - /dev/null + +landlock: + # How NemoClaw applies Landlock LSM enforcement. + # "best_effort" uses the highest Landlock ABI the host kernel supports. + # "strict" requires a specific ABI version and fails if unavailable. + compatibility: best_effort + +process: + # The OS user and group the agent process runs as inside the sandbox. + # "sandbox" is a non-root user created in the container image. + run_as_user: sandbox + run_as_group: sandbox + +# --- DYNAMIC FIELDS (hot-reloadable on a running sandbox) --- + +network_policies: + # Each key is a logical name for a set of allowed connections. + claude_api: + endpoints: + - host: api.anthropic.com + port: 443 + protocol: rest # enables L7 (HTTP) inspection + tls: terminate # proxy decrypts TLS to inspect traffic + enforcement: enforce # actively enforce access rules + access: full # allow all HTTP methods and paths + binaries: + # Only these binaries may connect to the endpoints above. + - path: /usr/local/bin/claude + - path: /usr/bin/node + +inference: + # Which inference route types userland code is allowed to use. + allowed_routes: + - local +``` + +See the [Policy Schema Reference](../reference/policy-schema.md) for every field, type, and default value. + +## Default Policy + +NemoClaw ships a built-in default policy designed for Claude Code. It covers Claude's API endpoints, telemetry hosts, GitHub access, and VS Code marketplace traffic out of the box. + +| Agent | Default policy coverage | What you need to do | +|---|---|---| +| Claude Code | Full | Nothing --- works out of the box | +| opencode | Partial | Add `opencode.ai` endpoint and opencode binary paths. | +| Codex | None | Provide a complete custom policy with OpenAI endpoints and Codex binary paths. | + +:::{important} +If you run a non-Claude agent without a custom policy, the agent's API calls will be denied by the proxy. You must provide a policy that declares the agent's endpoints and binaries. +::: + +## Create a Sandbox with a Custom Policy + +Pass a policy YAML file when creating the sandbox: + +```console +$ nemoclaw sandbox create --policy ./my-policy.yaml --keep -- claude +``` + +The `--keep` flag keeps the sandbox running after the initial command exits, which is useful when you plan to iterate on the policy. + +To avoid passing `--policy` every time, set a default policy via environment variable: + +```console +$ export NEMOCLAW_SANDBOX_POLICY=./my-policy.yaml +$ nemoclaw sandbox create --keep -- claude +``` + +The CLI uses the policy from `NEMOCLAW_SANDBOX_POLICY` whenever `--policy` is not explicitly provided. + +## The Policy Iteration Loop + +Policy authoring is an iterative process. You start with a minimal policy, observe what the agent needs, and refine the rules until everything works. This is the core workflow: + +```{mermaid} +flowchart TD + A["1. Create sandbox with initial policy"] --> B["2. Monitor logs for denied actions"] + B --> C["3. Pull current policy"] + C --> D["4. Modify the policy YAML"] + D --> E["5. Push updated policy"] + E --> F["6. Verify the new revision loaded"] + F --> B +``` + +### Step 1: Create the sandbox with your initial policy + +```console +$ nemoclaw sandbox create --policy ./my-policy.yaml --keep -- claude +``` + +### Step 2: Monitor logs for denied actions + +In a second terminal, tail the sandbox logs and look for `action: deny` entries: + +```console +$ nemoclaw sandbox logs --tail --source sandbox +``` + +Each deny entry shows the blocked host, port, calling binary, and reason. This tells you exactly what the agent tried to reach and why it was blocked. + +Alternatively, run `nemoclaw gator` for the NemoClaw Terminal, a live dashboard +that shows status and logs in a single view. See {doc}`/sandboxes/terminal` for +how to read log entries and diagnose what's being blocked. + +:::{tip} +The NemoClaw Terminal is especially useful during policy iteration — you can +watch deny entries appear in real time as the agent hits blocked endpoints, then +push an updated policy without leaving the terminal. +::: + +### Step 3: Pull the current policy + +Export the running policy to a file: + +```console +$ nemoclaw sandbox policy get --full > current-policy.yaml +``` + +:::{warning} +The `--full` output includes a metadata header with `Version`, `Hash`, and `Status` lines that are not valid YAML. Strip these lines before re-submitting the file as a policy update, or the push will fail. +::: + +### Step 4: Modify the policy YAML + +Edit `current-policy.yaml` to address the denied actions you observed. Common changes include: + +- Adding endpoints to `network_policies` entries +- Adding binary paths to existing endpoint rules +- Creating new named policy entries for new destinations +- Adjusting `access` levels or adding custom `rules` +- Updating `inference.allowed_routes` + +### Step 5: Push the updated policy + +```console +$ nemoclaw sandbox policy set --policy current-policy.yaml --wait +``` + +The `--wait` flag blocks until the policy engine processes the update. Exit codes: + +| Exit code | Meaning | +|-----------|---------| +| `0` | Policy loaded successfully | +| `1` | Policy failed validation | +| `124` | Timed out waiting for the policy engine | + +### Step 6: Verify the new revision loaded + +```console +$ nemoclaw sandbox policy list +``` + +Check that the latest revision shows status `loaded`. If it shows `failed`, review the error message and go back to Step 4. + +### Step 7: Repeat + +Return to Step 2. Monitor logs, observe new denied actions (or confirm everything works), and refine the policy until the agent operates correctly within the rules you have set. + +## Policy Revision History + +Every `policy set` creates a new revision. You can inspect the full revision history: + +```console +$ nemoclaw sandbox policy list --limit 50 +``` + +To retrieve a specific revision: + +```console +$ nemoclaw sandbox policy get --rev 3 --full +``` + +### Revision Statuses + +| Status | Meaning | +|--------------|---------| +| `pending` | The revision has been submitted and is awaiting processing by the policy engine. | +| `loaded` | The revision passed validation and is the active policy for the sandbox. | +| `failed` | The revision failed validation. The previous good revision remains active. | +| `superseded` | A newer revision has been loaded, replacing this one. | + +## Safety Properties + +**Last-known-good.** +If a new policy revision fails validation, the previous successfully loaded policy stays active. A bad push does not break a running sandbox --- the agent continues operating under the last good policy. + +**Idempotent.** +Submitting the same policy content again does not create a new revision. The CLI detects that the content has not changed and returns without modifying the revision history. + +## Next Steps + +- [Network Access Rules](network-access-rules.md) --- how the proxy evaluates connections, endpoint allowlists, binary matching, and enforcement modes. +- {doc}`../reference/policy-schema` --- complete field reference for the policy YAML. diff --git a/docs/safety-and-privacy/security-model.md b/docs/safety-and-privacy/security-model.md new file mode 100644 index 00000000..d064d591 --- /dev/null +++ b/docs/safety-and-privacy/security-model.md @@ -0,0 +1,87 @@ + + +# The Security Model + +When an AI agent runs with unrestricted access to your system, it can read any +file, reach any network host, call any API with your credentials, and install +arbitrary software. NemoClaw's security model exists to prevent all of that. + +:::{note} +NemoClaw uses defense in depth. Four independent protection layers --- filesystem, +network, process, and inference --- work together so that no single point of +failure can compromise your environment. +::: + +## What Happens Without Protection + +Autonomous agents are powerful, but power without boundaries is risk. Here are +four concrete threat scenarios and how NemoClaw addresses each one. + +### Data Exfiltration + +**Without protection:** +The agent writes a script that reads your source code and uploads it to an +external server using `curl`. + +**With NemoClaw:** +The network policy blocks all outbound connections except to hosts you have +explicitly approved. The `curl` command to an unapproved destination is denied +at the proxy before the request ever leaves the sandbox. + +--- + +### Credential Theft + +**Without protection:** +The agent reads `~/.ssh/id_rsa`, `~/.aws/credentials`, or other sensitive files +from your home directory and exfiltrates them. + +**With NemoClaw:** +Landlock filesystem restrictions limit the agent to declared paths. The agent +can access `/sandbox`, `/tmp`, and read-only system directories --- but not your +home directory, SSH keys, cloud credentials, or anything else outside the +policy. + +--- + +### Unauthorized API Calls + +**Without protection:** +The agent code calls `api.openai.com` with your API key, sending proprietary +data to a third-party inference provider you did not approve. + +**With NemoClaw:** +The privacy router intercepts outbound API calls and reroutes them to a +backend you control --- a local model, an NVIDIA endpoint, or your own +deployment. The agent's code does not need to change; the rerouting is +transparent. Your data never reaches an unauthorized provider. + +--- + +### Privilege Escalation + +**Without protection:** +The agent runs `sudo apt install` to install packages, modifies `/etc/passwd`, +or uses raw sockets to scan your internal network. + +**With NemoClaw:** +The agent runs as an unprivileged user with seccomp filters that block +dangerous system calls. Landlock prevents writes outside allowed paths. There +is no `sudo`, no `setuid`, and no path to elevated privileges. + +:::{important} +All four layers work together. No single layer is sufficient on its own. +Filesystem restrictions do not prevent network exfiltration. Network policies do +not prevent local privilege escalation. Process restrictions do not control +where inference traffic goes. Defense in depth means every layer covers gaps +that the others cannot. +::: + +## Next Steps + +- {doc}`policies` --- write and iterate on the policy YAML that configures all four layers +- {doc}`network-access-rules` --- configure network rules, binary matching, and TLS inspection +- {doc}`../inference/index` --- set up private inference backends diff --git a/docs/sandboxes/community-sandboxes.md b/docs/sandboxes/community-sandboxes.md new file mode 100644 index 00000000..6c869a9a --- /dev/null +++ b/docs/sandboxes/community-sandboxes.md @@ -0,0 +1,93 @@ + + +# Community Sandboxes + +Use pre-built sandboxes from the NemoClaw Community catalog, or contribute your +own. + +## What Are Community Sandboxes + +Community sandboxes are ready-to-use environments published in the +[NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) repository. +Each sandbox bundles a Dockerfile, policy, optional skills, and startup scripts +into a single package that you can launch with one command. + +## Current Catalog + +| Sandbox | Description | +|---|---| +| `base` | Foundational image with system tools and dev environment | +| `openclaw` | Open agent manipulation and control | +| `sdg` | Synthetic data generation workflows | +| `simulation` | General-purpose simulation sandboxes | + +## Use a Community Sandbox + +Launch a community sandbox by name with the `--from` flag: + +```console +$ nemoclaw sandbox create --from openclaw +``` + +When you pass `--from` with a community sandbox name, the CLI: + +1. Resolves the name against the + [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) repository. +2. Pulls the Dockerfile, policy, skills, and any startup scripts. +3. Builds the container image locally. +4. Creates the sandbox with the bundled configuration applied. + +You end up with a running sandbox whose image, policy, and tooling are all +preconfigured by the community package. + +### Other Sources + +The `--from` flag also accepts: + +- **Local directory paths** --- point to a directory on disk that contains a + Dockerfile and optional policy/skills: + + ```console + $ nemoclaw sandbox create --from ./my-sandbox-dir + ``` + +- **Container image references** --- use an existing container image directly: + + ```console + $ nemoclaw sandbox create --from my-registry.example.com/my-image:latest + ``` + +## Contribute a Community Sandbox + +Each community sandbox is a directory under `sandboxes/` in the +[NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) repository. +At minimum, a sandbox directory must contain: + +- `Dockerfile` --- defines the container image +- `README.md` --- describes the sandbox and how to use it + +Optional files: + +- `policy.yaml` --- default policy applied when the sandbox launches +- `skills/` --- agent skill definitions bundled with the sandbox +- Startup scripts --- any scripts the Dockerfile or entrypoint invokes + +To contribute, fork the repository, add your sandbox directory, and open a pull +request. See the repository's +[CONTRIBUTING.md](https://github.com/NVIDIA/NemoClaw-Community/blob/main/CONTRIBUTING.md) +for submission guidelines. + +:::{note} +The community catalog is designed to grow. If you have built a sandbox that +supports a particular workflow --- data processing, simulation, code review, +or anything else --- consider contributing it back so others can use it. +::: + +## Next Steps + +- {doc}`create-and-manage` --- full sandbox lifecycle management +- {doc}`custom-containers` --- build a fully custom container with BYOC +- {doc}`../safety-and-privacy/policies` --- customize the policy applied to any sandbox diff --git a/docs/sandboxes/create-and-manage.md b/docs/sandboxes/create-and-manage.md index 63b4080d..4cbc8825 100644 --- a/docs/sandboxes/create-and-manage.md +++ b/docs/sandboxes/create-and-manage.md @@ -5,114 +5,213 @@ # Create and Manage Sandboxes -## Creating a Sandbox +This page walks you through the full sandbox lifecycle: creating, inspecting, connecting to, monitoring, and deleting sandboxes. -The simplest form creates a sandbox with defaults and drops you into an interactive shell: +## Sandbox Lifecycle + +Every sandbox moves through a defined set of phases: + +| Phase | Description | +|---|---| +| **Provisioning** | The runtime is setting up the sandbox environment, injecting credentials, and applying your policy. | +| **Ready** | The sandbox is running. The agent process is active and all isolation layers are enforced. You can connect, sync files, and view logs. | +| **Error** | Something went wrong during provisioning or execution. Check logs with `nemoclaw sandbox logs` for details. | +| **Deleting** | The sandbox is being torn down. Resources are released and credentials are purged. | + +## The NemoClaw Runtime + +Sandboxes run inside a lightweight runtime cluster that NemoClaw manages for +you. The cluster runs as a [k3s](https://k3s.io/) Kubernetes distribution +inside a Docker container on your machine. + +**You do not need to set this up manually.** The first time you run a command +that needs a cluster (such as `nemoclaw sandbox create`), the CLI provisions +one automatically. This is the "Runtime ready" line you see in the output. +Subsequent commands reuse the existing cluster. + +For teams or when you need more resources, you can deploy the cluster to a +remote host instead of your local machine: ```console -$ nemoclaw sandbox create +$ nemoclaw cluster admin deploy --remote user@host ``` -### With an Agent Tool +See [Remote Deployment](../reference/architecture.md) for +details. If you have multiple clusters (local and remote), switch between them +with `nemoclaw cluster use `. See the +[CLI Reference](../reference/cli.md#cluster-commands) for the full command set. + +## Prerequisites -When the trailing command is a recognized tool, the CLI auto-creates the required provider from local credentials: +- NemoClaw CLI installed (`pip install nemoclaw`) +- Docker running on your machine + +## Create a Sandbox + +The simplest way to create a sandbox is to specify a trailing command: ```console $ nemoclaw sandbox create -- claude -$ nemoclaw sandbox create -- codex ``` -### With Options +The CLI bootstraps the runtime (if this is your first run), discovers your +credentials, applies the default policy, and drops you into the sandbox. + +You can customize creation with flags like `--name`, `--provider`, `--policy`, +`--sync`, `--keep`, `--forward`, and `--from`. See the +[CLI Reference](../reference/cli.md) for the full flag list. + +A fully specified creation command might look like: ```console $ nemoclaw sandbox create \ - --name my-sandbox \ - --provider my-github \ - --provider my-claude \ - --policy ./my-policy.yaml \ - --sync \ - -- claude + --name dev \ + --provider my-claude \ + --policy policy.yaml \ + --sync \ + --keep \ + -- claude ``` -| Flag | Description | -|------|-------------| -| `--name ` | Sandbox name (auto-generated if omitted). | -| `--provider ` | Provider to attach (repeatable). | -| `--policy ` | Custom policy YAML. Uses the built-in default if omitted. | -| `--sync` | Push local git-tracked files to `/sandbox` in the container. | -| `--keep` | Keep sandbox alive after the command exits. | -| `--forward ` | Forward a local port to the sandbox (implies `--keep`). | -| `--image ` | Custom container image (see [Custom Containers](custom-containers.md)). | - -### Auto-Bootstrap +:::{tip} +Use `--keep` to keep the sandbox running after the trailing command exits. +This is especially useful when you are iterating on a policy or want to +reconnect later from another terminal or VS Code. +::: -If no cluster is running, `sandbox create` offers to bootstrap one automatically. This is equivalent to running `nemoclaw cluster admin deploy` first. +## List and Inspect Sandboxes -## Listing Sandboxes +List all sandboxes: ```console $ nemoclaw sandbox list ``` -| Flag | Description | -|------|-------------| -| `--limit ` | Maximum number of sandboxes to return (default: 100). | -| `--offset ` | Pagination offset. | -| `--names` | Print only sandbox names. | - -## Inspecting a Sandbox +Get detailed information about a specific sandbox: ```console $ nemoclaw sandbox get my-sandbox ``` -Shows sandbox details including ID, name, namespace, phase, and policy. +## Connect to a Sandbox -## Connecting to a Sandbox +### Interactive SSH + +Open an SSH session into a running sandbox: ```console $ nemoclaw sandbox connect my-sandbox ``` -Opens an interactive SSH session. All provider credentials are available as environment variables inside the sandbox. - ### VS Code Remote-SSH +Export the sandbox SSH configuration and append it to your SSH config: + ```console $ nemoclaw sandbox ssh-config my-sandbox >> ~/.ssh/config ``` -Then use VS Code's Remote-SSH extension to connect to the host `my-sandbox`. +Then open VS Code, install the **Remote - SSH** extension if you have not +already, and connect to the host named `my-sandbox`. + +## View Logs -## Viewing Logs +Stream sandbox logs: ```console $ nemoclaw sandbox logs my-sandbox ``` -| Flag | Description | -|------|-------------| -| `-n ` | Number of log lines (default: 200). | -| `--tail` | Stream live logs. | -| `--since ` | Show logs from this duration ago (e.g., `5m`, `1h`). | -| `--source ` | Filter by source: `gateway`, `sandbox`, or `all` (repeatable). | -| `--level ` | Minimum level: `error`, `warn`, `info`, `debug`, `trace`. | +Use flags to filter and follow output: -### Monitoring for Denied Actions +| Flag | Purpose | Example | +|---|---|---| +| `--tail` | Stream logs in real time | `nemoclaw sandbox logs my-sandbox --tail` | +| `--source` | Filter by log source | `--source sandbox` | +| `--level` | Filter by severity | `--level warn` | +| `--since` | Show logs from a time window | `--since 5m` | -When iterating on a sandbox policy, watch for denied network requests: +Combine flags to narrow in on what you need: ```console -$ nemoclaw sandbox logs my-sandbox --tail --source sandbox +$ nemoclaw sandbox logs my-sandbox --tail --source sandbox --level warn --since 5m ``` -Denied actions include the destination host/port, the binary that attempted the connection, and the reason for denial. +:::{tip} +For a real-time dashboard that combines sandbox status and logs in one view, +run `nemoclaw gator`. See {doc}`terminal` for details on reading log entries and +diagnosing blocked connections. +::: -## Deleting Sandboxes +## Sync Files + +Push files from your host into the sandbox: + +```console +$ nemoclaw sandbox sync my-sandbox --up ./src /sandbox/src +``` + +Pull files from the sandbox to your host: + +```console +$ nemoclaw sandbox sync my-sandbox --down /sandbox/output ./local +``` + +:::{note} +You can also sync files at creation time with the `--sync` flag on +`nemoclaw sandbox create`. +::: + +## Port Forwarding + +Forward a port from the sandbox to your host machine. This runs in the +foreground by default: + +```console +$ nemoclaw sandbox forward start 8080 my-sandbox +``` + +Add `-d` to run the forward in the background: + +```console +$ nemoclaw sandbox forward start 8080 my-sandbox -d +``` + +List active port forwards: + +```console +$ nemoclaw sandbox forward list +``` + +Stop a port forward: + +```console +$ nemoclaw sandbox forward stop 8080 my-sandbox +``` + +:::{note} +You can set up port forwarding at creation time with the `--forward` flag on +`nemoclaw sandbox create`, which is convenient when you know upfront that +your workload exposes a service. +::: + +## Delete Sandboxes + +Delete a sandbox by name: ```console $ nemoclaw sandbox delete my-sandbox -$ nemoclaw sandbox delete sandbox-1 sandbox-2 sandbox-3 ``` -Deleting a sandbox also stops any active port forwards. +You can delete multiple sandboxes in a single command: + +```console +$ nemoclaw sandbox delete sandbox-a sandbox-b sandbox-c +``` + +## Next Steps + +- {doc}`community-sandboxes` --- use pre-built sandboxes from the community catalog +- {doc}`providers` --- create and attach credential providers +- {doc}`custom-containers` --- build and run your own container image +- {doc}`../safety-and-privacy/policies` --- control what the agent can access \ No newline at end of file diff --git a/docs/sandboxes/custom-containers.md b/docs/sandboxes/custom-containers.md index 2a989967..a5af5042 100644 --- a/docs/sandboxes/custom-containers.md +++ b/docs/sandboxes/custom-containers.md @@ -3,13 +3,13 @@ SPDX-License-Identifier: Apache-2.0 --> -# Custom Containers (BYOC) +# Custom Containers -You can run any Linux container image as a sandbox while keeping the NemoClaw supervisor in control of security enforcement. This is called Bring Your Own Container (BYOC). +You can run any Linux container image as a sandbox while keeping the NemoClaw supervisor in control of security enforcement. ## How It Works -When you specify `--image`, the server activates **supervisor bootstrap mode**. The `navigator-sandbox` supervisor binary is side-loaded from the default sandbox image via a Kubernetes init container, then mounted read-only into your custom container. This means you do not need to build the supervisor into your image. +When you specify `--image`, the server activates supervisor bootstrap mode. The `navigator-sandbox` supervisor binary is side-loaded from the default sandbox image via a Kubernetes init container, then mounted read-only into your custom container. This means you do not need to build the supervisor into your image. ```{mermaid} flowchart TB diff --git a/docs/sandboxes/file-sync.md b/docs/sandboxes/file-sync.md deleted file mode 100644 index ad92774b..00000000 --- a/docs/sandboxes/file-sync.md +++ /dev/null @@ -1,41 +0,0 @@ - - -# File Sync - -NemoClaw supports syncing files between your local machine and a running sandbox. File sync uses tar-over-SSH through the gateway tunnel — no direct network access to the sandbox pod is needed. - -## Sync at Create Time - -The `--sync` flag pushes local git-tracked files into the sandbox at `/sandbox` before the agent starts: - -```console -$ nemoclaw sandbox create --sync -- claude -``` - -This is useful when you want the agent to work with your current project files. - -## Manual Sync - -### Push Files to a Sandbox - -```console -$ nemoclaw sandbox sync my-sandbox --up ./src /sandbox/src -``` - -This copies local `./src` into `/sandbox/src` inside the sandbox. - -### Pull Files from a Sandbox - -```console -$ nemoclaw sandbox sync my-sandbox --down /sandbox/output ./local-output -``` - -This copies `/sandbox/output` from the sandbox to `./local-output` on your machine. - -### Default Destinations - -- `--up` defaults to `/sandbox` if no destination is specified. -- `--down` defaults to the current directory (`.`). diff --git a/docs/sandboxes/index.md b/docs/sandboxes/index.md index 942a3333..a6e649e6 100644 --- a/docs/sandboxes/index.md +++ b/docs/sandboxes/index.md @@ -36,7 +36,7 @@ Every sandbox is governed by a policy that defines what the agent can do, ensuri - **Inference routing** — which AI model backends are available, keeping inference traffic private. - **Process privileges** — the user and group the agent runs as, limiting blast radius. -See [Safety & Privacy](../security/index.md) for details. +See [Safety & Privacy](../safety-and-privacy/index.md) for details. ## Quick Reference @@ -54,8 +54,9 @@ See [Safety & Privacy](../security/index.md) for details. ## In This Section -- [Create and Manage](create-and-manage.md) — sandbox CRUD, connecting, and log viewing. -- [Providers](providers.md) — managing external credentials privately. -- [Custom Containers](custom-containers.md) — bring your own container images. -- [File Sync](file-sync.md) — pushing and pulling files to/from sandboxes. -- [Port Forwarding](port-forwarding.md) — forwarding local ports into sandboxes. +- [Create and Manage](create-and-manage.md): About creating, listing, inspecting, and connecting to sandboxes. +- [Providers](providers.md): About managing external credentials privately. +- [Custom Containers](custom-containers.md): About bringing your own container images. +- [Community Sandboxes](community-sandboxes.md): About using pre-built sandboxes from the NemoClaw Community catalog. +- [Port Forwarding](port-forwarding.md): About forwarding local ports into sandboxes. +- [Terminal](terminal.md): About using NemoClaw Terminal to monitor sandbox activity and diagnose blocked connections. diff --git a/docs/sandboxes/providers.md b/docs/sandboxes/providers.md index 5f42a09b..92f7ca6f 100644 --- a/docs/sandboxes/providers.md +++ b/docs/sandboxes/providers.md @@ -52,10 +52,6 @@ A bare key (without `=VALUE`) reads the value from the environment variable of t $ nemoclaw provider create --name my-api --type generic --credential API_KEY ``` -### Auto-Creation During Sandbox Create - -When you run `nemoclaw sandbox create -- claude`, the CLI detects that a `claude` provider is needed, discovers local credentials, and creates the provider automatically. You are prompted interactively if credentials are missing. - ## Managing Providers ```console @@ -75,6 +71,12 @@ $ nemoclaw sandbox create --provider my-claude --provider my-github -- claude Each attached provider's credentials are injected as environment variables into the sandbox. If multiple providers define the same environment variable, the first provider's value wins. +:::{warning} +Providers cannot be added to a running sandbox. If you need to attach an +additional provider, delete the sandbox and recreate it with all required +providers specified. +::: + ## Privacy & Safety NemoClaw manages credentials with a privacy-first design: @@ -83,3 +85,71 @@ NemoClaw manages credentials with a privacy-first design: - **Runtime-only injection** — credentials are fetched at runtime by the sandbox supervisor, minimizing exposure surface. - **No credential leakage** — the CLI never displays credential values in its output. - **Strict key validation** — only credential keys that are valid environment variable names (`^[A-Za-z_][A-Za-z0-9_]*$`) are injected; invalid keys are silently skipped. + +### Auto-Discovery Shortcut + +When the trailing command in `nemoclaw sandbox create` is a recognized tool name +--- `claude`, `codex`, or `opencode` --- the CLI auto-creates the required +provider from your local credentials if one does not already exist. You do not +need to create the provider separately: + +```console +$ nemoclaw sandbox create -- claude +``` + +This detects `claude` as a known tool, finds your `ANTHROPIC_API_KEY`, creates +a provider, attaches it to the sandbox, and launches Claude Code. + +## How Credentials Flow + +Credentials follow a secure path from your machine into the agent process. + +```{mermaid} +flowchart LR + A["You create a provider"] --> B["Attach provider\nto sandbox at creation"] + B --> C["Sandbox starts"] + C --> D["Supervisor fetches\ncredentials from gateway"] + D --> E["Credentials injected into\nagent process + SSH sessions"] +``` + +1. **You create a provider** with credentials from your environment or + specified explicitly. +2. **You attach the provider to a sandbox** at creation time using the + `--provider` flag (one or more providers can be attached). +3. **The sandbox starts.** The supervisor process initializes. +4. **The supervisor fetches credentials** from the NemoClaw gateway at runtime. + Credentials are not stored in the sandbox specification --- they are + retrieved on demand. +5. **Credentials are injected** into the agent process as environment variables. + They are also available in SSH sessions when you connect to the sandbox. + +:::{warning} +Credentials are never stored in the sandbox container specification. They are +fetched at runtime by the supervisor and held only in process memory. This +means credentials are not visible in container inspection, image layers, or +environment dumps of the container spec. +::: + +## Supported Types + +| Type | Environment Variables Injected | Typical Use | +|---|---|---| +| `claude` | `ANTHROPIC_API_KEY`, `CLAUDE_API_KEY` | Claude Code, Anthropic API | +| `codex` | `OPENAI_API_KEY` | OpenAI Codex | +| `opencode` | `OPENCODE_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY` | opencode tool | +| `github` | `GITHUB_TOKEN`, `GH_TOKEN` | GitHub API, `gh` CLI | +| `gitlab` | `GITLAB_TOKEN`, `GLAB_TOKEN`, `CI_JOB_TOKEN` | GitLab API, `glab` CLI | +| `nvidia` | `NVIDIA_API_KEY` | NVIDIA API Catalog | +| `generic` | User-defined | Any service with custom credentials | +| `outlook` | *(none --- no auto-discovery)* | Microsoft Outlook integration | + +:::{tip} +Use the `generic` type for any service not listed above. You define the +environment variable names and values yourself with `--credential`. +::: + +## Next Steps + +- {doc}`create-and-manage` --- full sandbox lifecycle management +- {doc}`custom-containers` --- use providers with custom container images +- {doc}`/safety-and-privacy/security-model` --- why credential isolation matters \ No newline at end of file diff --git a/docs/sandboxes/terminal.md b/docs/sandboxes/terminal.md new file mode 100644 index 00000000..0b30263e --- /dev/null +++ b/docs/sandboxes/terminal.md @@ -0,0 +1,106 @@ + + +# Terminal + +NemoClaw Terminal is a terminal dashboard that displays sandbox status and live activity in a single view. Use it to monitor agent behavior, diagnose blocked connections, and observe inference interception in real time. + +```console +$ nemoclaw gator +``` + +## Sandbox Status + +The status pane at the top of the dashboard displays the following sandbox metadata: + +- **Name** and **phase** (`Provisioning`, `Ready`, `Error`) +- **Image** running in the sandbox +- **Providers** attached and their available credentials +- **Age** since creation +- **Port forwards** currently active + +A phase other than `Ready` indicates the sandbox is still initializing or has encountered an error. Inspect the logs pane for details. + +## Live Log Stream + +The logs pane streams activity in real time. Outbound connections, policy decisions, and inference interceptions appear as they occur. + +Log entries originate from two sources: + +- **sandbox** — the sandbox supervisor (proxy decisions, policy enforcement, SSH connections, process lifecycle). +- **gateway** — the control plane (sandbox creation, phase changes, policy distribution). + +Press `f` to enable follow mode and auto-scroll to new entries. + +## Diagnosing Blocked Connections + +Entries with `action=deny` indicate connections blocked by policy: + +``` +22:35:19 sandbox INFO CONNECT action=deny dst_host=registry.npmjs.org dst_port=443 +``` + +Each deny entry contains the following fields: + +| Field | Description | +|---|---| +| `action=deny` | Connection was blocked by the network policy. | +| `dst_host` | Destination host the process attempted to reach. | +| `dst_port` | Destination port (typically 443 for HTTPS). | +| `src_addr` | Source address inside the sandbox. | +| `policy` | Policy rule that was evaluated, or `-` if no rule matched. | + +To resolve a blocked connection: + +1. Add the host to the network policy if the connection is legitimate. See {doc}`../safety-and-privacy/policies` for the iteration workflow. +2. Leave it blocked if the connection is unauthorized. + +## Diagnosing Inference Interception + +Entries with `action=inspect_for_inference` indicate intercepted API calls: + +``` +22:35:37 sandbox INFO CONNECT action=inspect_for_inference dst_host=integrate.api.nvidia.com dst_port=443 +22:35:37 sandbox INFO Intercepted inference request, routing locally kind=chat_completion +``` + +This sequence indicates: + +- No network policy matched the connection (the endpoint and binary combination is not in the policy). +- Inference routing is configured (`allowed_routes` is non-empty), so the proxy intercepted the call instead of denying it. +- The proxy TLS-terminated the connection, detected an inference API pattern, and routed the request through the privacy router. + +:::{note} +If these calls should go directly to the destination rather than through inference routing, the most likely cause is a binary path mismatch. The process making the HTTP call does not match any binary listed in the network policy. + +Check the log entry for the binary path, then update the `binaries` list in the policy. See {doc}`../safety-and-privacy/network-access-rules` for details on binary matching. +::: + +## Filtering and Navigation + +The dashboard provides filtering and navigation controls: + +- Press **`s`** to filter logs by source — display only `sandbox` logs (policy decisions) or only `gateway` logs (lifecycle events). +- Press **`f`** to toggle follow mode — auto-scroll to the latest entries. +- Press **`Enter`** on a log entry to open the detail view with the full message. +- Use **`j`** / **`k`** to navigate up and down the log list. + +## Keyboard Shortcuts + +| Key | Action | +|---|---| +| `j` / `k` | Navigate down / up in the log list. | +| `Enter` | Open detail view for the selected entry. | +| `g` / `G` | Jump to top / bottom. | +| `f` | Toggle follow mode (auto-scroll to new entries). | +| `s` | Open source filter (sandbox, gateway, or all). | +| `Esc` | Return to the main view / close detail view. | +| `q` | Quit. | + +## Related Topics + +- **Blocked connections** — Follow {doc}`../safety-and-privacy/policies` to pull the current policy, add the missing endpoint, and push an update without restarting the sandbox. +- **Inference interception** — See {doc}`../safety-and-privacy/network-access-rules` for the distinction between agent traffic (routed directly) and userland traffic (routed through inference routing). +- **General troubleshooting** — See {doc}`../troubleshooting/cluster-issues` for common issues and diagnostics. diff --git a/docs/security/index.md b/docs/security/index.md deleted file mode 100644 index 67364a8f..00000000 --- a/docs/security/index.md +++ /dev/null @@ -1,74 +0,0 @@ - - -# About Safety and Privacy - -NemoClaw provides defense-in-depth safety and privacy protection for AI agents through multiple independent enforcement layers. Each sandbox is governed by a declarative policy that controls what the agent can access, preventing unauthorized data access, exfiltration, and credential exposure. - -## Safety and Privacy Model - -### How NemoClaw Protects You - -Every sandbox enforces four independent protection layers: - -| Layer | Mechanism | What It Protects | -|-------|-----------|-----------------| -| **Filesystem** | Landlock LSM | Prevents agents from reading sensitive files or writing outside designated directories. Enforced by the Linux kernel. | -| **System calls** | seccomp BPF | Blocks dangerous low-level operations that could bypass safety controls (e.g., raw network socket creation). | -| **Network** | Network namespace + proxy | Prevents data exfiltration — all traffic goes through the proxy, which inspects and authorizes every connection. | -| **Process** | Privilege separation | Prevents privilege escalation — the agent runs as an unprivileged user. | - -These layers are independent — a bypass of one layer does not compromise the others. - -### Data Privacy - -All outbound network traffic from the sandbox is forced through an HTTP CONNECT proxy, ensuring no data leaves without authorization. The proxy: - -1. **Identifies the program** making each connection by inspecting `/proc` — you always know which process is sending data. -2. **Verifies binary integrity** using trust-on-first-use SHA256 hashing — if a binary is tampered with, subsequent requests are denied. -3. **Enforces least-privilege network access** using an embedded OPA engine with per-binary, per-host granularity — only the programs you authorize can reach each endpoint. -4. **Protects private infrastructure** by blocking DNS results pointing to internal IP ranges (RFC 1918, link-local, cloud metadata endpoints), preventing agents from accessing internal services. -5. **Inspects data in transit** when L7 inspection is configured — terminates TLS and examines individual HTTP requests for fine-grained data access control. - -### Credential Privacy - -Credentials are managed with a privacy-first design: - -- API keys and tokens are stored separately from sandbox definitions on the gateway. -- Credentials never appear in Kubernetes pod specs or container configuration. -- Credentials are fetched only at runtime by the sandbox supervisor and injected as environment variables. -- The CLI never displays credential values in its output. - -### Communication Security - -All communication with the NemoClaw gateway is secured by mutual TLS (mTLS). The PKI is bootstrapped automatically during cluster deployment. Every client (CLI, SDK, sandbox pods) must present a valid certificate signed by the cluster CA — there is no unauthenticated path. - -## Policy Overview - -Sandbox behavior is governed by policies written in YAML. Policies give you explicit control over: - -- **Filesystem access** — which directories are readable and writable, protecting sensitive data. -- **Network access** — which remote hosts each program can connect to, preventing data exfiltration. -- **Inference routing** — which AI model backends the sandbox can use, keeping prompts and responses private. -- **Process privileges** — the user and group the agent runs as, limiting blast radius. - -See [Policies](policies.md) for the full guide on writing and managing policies. - -### Static vs. Dynamic Fields - -Policy fields are divided into two categories: - -| Category | Fields | Updatable at Runtime? | -|----------|--------|----------------------| -| **Static** | `filesystem_policy`, `landlock`, `process` | No — applied once at startup, immutable. | -| **Dynamic** | `network_policies`, `inference` | Yes — hot-reloaded within ~30 seconds. | - -Static fields are enforced at the kernel level (Landlock, seccomp) and cannot be changed after the sandbox starts. Dynamic fields are evaluated at runtime by the OPA engine and can be updated using `nemoclaw sandbox policy set`. - -## In This Section - -- [Policies](policies.md) — writing, managing, and iterating on sandbox policies. -- [Network Access Control](network-access.md) — detailed network policy configuration. -- [Policy Schema Reference](../reference/policy-schema.md) — complete YAML schema. diff --git a/docs/security/network-access.md b/docs/security/network-access.md deleted file mode 100644 index abfb374a..00000000 --- a/docs/security/network-access.md +++ /dev/null @@ -1,148 +0,0 @@ - - -# Network Access Control - -The `network_policies` section of a sandbox policy controls which remote hosts each program in the sandbox can connect to, preventing unauthorized data exfiltration. The proxy evaluates every outbound connection against these rules — no data leaves the sandbox without explicit authorization. - -## Basic Structure - -Network policies are a map of named entries. Each entry specifies endpoints (host + port) and the binaries allowed to connect to them: - -```yaml -network_policies: - github: - endpoints: - - host: github.com - port: 443 - - host: api.github.com - port: 443 - binaries: - - path_patterns: ["**/git"] - - path_patterns: ["**/ssh"] - - anthropic: - endpoints: - - host: api.anthropic.com - port: 443 - binaries: - - path_patterns: ["**/claude"] - - path_patterns: ["**/node"] -``` - -## Endpoints - -Each endpoint specifies a host and port: - -```yaml -endpoints: - - host: api.example.com - port: 443 -``` - -The `host` field matches the hostname in the CONNECT request. The `port` field matches the destination port. - -## Binary Matching - -The `binaries` field specifies which programs are allowed to connect to the endpoints. Each binary entry uses glob patterns matched against the full path of the executable: - -```yaml -binaries: - - path_patterns: ["**/git"] # matches /usr/bin/git, /usr/local/bin/git, etc. - - path_patterns: ["**/node"] # matches any 'node' binary - - path_patterns: ["/usr/bin/curl"] # matches only this specific path -``` - -### Binary Integrity - -The proxy uses a trust-on-first-use (TOFU) model for binary verification. The first time a binary makes a network request, its SHA256 hash is recorded. If the binary changes later (indicating possible tampering), subsequent requests are denied. - -## L7 Inspection - -For endpoints that need deeper inspection, you can configure L7 (HTTP-level) rules. L7 inspection terminates TLS and inspects individual HTTP requests: - -```yaml -network_policies: - api-service: - endpoints: - - host: api.example.com - port: 443 - l7: - tls_mode: terminate - enforcement_mode: enforce - rules: - - method: GET - path_pattern: "/v1/data/*" - - method: POST - path_pattern: "/v1/submit" - binaries: - - path_patterns: ["**/curl"] -``` - -### L7 Fields - -| Field | Description | -|-------|-------------| -| `tls_mode` | `terminate` — proxy terminates TLS and inspects plaintext HTTP. | -| `enforcement_mode` | `enforce` — block requests that don't match any rule. `audit` — log violations but allow traffic. | -| `rules` | List of allowed HTTP method + path patterns. | - -### Access Presets - -Instead of listing individual rules, you can use an `access` preset: - -```yaml -network_policies: - api-service: - endpoints: - - host: api.example.com - port: 443 - l7: - tls_mode: terminate - access: read-only - binaries: - - path_patterns: ["**/curl"] -``` - -| Preset | Allowed Methods | -|--------|----------------| -| `read-only` | `GET`, `HEAD`, `OPTIONS` | -| `read-write` | `GET`, `HEAD`, `OPTIONS`, `POST`, `PUT`, `PATCH`, `DELETE` | -| `full` | All HTTP methods | - -Presets are expanded into explicit rules at policy load time. - -## SSRF Protection - -Even when a hostname is allowed by policy, the proxy resolves DNS before connecting and blocks any result that points to a private network address. This prevents SSRF attacks where an allowed hostname could be redirected to internal infrastructure. - -Blocked IP ranges include: - -- Loopback (`127.0.0.0/8`, `::1`) -- RFC 1918 private ranges (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`) -- Link-local (`169.254.0.0/16`, `fe80::/10`) -- Cloud metadata endpoints (e.g., `169.254.169.254`) - -## Network Modes - -The sandbox supports three network modes, determined at creation time: - -| Mode | Description | -|------|-------------| -| **Proxy** | All traffic goes through the policy-enforcing proxy. Activated when `network_policies` is non-empty. | -| **Block** | No network access at all. System calls for network sockets are blocked by seccomp. | -| **Allow** | Unrestricted network access. No proxy, no seccomp filtering. | - -The network mode cannot change after sandbox creation. Adding `network_policies` to a sandbox created without them (or removing all policies from a sandbox that has them) is rejected. - -## Tri-State Routing Decision - -When a connection request arrives at the proxy, the OPA engine returns one of three actions: - -| Action | Condition | Behavior | -|--------|-----------|----------| -| **Allow** | Endpoint + binary matched a `network_policies` entry. | Connection proceeds directly. | -| **Inspect for Inference** | No policy match, but `inference.allowed_routes` is non-empty. | TLS-terminate and check for inference API patterns. See [Inference Routing](../inference/index.md). | -| **Deny** | No match and no inference routing configured. | Connection is rejected. | diff --git a/docs/security/policies.md b/docs/security/policies.md deleted file mode 100644 index 8185e03d..00000000 --- a/docs/security/policies.md +++ /dev/null @@ -1,190 +0,0 @@ - - -# Policies - -Sandbox policies are YAML documents that define what an agent can do. Every sandbox has a policy — either the built-in default or a custom one provided at creation time. - -## Using Policies - -### Create a Sandbox with a Custom Policy - -```console -$ nemoclaw sandbox create --policy ./my-policy.yaml --keep -- claude -``` - -### Set a Default Policy via Environment Variable - -```console -$ export NEMOCLAW_SANDBOX_POLICY=./my-policy.yaml -$ nemoclaw sandbox create -- claude -``` - -## Policy Structure - -A policy has four top-level sections: - -```yaml -filesystem_policy: - read_only: - - /usr - - /etc - read_write: - - /sandbox - - /tmp - -landlock: - compatibility: best_effort - -process: - run_as_user: sandbox - run_as_group: sandbox - -network_policies: - github: - endpoints: - - host: github.com - port: 443 - - host: api.github.com - port: 443 - binaries: - - path_patterns: ["**/git"] - - path_patterns: ["**/ssh"] - -inference: - allowed_routes: - - local -``` - -### `filesystem_policy` (Static) - -Controls which directories the agent can access. Enforced by the Linux Landlock LSM. - -| Field | Description | -|-------|-------------| -| `read_only` | List of paths the agent can read but not write. | -| `read_write` | List of paths the agent can read and write. Directories are created and chowned automatically. | - -### `landlock` (Static) - -| Field | Description | -|-------|-------------| -| `compatibility` | `best_effort` (default) — use the best available Landlock ABI. `hard_requirement` — fail if the required ABI is not available. | - -### `process` (Static) - -| Field | Description | -|-------|-------------| -| `run_as_user` | Username or UID the agent runs as. | -| `run_as_group` | Group name or GID the agent runs as. | - -### `network_policies` (Dynamic) - -A map of named network policy entries. Each entry defines which endpoints a set of binaries can reach. See [Network Access Control](network-access.md) for the full specification. - -### `inference` (Dynamic) - -| Field | Description | -|-------|-------------| -| `allowed_routes` | List of routing hint names that this sandbox can use for inference. Routes are created separately via `nemoclaw inference create`. | - -## Live Policy Updates - -Dynamic fields (`network_policies` and `inference`) can be updated on a running sandbox without restarting it. - -### The Policy Iteration Loop - -``` -Create sandbox with initial policy - │ - ▼ - Monitor logs ◄──────────────────┐ - │ │ - ▼ │ - Observe denied actions │ - │ │ - ▼ │ - Pull current policy │ - │ │ - ▼ │ - Modify policy YAML │ - │ │ - ▼ │ - Push updated policy │ - │ │ - ▼ │ - Verify reload succeeded ─────────┘ -``` - -### Step 1: Monitor logs for denied actions - -```console -$ nemoclaw sandbox logs my-sandbox --tail --source sandbox -``` - -Look for `action: deny` log lines — these show the destination host/port, the binary that attempted the connection, and the denial reason. - -### Step 2: Pull the current policy - -```console -$ nemoclaw sandbox policy get my-sandbox --full > current-policy.yaml -``` - -The `--full` flag outputs valid YAML that can be directly re-submitted. - -### Step 3: Modify and push the updated policy - -Edit `current-policy.yaml`, then: - -```console -$ nemoclaw sandbox policy set my-sandbox --policy current-policy.yaml --wait -``` - -The `--wait` flag blocks until the sandbox confirms the policy is loaded. Exit codes: - -| Code | Meaning | -|------|---------| -| 0 | Policy loaded successfully. | -| 1 | Policy load failed. | -| 124 | Timeout (default: 60 seconds). | - -### Step 4: Verify - -```console -$ nemoclaw sandbox policy list my-sandbox -``` - -Check that the latest revision shows status `loaded`. - -## Policy Revision History - -Each policy update creates a new revision. View the history: - -```console -$ nemoclaw sandbox policy list my-sandbox --limit 50 -``` - -Fetch a specific historical revision: - -```console -$ nemoclaw sandbox policy get my-sandbox --rev 3 --full -``` - -### Revision Statuses - -| Status | Meaning | -|--------|---------| -| `pending` | Accepted by the server; not yet loaded by the sandbox. | -| `loaded` | Successfully applied by the sandbox. | -| `failed` | Sandbox attempted to load but validation failed; previous policy remains active. | -| `superseded` | A newer revision was submitted before the sandbox loaded this one. | - -## Last-Known-Good Behavior - -If a new policy version fails validation, the sandbox keeps the previous (last-known-good) policy active. This provides safe rollback semantics — a bad policy push does not break a running sandbox. - -## Idempotent Updates - -Submitting the same policy content again does not create a new revision. The CLI detects this and prints "Policy unchanged." diff --git a/docs/troubleshooting/cluster-issues.md b/docs/troubleshooting/cluster-issues.md new file mode 100644 index 00000000..c8860861 --- /dev/null +++ b/docs/troubleshooting/cluster-issues.md @@ -0,0 +1,35 @@ + + +# Cluster Issues + +Troubleshoot problems with deploying, connecting to, and running NemoClaw clusters. + +## Cluster Deploy Fails + +**Symptom:** `nemoclaw cluster admin deploy` exits with an error. + +**Check:** +1. Is Docker running? The cluster requires Docker to be active. +2. Is the port already in use? Try a different port: `--port 8081`. +3. Does a stale container exist? Destroy and redeploy: `nemoclaw cluster admin destroy && nemoclaw cluster admin deploy`. + +## Cluster Not Reachable + +**Symptom:** `nemoclaw cluster status` fails to connect. + +**Check:** +1. Is the cluster container running? `docker ps | grep nemoclaw`. +2. Was the cluster stopped? Redeploy: `nemoclaw cluster admin deploy`. +3. For remote clusters, is the SSH connection working? + +## Health Check Fails During Deploy + +**Symptom:** Deploy hangs or times out waiting for health checks. + +**Check:** +1. View container logs: `docker logs nemoclaw-cluster`. +2. Check if k3s started: the bootstrap process waits up to 180 attempts (6 minutes) for cluster readiness. +3. Look for resource constraints — k3s needs sufficient memory and disk. diff --git a/docs/troubleshooting/custom-container-issues.md b/docs/troubleshooting/custom-container-issues.md new file mode 100644 index 00000000..af81bef1 --- /dev/null +++ b/docs/troubleshooting/custom-container-issues.md @@ -0,0 +1,17 @@ + + +# Custom Container Issues + +Troubleshoot problems with building and running custom container images in sandboxes. + +## Custom Image Fails to Start + +**Symptom:** Sandbox with `--image` goes to `Error` state. + +**Check:** +1. Is the image pushed to the cluster? `nemoclaw sandbox image push --dockerfile ./Dockerfile --tag my-image`. +2. Does the image have glibc and `/proc`? Distroless / `FROM scratch` images are not supported. +3. For proxy mode, does the image have `iproute2`? Network namespace setup requires it. diff --git a/docs/troubleshooting/getting-more-information.md b/docs/troubleshooting/getting-more-information.md new file mode 100644 index 00000000..6075390e --- /dev/null +++ b/docs/troubleshooting/getting-more-information.md @@ -0,0 +1,12 @@ + + +# Getting More Information + +Use these techniques to gather additional diagnostic detail when troubleshooting. + +- Increase CLI verbosity: `nemoclaw -vvv ` for trace-level output. +- View gateway-side logs: `nemoclaw sandbox logs --source gateway`. +- View sandbox-side logs: `nemoclaw sandbox logs --source sandbox --level debug`. diff --git a/docs/troubleshooting/index.md b/docs/troubleshooting/index.md deleted file mode 100644 index ccb61fd6..00000000 --- a/docs/troubleshooting/index.md +++ /dev/null @@ -1,123 +0,0 @@ - - -# About Troubleshooting - -Common issues and how to resolve them. - -## Cluster Issues - -### Cluster Deploy Fails - -**Symptom:** `nemoclaw cluster admin deploy` exits with an error. - -**Check:** -1. Is Docker running? The cluster requires Docker to be active. -2. Is the port already in use? Try a different port: `--port 8081`. -3. Does a stale container exist? Destroy and redeploy: `nemoclaw cluster admin destroy && nemoclaw cluster admin deploy`. - -### Cluster Not Reachable - -**Symptom:** `nemoclaw cluster status` fails to connect. - -**Check:** -1. Is the cluster container running? `docker ps | grep nemoclaw`. -2. Was the cluster stopped? Redeploy: `nemoclaw cluster admin deploy`. -3. For remote clusters, is the SSH connection working? - -### Health Check Fails During Deploy - -**Symptom:** Deploy hangs or times out waiting for health checks. - -**Check:** -1. View container logs: `docker logs nemoclaw-cluster`. -2. Check if k3s started: the bootstrap process waits up to 180 attempts (6 minutes) for cluster readiness. -3. Look for resource constraints — k3s needs sufficient memory and disk. - -## Sandbox Issues - -### Sandbox Stuck in Provisioning - -**Symptom:** Sandbox shows `Provisioning` status and does not become `Ready`. - -**Check:** -1. View sandbox logs: `nemoclaw sandbox logs --source gateway`. -2. Check if the container image can be pulled. -3. For custom images, verify the image was pushed: `nemoclaw sandbox image push`. - -### Cannot Connect to Sandbox - -**Symptom:** `nemoclaw sandbox connect ` fails. - -**Check:** -1. Is the sandbox in `Ready` state? `nemoclaw sandbox get `. -2. Is SSH accessible? The tunnel goes through the gateway — verify cluster connectivity first. - -### Network Requests Denied - -**Symptom:** The agent cannot reach a remote host. - -**Check:** -1. Stream sandbox logs: `nemoclaw sandbox logs --tail --source sandbox`. -2. Look for `deny` actions — they include the destination, binary, and reason. -3. Update the policy to allow the blocked endpoint. See [Policy Iteration Loop](../security/policies.md#the-policy-iteration-loop). - -### Policy Update Fails - -**Symptom:** `nemoclaw sandbox policy set` returns an error or the status shows `failed`. - -**Check:** -1. Are you changing a static field? `filesystem_policy`, `landlock`, and `process` cannot change after creation. -2. Are you adding/removing `network_policies` to change the network mode? This is not allowed — the mode is fixed at creation. -3. Check the error message in `nemoclaw sandbox policy list `. - -## Provider Issues - -### Provider Discovery Finds No Credentials - -**Symptom:** `--from-existing` creates a provider with no credentials. - -**Check:** -1. Are the expected environment variables set? (e.g., `ANTHROPIC_API_KEY` for Claude). -2. Do the expected config files exist? (e.g., `~/.claude.json`). -3. Try explicit credentials: `--credential ANTHROPIC_API_KEY=sk-...`. - -### Sandbox Missing Credentials - -**Symptom:** Environment variables for a provider are not set inside the sandbox. - -**Check:** -1. Was the provider attached? `nemoclaw sandbox get ` — check the providers list. -2. Does the provider have credentials? `nemoclaw provider get `. -3. Are the credential keys valid env var names? Keys with dots, dashes, or spaces are silently skipped. - -## Custom Container Issues - -### Custom Image Fails to Start - -**Symptom:** Sandbox with `--image` goes to `Error` state. - -**Check:** -1. Is the image pushed to the cluster? `nemoclaw sandbox image push --dockerfile ./Dockerfile --tag my-image`. -2. Does the image have glibc and `/proc`? Distroless / `FROM scratch` images are not supported. -3. For proxy mode, does the image have `iproute2`? Network namespace setup requires it. - -## Port Forwarding Issues - -### Port Forward Not Working - -**Symptom:** `localhost:` does not connect to the sandbox service. - -**Check:** -1. Is the forward running? `nemoclaw sandbox forward list`. -2. Is the service listening on that port inside the sandbox? -3. Is the sandbox still in `Ready` state? -4. Try stopping and restarting: `nemoclaw sandbox forward stop && nemoclaw sandbox forward start -d`. - -## Getting More Information - -- Increase CLI verbosity: `nemoclaw -vvv ` for trace-level output. -- View gateway-side logs: `nemoclaw sandbox logs --source gateway`. -- View sandbox-side logs: `nemoclaw sandbox logs --source sandbox --level debug`. diff --git a/docs/troubleshooting/port-forwarding-issues.md b/docs/troubleshooting/port-forwarding-issues.md new file mode 100644 index 00000000..96efc8d2 --- /dev/null +++ b/docs/troubleshooting/port-forwarding-issues.md @@ -0,0 +1,18 @@ + + +# Port Forwarding Issues + +Troubleshoot problems with forwarding local ports into sandbox services. + +## Port Forward Not Working + +**Symptom:** `localhost:` does not connect to the sandbox service. + +**Check:** +1. Is the forward running? `nemoclaw sandbox forward list`. +2. Is the service listening on that port inside the sandbox? +3. Is the sandbox still in `Ready` state? +4. Try stopping and restarting: `nemoclaw sandbox forward stop && nemoclaw sandbox forward start -d`. diff --git a/docs/troubleshooting/provider-issues.md b/docs/troubleshooting/provider-issues.md new file mode 100644 index 00000000..ed7c473e --- /dev/null +++ b/docs/troubleshooting/provider-issues.md @@ -0,0 +1,26 @@ + + +# Provider Issues + +Troubleshoot problems with provider credential discovery and injection into sandboxes. + +## Provider Discovery Finds No Credentials + +**Symptom:** `--from-existing` creates a provider with no credentials. + +**Check:** +1. Are the expected environment variables set? (e.g., `ANTHROPIC_API_KEY` for Claude). +2. Do the expected config files exist? (e.g., `~/.claude.json`). +3. Try explicit credentials: `--credential ANTHROPIC_API_KEY=sk-...`. + +## Sandbox Missing Credentials + +**Symptom:** Environment variables for a provider are not set inside the sandbox. + +**Check:** +1. Was the provider attached? `nemoclaw sandbox get ` — check the providers list. +2. Does the provider have credentials? `nemoclaw provider get `. +3. Are the credential keys valid env var names? Keys with dots, dashes, or spaces are silently skipped. diff --git a/docs/troubleshooting/sandbox-issues.md b/docs/troubleshooting/sandbox-issues.md new file mode 100644 index 00000000..c9419f78 --- /dev/null +++ b/docs/troubleshooting/sandbox-issues.md @@ -0,0 +1,43 @@ + + +# Sandbox Issues + +Troubleshoot problems with creating, connecting to, and configuring sandboxes. + +## Sandbox Stuck in Provisioning + +**Symptom:** Sandbox shows `Provisioning` status and does not become `Ready`. + +**Check:** +1. View sandbox logs: `nemoclaw sandbox logs --source gateway`. +2. Check if the container image can be pulled. +3. For custom images, verify the image was pushed: `nemoclaw sandbox image push`. + +## Cannot Connect to Sandbox + +**Symptom:** `nemoclaw sandbox connect ` fails. + +**Check:** +1. Is the sandbox in `Ready` state? `nemoclaw sandbox get `. +2. Is SSH accessible? The tunnel goes through the gateway — verify cluster connectivity first. + +## Network Requests Denied + +**Symptom:** The agent cannot reach a remote host. + +**Check:** +1. Stream sandbox logs: `nemoclaw sandbox logs --tail --source sandbox`. +2. Look for `deny` actions — they include the destination, binary, and reason. +3. Update the policy to allow the blocked endpoint. See [Policy Iteration Loop](../safety-and-privacy/policies.md#the-policy-iteration-loop). + +## Policy Update Fails + +**Symptom:** `nemoclaw sandbox policy set` returns an error or the status shows `failed`. + +**Check:** +1. Are you changing a static field? `filesystem_policy`, `landlock`, and `process` cannot change after creation. +2. Are you adding/removing `network_policies` to change the network mode? This is not allowed — the mode is fixed at creation. +3. Check the error message in `nemoclaw sandbox policy list `. From c211edf4fbd5c4b6e4d934cedbd89d09f4b2aaf8 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 5 Mar 2026 15:21:45 -0800 Subject: [PATCH 05/39] improve observability --- docs/index.md | 20 +---- .../index.md => observability/health.md} | 67 +++++++++----- docs/observability/index.md | 90 ++++--------------- docs/observability/logs.md | 67 ++++++++++++++ 4 files changed, 133 insertions(+), 111 deletions(-) rename docs/{gator/index.md => observability/health.md} (74%) create mode 100644 docs/observability/logs.md diff --git a/docs/index.md b/docs/index.md index 28a2b412..649b556a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -137,20 +137,11 @@ Bootstrap, manage, and deploy NemoClaw clusters locally or on remote hosts via S {bdg-secondary}`How To` ::: -:::{grid-item-card} Gator TUI -:link: gator/index -:link-type: doc - -Use the keyboard-driven terminal dashboard for real-time cluster monitoring and sandbox management. -+++ -{bdg-secondary}`How To` -::: - :::{grid-item-card} Observability :link: observability/index :link-type: doc -Stream sandbox logs, audit agent activity, and monitor policy enforcement in real time. +Stream sandbox logs, audit agent activity, and monitor policy enforcement with the Gator TUI and CLI. +++ {bdg-secondary}`How To` ::: @@ -252,18 +243,13 @@ clusters/index clusters/remote-deploy ``` -```{toctree} -:caption: Gator TUI -:hidden: - -gator/index -``` - ```{toctree} :caption: Observability :hidden: observability/index +observability/logs +observability/health ``` ```{toctree} diff --git a/docs/gator/index.md b/docs/observability/health.md similarity index 74% rename from docs/gator/index.md rename to docs/observability/health.md index 870cd755..ded723dc 100644 --- a/docs/gator/index.md +++ b/docs/observability/health.md @@ -3,11 +3,34 @@ SPDX-License-Identifier: Apache-2.0 --> -# About Gator TUI +# Cluster and Sandbox Health + +NemoClaw provides two ways to monitor health: the CLI for quick checks and the Gator TUI for a live dashboard. + +## CLI + +Check cluster health: + +```console +$ nemoclaw cluster status +``` + +Shows gateway connectivity and version. + +Check sandbox status: + +```console +$ nemoclaw sandbox list +$ nemoclaw sandbox get +``` + +`sandbox list` shows all sandboxes with their current phase. `sandbox get` returns detailed information for a single sandbox, including status, image, attached providers, and policy revision. + +## Gator TUI Gator is a terminal user interface for NemoClaw, inspired by [k9s](https://k9scli.io/). Instead of typing individual CLI commands to check cluster health, list sandboxes, and manage resources, Gator gives you a real-time, keyboard-driven dashboard. -## Launching Gator +### Launching Gator ```console $ nemoclaw gator @@ -15,9 +38,9 @@ $ nemoclaw gator --cluster prod $ NEMOCLAW_CLUSTER=prod nemoclaw gator ``` -Gator inherits all CLI configuration — cluster selection, TLS settings, and verbosity flags work the same way. No separate configuration is needed. +Gator inherits all CLI configuration --- cluster selection, TLS settings, and verbosity flags work the same way. No separate configuration is needed. -## Screen Layout +### Screen Layout ``` ┌─────────────────────────────────────────────────────────────────┐ @@ -33,25 +56,25 @@ Gator inherits all CLI configuration — cluster selection, TLS settings, and ve └─────────────────────────────────────────────────────────────────┘ ``` -- **Title bar** — Gator logo, cluster name, current view, and live health status. -- **Main area** — the active view. -- **Navigation bar** — available views with shortcut keys. -- **Command bar** — appears when you press `:` (vim-style). +- **Title bar** --- Gator logo, cluster name, current view, and live health status. +- **Main area** --- the active view. +- **Navigation bar** --- available views with shortcut keys. +- **Command bar** --- appears when you press `:` (vim-style). -## Views +### Views -### Dashboard (press `1`) +#### Dashboard (press `1`) Shows your cluster at a glance: - **Cluster name** and **gateway endpoint**. -- **Health status** — polls every 2 seconds: - - `●` **Healthy** (green) — everything is running normally. - - `◐` **Degraded** (yellow) — the cluster is up but something needs attention. - - `○` **Unhealthy** (red) — the cluster is not operating correctly. +- **Health status** --- polls every 2 seconds: + - `●` **Healthy** (green) --- everything is running normally. + - `◐` **Degraded** (yellow) --- the cluster is up but something needs attention. + - `○` **Unhealthy** (red) --- the cluster is not operating correctly. - **Sandbox count**. -### Sandboxes (press `2`) +#### Sandboxes (press `2`) A live table of all sandboxes: @@ -66,9 +89,9 @@ A live table of all sandboxes: Navigate with `j`/`k` or arrow keys. -## Keyboard Controls +### Keyboard Controls -### Normal Mode +#### Normal Mode | Key | Action | |-----|--------| @@ -80,7 +103,7 @@ Navigate with `j`/`k` or arrow keys. | `q` | Quit Gator. | | `Ctrl+C` | Force quit. | -### Command Mode +#### Command Mode Press `:` to open the command bar. Type a command and press `Enter`. @@ -92,15 +115,15 @@ Press `:` to open the command bar. Type a command and press `Enter`. Press `Esc` to cancel. -## Port Forwarding +### Port Forwarding When creating a sandbox in Gator, specify ports in the **Ports** field (comma-separated, e.g., `8080,3000`). After the sandbox reaches `Ready` state, Gator automatically spawns background SSH tunnels. Forwarded ports appear in the **NOTES** column and in the sandbox detail view. -## Data Refresh +### Data Refresh -Gator polls the cluster every 2 seconds. Both cluster health and the sandbox list update automatically — no manual refresh needed. +Gator polls the cluster every 2 seconds. Both cluster health and the sandbox list update automatically --- no manual refresh needed. -## Theme +### Theme Gator uses a dark terminal theme based on the NVIDIA brand palette: diff --git a/docs/observability/index.md b/docs/observability/index.md index 4d309365..3d82c95c 100644 --- a/docs/observability/index.md +++ b/docs/observability/index.md @@ -5,81 +5,27 @@ # About Observability -NemoClaw provides log streaming and monitoring for sandboxes and the gateway. +NemoClaw provides log streaming and monitoring for sandboxes and the gateway. You can stream logs from the CLI, monitor denied actions to iterate on policies, and use the Gator TUI for a real-time dashboard. -## Sandbox Logs +::::{grid} 1 1 2 2 +:gutter: 3 -View recent logs from a sandbox: +:::{grid-item-card} Sandbox Logs +:link: logs +:link-type: doc -```console -$ nemoclaw sandbox logs my-sandbox -``` +Stream, filter, and monitor sandbox and gateway logs from the CLI. ++++ +{bdg-secondary}`How To` +::: -### Live Streaming +:::{grid-item-card} Cluster and Sandbox Health +:link: health +:link-type: doc -Stream logs in real time: +Check cluster and sandbox health from the CLI or the Gator TUI dashboard. ++++ +{bdg-secondary}`How To` +::: -```console -$ nemoclaw sandbox logs my-sandbox --tail -``` - -### Filtering - -Filter by source, level, and time range: - -```console -$ nemoclaw sandbox logs my-sandbox --tail --source sandbox --level warn -$ nemoclaw sandbox logs my-sandbox --since 5m -$ nemoclaw sandbox logs my-sandbox --source gateway --level error -``` - -| Flag | Description | -|------|-------------| -| `--tail` | Stream live logs (does not exit). | -| `--source` | Filter by source: `gateway`, `sandbox`, or `all` (repeatable). | -| `--level` | Minimum log level: `error`, `warn`, `info`, `debug`, `trace`. | -| `--since` | Show logs from this duration ago (e.g., `5m`, `1h`, `30s`). | -| `-n ` | Number of log lines to fetch (default: 200). | - -### Log Sources - -| Source | Content | -|--------|---------| -| `gateway` | Gateway-side events: sandbox lifecycle, gRPC calls, pod management. | -| `sandbox` | Sandbox-side events: proxy decisions, policy evaluation, connection allows/denies. | - -## Monitoring Denied Actions - -When iterating on sandbox policies, the most useful view is sandbox-level deny events: - -```console -$ nemoclaw sandbox logs my-sandbox --tail --source sandbox -``` - -Deny log entries include: - -- **Destination host and port** — what the agent tried to reach. -- **Binary path** — which program attempted the connection. -- **Deny reason** — why the connection was blocked (no matching policy, binary mismatch, etc.). - -This information drives the [policy iteration loop](../safety-and-privacy/policies.md#the-policy-iteration-loop). - -## Log Architecture - -Sandbox logs are pushed from the sandbox process to the gateway using a background batching layer. The sandbox collects log entries from its tracing subscriber and streams them to the gateway via gRPC in batches. The gateway stores log entries and makes them available via the CLI's `logs` command. - -This push-based model means logs are available even if you are not actively streaming — you can always retrieve recent logs after the fact. - -## Cluster Health - -### CLI - -```console -$ nemoclaw cluster status -``` - -Shows gateway connectivity and version. - -### Gator TUI - -The [Gator TUI](../gator/index.md) dashboard polls cluster health every 2 seconds, displaying real-time status: Healthy, Degraded, or Unhealthy. +:::: diff --git a/docs/observability/logs.md b/docs/observability/logs.md new file mode 100644 index 00000000..be750e74 --- /dev/null +++ b/docs/observability/logs.md @@ -0,0 +1,67 @@ + + +# Sandbox Logs + +View recent logs from a sandbox: + +```console +$ nemoclaw sandbox logs my-sandbox +``` + +## Live Streaming + +Stream logs in real time: + +```console +$ nemoclaw sandbox logs my-sandbox --tail +``` + +## Filtering + +Filter by source, level, and time range: + +```console +$ nemoclaw sandbox logs my-sandbox --tail --source sandbox --level warn +$ nemoclaw sandbox logs my-sandbox --since 5m +$ nemoclaw sandbox logs my-sandbox --source gateway --level error +``` + +| Flag | Description | +|------|-------------| +| `--tail` | Stream live logs (does not exit). | +| `--source` | Filter by source: `gateway`, `sandbox`, or `all` (repeatable). | +| `--level` | Minimum log level: `error`, `warn`, `info`, `debug`, `trace`. | +| `--since` | Show logs from this duration ago (e.g., `5m`, `1h`, `30s`). | +| `-n ` | Number of log lines to fetch (default: 200). | + +## Log Sources + +| Source | Content | +|--------|---------| +| `gateway` | Gateway-side events: sandbox lifecycle, gRPC calls, pod management. | +| `sandbox` | Sandbox-side events: proxy decisions, policy evaluation, connection allows/denies. | + +## Monitoring Denied Actions + +When iterating on sandbox policies, the most useful view is sandbox-level deny events: + +```console +$ nemoclaw sandbox logs my-sandbox --tail --source sandbox +``` + +Deny log entries include: + +- **Destination host and port** --- what the agent tried to reach. +- **Binary path** --- which program attempted the connection. +- **Deny reason** --- why the connection was blocked (no matching policy, binary mismatch, etc.). + +This information drives the [policy iteration loop](../safety-and-privacy/policies.md#the-policy-iteration-loop). + +## Log Architecture + +Sandbox logs are pushed from the sandbox process to the gateway using a background batching layer. The sandbox collects log entries from its tracing subscriber and streams them to the gateway via gRPC in batches. The gateway stores log entries and makes them available via the CLI's `logs` command. + +This push-based model means logs are available even if you are not actively streaming --- you can always retrieve recent logs after the fact. From d674bf2ee2ae91b805b641821b28b974e2308874 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 5 Mar 2026 15:47:56 -0800 Subject: [PATCH 06/39] moving pieces --- docs/about/release-notes.md | 2 +- docs/get-started/tutorials/run-opencode.md | 2 +- docs/index.md | 2 +- docs/observability/health.md | 30 +++++++++---------- docs/observability/index.md | 4 +-- docs/reference/cli.md | 4 +-- docs/resources/index.md | 4 +-- docs/safety-and-privacy/policies.md | 2 +- docs/sandboxes/create-and-manage.md | 2 +- docs/sandboxes/custom-containers.md | 10 +++---- docs/sandboxes/port-forwarding.md | 6 ++-- docs/sandboxes/terminal.md | 2 +- .../custom-container-issues.md | 2 +- 13 files changed, 36 insertions(+), 36 deletions(-) diff --git a/docs/about/release-notes.md b/docs/about/release-notes.md index 8409ba25..b262db37 100644 --- a/docs/about/release-notes.md +++ b/docs/about/release-notes.md @@ -25,7 +25,7 @@ The following table summarizes the key features included in this release. | Inference routing | Transparent interception and rerouting of OpenAI/Anthropic API calls to policy-controlled backends for inference privacy. | | Cluster bootstrap | Single-container k3s deployment with Docker as the only dependency. Supports local and remote (SSH) targets. | | CLI (`nemoclaw` / `ncl`) | Full command-line interface for cluster, sandbox, provider, and inference route management. | -| Gator TUI | Terminal dashboard for real-time cluster monitoring and sandbox management. | +| NemoClaw Terminal | Terminal dashboard for real-time cluster monitoring and sandbox management. | | BYOC | Run custom container images as sandboxes with supervisor bootstrap. | | SSH tunneling | Secure access to sandboxes through the gateway with session tokens and mTLS. | | File sync | Push and pull files to/from sandboxes via tar-over-SSH. | diff --git a/docs/get-started/tutorials/run-opencode.md b/docs/get-started/tutorials/run-opencode.md index 7c952cc0..b6e8a149 100644 --- a/docs/get-started/tutorials/run-opencode.md +++ b/docs/get-started/tutorials/run-opencode.md @@ -62,7 +62,7 @@ $ nemoclaw sandbox logs opencode-sandbox --tail Or launch the NemoClaw Terminal for a live view: ```console -$ nemoclaw gator +$ nemoclaw term ``` Look for lines like these in the output: diff --git a/docs/index.md b/docs/index.md index 649b556a..b7362590 100644 --- a/docs/index.md +++ b/docs/index.md @@ -141,7 +141,7 @@ Bootstrap, manage, and deploy NemoClaw clusters locally or on remote hosts via S :link: observability/index :link-type: doc -Stream sandbox logs, audit agent activity, and monitor policy enforcement with the Gator TUI and CLI. +Stream sandbox logs, audit agent activity, and monitor policy enforcement with the NemoClaw Terminal and CLI. +++ {bdg-secondary}`How To` ::: diff --git a/docs/observability/health.md b/docs/observability/health.md index ded723dc..11b68026 100644 --- a/docs/observability/health.md +++ b/docs/observability/health.md @@ -5,7 +5,7 @@ # Cluster and Sandbox Health -NemoClaw provides two ways to monitor health: the CLI for quick checks and the Gator TUI for a live dashboard. +NemoClaw provides two ways to monitor health: the CLI for quick checks and the NemoClaw Terminal for a live dashboard. ## CLI @@ -26,25 +26,25 @@ $ nemoclaw sandbox get `sandbox list` shows all sandboxes with their current phase. `sandbox get` returns detailed information for a single sandbox, including status, image, attached providers, and policy revision. -## Gator TUI +## NemoClaw Terminal -Gator is a terminal user interface for NemoClaw, inspired by [k9s](https://k9scli.io/). Instead of typing individual CLI commands to check cluster health, list sandboxes, and manage resources, Gator gives you a real-time, keyboard-driven dashboard. +The NemoClaw Terminal is a terminal user interface inspired by [k9s](https://k9scli.io/). Instead of typing individual CLI commands to check cluster health, list sandboxes, and manage resources, it gives you a real-time, keyboard-driven dashboard. -### Launching Gator +### Launching the Terminal ```console -$ nemoclaw gator -$ nemoclaw gator --cluster prod -$ NEMOCLAW_CLUSTER=prod nemoclaw gator +$ nemoclaw term +$ nemoclaw term --cluster prod +$ NEMOCLAW_CLUSTER=prod nemoclaw term ``` -Gator inherits all CLI configuration --- cluster selection, TLS settings, and verbosity flags work the same way. No separate configuration is needed. +The terminal inherits all CLI configuration --- cluster selection, TLS settings, and verbosity flags work the same way. No separate configuration is needed. ### Screen Layout ``` ┌─────────────────────────────────────────────────────────────────┐ -│ gator ─ my-cluster ─ Dashboard ● Healthy │ ← title bar +│ NemoClaw ─ my-cluster ─ Dashboard ● Healthy │ ← title bar ├─────────────────────────────────────────────────────────────────┤ │ │ │ (view content — Dashboard or Sandboxes) │ ← main area @@ -56,7 +56,7 @@ Gator inherits all CLI configuration --- cluster selection, TLS settings, and ve └─────────────────────────────────────────────────────────────────┘ ``` -- **Title bar** --- Gator logo, cluster name, current view, and live health status. +- **Title bar** --- NemoClaw logo, cluster name, current view, and live health status. - **Main area** --- the active view. - **Navigation bar** --- available views with shortcut keys. - **Command bar** --- appears when you press `:` (vim-style). @@ -100,7 +100,7 @@ Navigate with `j`/`k` or arrow keys. | `j` / `↓` | Move selection down. | | `k` / `↑` | Move selection up. | | `:` | Enter command mode. | -| `q` | Quit Gator. | +| `q` | Quit the terminal. | | `Ctrl+C` | Force quit. | #### Command Mode @@ -109,7 +109,7 @@ Press `:` to open the command bar. Type a command and press `Enter`. | Command | Action | |---------|--------| -| `quit` / `q` | Quit Gator. | +| `quit` / `q` | Quit the terminal. | | `dashboard` / `1` | Switch to Dashboard. | | `sandboxes` / `2` | Switch to Sandboxes. | @@ -117,15 +117,15 @@ Press `Esc` to cancel. ### Port Forwarding -When creating a sandbox in Gator, specify ports in the **Ports** field (comma-separated, e.g., `8080,3000`). After the sandbox reaches `Ready` state, Gator automatically spawns background SSH tunnels. Forwarded ports appear in the **NOTES** column and in the sandbox detail view. +When creating a sandbox in the terminal, specify ports in the **Ports** field (comma-separated, e.g., `8080,3000`). After the sandbox reaches `Ready` state, the terminal automatically spawns background SSH tunnels. Forwarded ports appear in the **NOTES** column and in the sandbox detail view. ### Data Refresh -Gator polls the cluster every 2 seconds. Both cluster health and the sandbox list update automatically --- no manual refresh needed. +The terminal polls the cluster every 2 seconds. Both cluster health and the sandbox list update automatically --- no manual refresh needed. ### Theme -Gator uses a dark terminal theme based on the NVIDIA brand palette: +The NemoClaw Terminal uses a dark terminal theme based on the NVIDIA brand palette: - **Background**: Terminal black. - **Text**: White for primary, dimmed for secondary. diff --git a/docs/observability/index.md b/docs/observability/index.md index 3d82c95c..c1e89618 100644 --- a/docs/observability/index.md +++ b/docs/observability/index.md @@ -5,7 +5,7 @@ # About Observability -NemoClaw provides log streaming and monitoring for sandboxes and the gateway. You can stream logs from the CLI, monitor denied actions to iterate on policies, and use the Gator TUI for a real-time dashboard. +NemoClaw provides log streaming and monitoring for sandboxes and the gateway. You can stream logs from the CLI, monitor denied actions to iterate on policies, and use the NemoClaw Terminal for a real-time dashboard. ::::{grid} 1 1 2 2 :gutter: 3 @@ -23,7 +23,7 @@ Stream, filter, and monitor sandbox and gateway logs from the CLI. :link: health :link-type: doc -Check cluster and sandbox health from the CLI or the Gator TUI dashboard. +Check cluster and sandbox health from the CLI or the NemoClaw Terminal dashboard. +++ {bdg-secondary}`How To` ::: diff --git a/docs/reference/cli.md b/docs/reference/cli.md index dbe014b4..14f795f9 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -49,7 +49,7 @@ nemoclaw │ ├── update │ ├── delete │ └── list -├── gator +├── term └── completions ``` @@ -148,7 +148,7 @@ Manage inference routes that intercept and reroute LLM API calls from userland c ## NemoClaw Terminal -`nemoclaw gator` launches the NemoClaw Terminal, a dashboard that shows sandbox +`nemoclaw term` launches the NemoClaw Terminal, a dashboard that shows sandbox status, live logs, and policy decisions in a single view. Navigate with `j`/`k`, press `f` to follow live output, `s` to filter by source, and `q` to quit. diff --git a/docs/resources/index.md b/docs/resources/index.md index f198f337..eaadbf89 100644 --- a/docs/resources/index.md +++ b/docs/resources/index.md @@ -18,7 +18,7 @@ | [OPA / Rego](https://www.openpolicyagent.org/) | Policy language for sandbox network access control. NemoClaw uses the `regorus` pure-Rust evaluator. | | [Landlock](https://landlock.io/) | Linux security module for filesystem access control. | | [seccomp](https://www.kernel.org/doc/html/latest/userspace-api/seccomp_filter.html) | Linux kernel system call filtering. | -| [ratatui](https://ratatui.rs/) | Rust TUI framework powering the Gator terminal dashboard. | +| [ratatui](https://ratatui.rs/) | Rust TUI framework powering the NemoClaw Terminal dashboard. | | [russh](https://github.com/warp-tech/russh) | Rust SSH library used for the sandbox embedded SSH server. | | [Helm](https://helm.sh/) | Kubernetes package manager used for deploying NemoClaw components. | @@ -33,7 +33,7 @@ | **Gateway** | The central control plane service that manages sandboxes, providers, and routes. | | **Inference Route** | A mapping from a routing hint to a backend AI model endpoint. | | **BYOC** | Bring Your Own Container — running custom images as sandboxes. | -| **Gator** | The NemoClaw terminal user interface (TUI). | +| **NemoClaw Terminal** | The NemoClaw terminal user interface (TUI), launched with `nemoclaw term`. | | **L7 Inspection** | HTTP-level traffic inspection inside TLS tunnels. | | **TOFU** | Trust-On-First-Use — the binary integrity verification model used by the proxy. | | **mTLS** | Mutual TLS — both client and server present certificates. Used for all gateway communication. | diff --git a/docs/safety-and-privacy/policies.md b/docs/safety-and-privacy/policies.md index 629ad617..76a23fdd 100644 --- a/docs/safety-and-privacy/policies.md +++ b/docs/safety-and-privacy/policies.md @@ -131,7 +131,7 @@ $ nemoclaw sandbox logs --tail --source sandbox Each deny entry shows the blocked host, port, calling binary, and reason. This tells you exactly what the agent tried to reach and why it was blocked. -Alternatively, run `nemoclaw gator` for the NemoClaw Terminal, a live dashboard +Alternatively, run `nemoclaw term` for the NemoClaw Terminal, a live dashboard that shows status and logs in a single view. See {doc}`/sandboxes/terminal` for how to read log entries and diagnose what's being blocked. diff --git a/docs/sandboxes/create-and-manage.md b/docs/sandboxes/create-and-manage.md index 4cbc8825..bd580990 100644 --- a/docs/sandboxes/create-and-manage.md +++ b/docs/sandboxes/create-and-manage.md @@ -139,7 +139,7 @@ $ nemoclaw sandbox logs my-sandbox --tail --source sandbox --level warn --since :::{tip} For a real-time dashboard that combines sandbox status and logs in one view, -run `nemoclaw gator`. See {doc}`terminal` for details on reading log entries and +run `nemoclaw term`. See {doc}`terminal` for details on reading log entries and diagnosing blocked connections. ::: diff --git a/docs/sandboxes/custom-containers.md b/docs/sandboxes/custom-containers.md index a5af5042..4654d245 100644 --- a/docs/sandboxes/custom-containers.md +++ b/docs/sandboxes/custom-containers.md @@ -9,7 +9,7 @@ You can run any Linux container image as a sandbox while keeping the NemoClaw su ## How It Works -When you specify `--image`, the server activates supervisor bootstrap mode. The `navigator-sandbox` supervisor binary is side-loaded from the default sandbox image via a Kubernetes init container, then mounted read-only into your custom container. This means you do not need to build the supervisor into your image. +When you specify `--from` with a container image reference, the server activates supervisor bootstrap mode. The `navigator-sandbox` supervisor binary is side-loaded from the default sandbox image via a Kubernetes init container, then mounted read-only into your custom container. This means you do not need to build the supervisor into your image. ```{mermaid} flowchart TB @@ -49,17 +49,17 @@ The image is built locally via Docker and imported directly into the cluster's c ## Creating a Sandbox with a Custom Image ```console -$ nemoclaw sandbox create --image my-app:latest --keep --name my-app +$ nemoclaw sandbox create --from my-app:latest --keep --name my-app ``` -When `--image` is set, the CLI clears the default `run_as_user`/`run_as_group` policy, since custom images may not have the default `sandbox` user. +When `--from` specifies a container image, the CLI clears the default `run_as_user`/`run_as_group` policy, since custom images may not have the default `sandbox` user. ### With Port Forwarding If your container runs a service: ```console -$ nemoclaw sandbox create --image my-app:latest --forward 8080 --keep -- ./start-server.sh +$ nemoclaw sandbox create --from my-app:latest --forward 8080 --keep -- ./start-server.sh ``` The `--forward` flag starts a background port forward before the command runs, so the service is reachable at `localhost:8080` immediately. @@ -71,7 +71,7 @@ To iterate on your container: ```console $ nemoclaw sandbox delete my-app $ nemoclaw sandbox image push --dockerfile ./Dockerfile --tag my-app:v2 -$ nemoclaw sandbox create --image my-app:v2 --keep --name my-app +$ nemoclaw sandbox create --from my-app:v2 --keep --name my-app ``` ## Limitations diff --git a/docs/sandboxes/port-forwarding.md b/docs/sandboxes/port-forwarding.md index f0ca2268..cee0a015 100644 --- a/docs/sandboxes/port-forwarding.md +++ b/docs/sandboxes/port-forwarding.md @@ -44,7 +44,7 @@ $ nemoclaw sandbox forward stop 8080 my-sandbox You can start a port forward when creating a sandbox: ```console -$ nemoclaw sandbox create --image my-app:latest --forward 8080 --keep -- ./start-server.sh +$ nemoclaw sandbox create --from my-app:latest --forward 8080 --keep -- ./start-server.sh ``` The `--forward` flag implies `--keep` (the sandbox stays alive after the command exits) and starts the forward before the command runs. @@ -55,6 +55,6 @@ Port forwarding uses OpenSSH's `-L` flag (`-L :127.0.0.1:`) through Background forwards are tracked via PID files in `~/.config/nemoclaw/forwards/`. Deleting a sandbox automatically stops any active forwards for that sandbox. -## Gator TUI +## NemoClaw Terminal -The Gator TUI also supports port forwarding. When creating a sandbox in Gator, specify ports in the **Ports** field (comma-separated, e.g., `8080,3000`). Forwarded ports appear in the sandbox table's **NOTES** column. +The NemoClaw Terminal also supports port forwarding. When creating a sandbox in the terminal, specify ports in the **Ports** field (comma-separated, e.g., `8080,3000`). Forwarded ports appear in the sandbox table's **NOTES** column. diff --git a/docs/sandboxes/terminal.md b/docs/sandboxes/terminal.md index 0b30263e..23452918 100644 --- a/docs/sandboxes/terminal.md +++ b/docs/sandboxes/terminal.md @@ -8,7 +8,7 @@ NemoClaw Terminal is a terminal dashboard that displays sandbox status and live activity in a single view. Use it to monitor agent behavior, diagnose blocked connections, and observe inference interception in real time. ```console -$ nemoclaw gator +$ nemoclaw term ``` ## Sandbox Status diff --git a/docs/troubleshooting/custom-container-issues.md b/docs/troubleshooting/custom-container-issues.md index af81bef1..3dd42b25 100644 --- a/docs/troubleshooting/custom-container-issues.md +++ b/docs/troubleshooting/custom-container-issues.md @@ -9,7 +9,7 @@ Troubleshoot problems with building and running custom container images in sandb ## Custom Image Fails to Start -**Symptom:** Sandbox with `--image` goes to `Error` state. +**Symptom:** Sandbox with `--from ` goes to `Error` state. **Check:** 1. Is the image pushed to the cluster? `nemoclaw sandbox image push --dockerfile ./Dockerfile --tag my-image`. From 633b4e06a126f559d356f3c6099f72603072bc83 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 5 Mar 2026 15:58:51 -0800 Subject: [PATCH 07/39] move TOC around --- docs/index.md | 75 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/docs/index.md b/docs/index.md index b7362590..d8c47573 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,7 +1,7 @@ --- title: page: "NVIDIA NemoClaw Developer Guide" - nav: "NVIDIA NemoClaw" + nav: "Get Started" card: "NVIDIA NemoClaw" description: "NemoClaw is the safe, private runtime for autonomous AI agents. Run agents in sandboxed environments that protect your data, credentials, and infrastructure." topics: @@ -24,11 +24,67 @@ content: # NVIDIA NemoClaw Developer Guide +{bdg-link-secondary}`GitHub ` +{bdg-link-primary}`PyPI ` + NemoClaw is the safe, private runtime for autonomous AI agents. It provides sandboxed execution environments that protect your data, credentials, and infrastructure — agents run with exactly the permissions they need and nothing more, governed by declarative policies that prevent unauthorized file access, data exfiltration, and uncontrolled network activity. +# Install and Create a Sandbox + +NemoClaw is designed for minimal setup with safety and privacy built in from the start. Two commands take you from zero to a running, policy-enforced sandbox. + +## Prerequisites + +The following are the prerequisites for the NemoClaw CLI. + +- Docker must be running. +- Python 3.12+ is required. + +## Install the CLI + +```console +$ pip install nemoclaw +``` + +## Create a Sandbox + +::::{tab-set} + +:::{tab-item} Claude Code +```console +$ nemoclaw sandbox create -- claude +``` + +```text +✓ Runtime ready +✓ Discovered Claude credentials (ANTHROPIC_API_KEY) +✓ Created sandbox: keen-fox +✓ Policy loaded (4 protection layers active) + +Connecting to keen-fox... +``` + +Claude Code works out of the box with the default policy. +::: + +:::{tab-item} Community Sandbox +```console +$ nemoclaw sandbox create --from openclaw +``` + +The `--from` flag pulls from the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) catalog --- a collection of domain-specific sandbox images bundled with their own containers, policies, and skills. +::: + +:::: + +The agent runs with filesystem, network, process, and inference protection active. Credentials stay inside the sandbox, network access follows your policy, and inference traffic remains private. A single YAML policy controls all four protection layers and is hot-reloadable on a running sandbox. + +For opencode or Codex, see the [Tutorials](tutorials/index.md) for agent-specific setup. + + --- ## About NemoClaw @@ -184,22 +240,22 @@ Links to the GitHub repository, related projects, and additional learning materi :::: + ```{toctree} -:caption: About :hidden: -Overview -about/how-it-works -about/support-matrix -about/release-notes +Get Started +get-started/tutorials/index ``` ```{toctree} -:caption: Get Started +:caption: Concepts :hidden: -get-started/installation -get-started/tutorials/index +Overview +about/how-it-works +about/support-matrix +about/release-notes ``` ```{toctree} @@ -257,6 +313,7 @@ observability/health :hidden: reference/index +about/support-matrix reference/cli reference/policy-schema reference/environment-variables From 3e360881276ba381b15e20abd09f06813c55bb61 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 5 Mar 2026 16:00:16 -0800 Subject: [PATCH 08/39] drop support matrix from concepts --- docs/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index d8c47573..853f4f23 100644 --- a/docs/index.md +++ b/docs/index.md @@ -254,7 +254,6 @@ get-started/tutorials/index Overview about/how-it-works -about/support-matrix about/release-notes ``` From f02a95f9ede777ecd37b7503dbc32b6485d9e90f Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 5 Mar 2026 16:09:12 -0800 Subject: [PATCH 09/39] fix links --- docs/about/index.md | 3 +- docs/get-started/installation.md | 78 ---------------------- docs/get-started/tutorials/index.md | 2 +- docs/get-started/tutorials/run-agents.md | 2 +- docs/get-started/tutorials/run-claude.md | 2 +- docs/get-started/tutorials/run-openclaw.md | 2 +- docs/index.md | 21 ++---- 7 files changed, 11 insertions(+), 99 deletions(-) delete mode 100644 docs/get-started/installation.md diff --git a/docs/about/index.md b/docs/about/index.md index 29fd8da6..e7a2cfea 100644 --- a/docs/about/index.md +++ b/docs/about/index.md @@ -87,7 +87,7 @@ nemoclaw cluster admin deploy nemoclaw sandbox create -- claude ``` -No Kubernetes expertise is required. Refer to [Get Started](../get-started/installation.md) for full installation steps. +No Kubernetes expertise is required. ::: ## Use Cases @@ -106,4 +106,3 @@ No Kubernetes expertise is required. Refer to [Get Started](../get-started/insta - [How It Works](how-it-works.md): Explore the architecture, major subsystems, and the end-to-end flow from cluster bootstrap to running sandbox. - [Support Matrix](support-matrix.md): Find platform requirements, supported providers, agent tools, and compatibility details. - [Release Notes](release-notes.md): Track what changed in each version. -- [Get Started](../get-started/installation.md): Install the CLI and launch your first sandbox. diff --git a/docs/get-started/installation.md b/docs/get-started/installation.md deleted file mode 100644 index dad8ac91..00000000 --- a/docs/get-started/installation.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: - page: "About Getting Started with NemoClaw" - nav: "About Getting Started" - card: "About Getting Started" -description: "Install the CLI, bootstrap a cluster, and launch your first sandbox in minutes." -topics: -- Get Started -tags: -- Installation -- Quickstart -- Sandbox -- CLI -content: - type: get_started - difficulty: technical_beginner - audience: - - engineer - - ai_engineer - - devops ---- - - - -# Install and Create a Sandbox - -NemoClaw is designed for minimal setup with safety and privacy built in from the start. Two commands take you from zero to a running, policy-enforced sandbox. - -## Prerequisites - -The following are the prerequisites for the NemoClaw CLI. - -- Docker must be running. -- Python 3.12+ is required. - -## Install the CLI - -```console -$ pip install nemoclaw -``` - -## Create a Sandbox - -::::{tab-set} - -:::{tab-item} Claude Code -```console -$ nemoclaw sandbox create -- claude -``` - -```text -✓ Runtime ready -✓ Discovered Claude credentials (ANTHROPIC_API_KEY) -✓ Created sandbox: keen-fox -✓ Policy loaded (4 protection layers active) - -Connecting to keen-fox... -``` - -Claude Code works out of the box with the default policy. -::: - -:::{tab-item} Community Sandbox -```console -$ nemoclaw sandbox create --from openclaw -``` - -The `--from` flag pulls from the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) catalog --- a collection of domain-specific sandbox images bundled with their own containers, policies, and skills. -::: - -:::: - -The agent runs with filesystem, network, process, and inference protection active. Credentials stay inside the sandbox, network access follows your policy, and inference traffic remains private. A single YAML policy controls all four protection layers and is hot-reloadable on a running sandbox. - -For opencode or Codex, see the [Tutorials](tutorials/index.md) for agent-specific setup. diff --git a/docs/get-started/tutorials/index.md b/docs/get-started/tutorials/index.md index cd5ecb14..79882f0d 100644 --- a/docs/get-started/tutorials/index.md +++ b/docs/get-started/tutorials/index.md @@ -2,7 +2,7 @@ Each tutorial walks through an end-to-end workflow from bootstrapping a cluster to running an agent inside a policy-enforced sandbox. Pick the tutorial that matches your agent and follow along. -All tutorials assume you have [installed the CLI](../installation.md) and have Docker running. +All tutorials assume you have [installed the CLI](../../index.md#install-the-cli) and have Docker running. ::::{grid} 1 1 2 2 :gutter: 3 diff --git a/docs/get-started/tutorials/run-agents.md b/docs/get-started/tutorials/run-agents.md index 428ffd05..76758d21 100644 --- a/docs/get-started/tutorials/run-agents.md +++ b/docs/get-started/tutorials/run-agents.md @@ -11,7 +11,7 @@ This tutorial shows how to run OpenClaw inside NemoClaw with zero code changes. Before you begin, ensure the following are in place. -- NemoClaw CLI installed. Refer to [Installation](../installation.md). +- NemoClaw CLI installed. Refer to [Installation](../../index.md#install-the-cli). - A running cluster. Run `nemoclaw cluster admin deploy` to create one. ## Why NemoClaw diff --git a/docs/get-started/tutorials/run-claude.md b/docs/get-started/tutorials/run-claude.md index 1818ef35..093364b2 100644 --- a/docs/get-started/tutorials/run-claude.md +++ b/docs/get-started/tutorials/run-claude.md @@ -9,7 +9,7 @@ Run Anthropic Claude as a coding agent inside a NemoClaw sandbox. This tutorial ## Prerequisites -- NemoClaw CLI installed. Refer to [Installation](../installation.md). +- NemoClaw CLI installed. Refer to [Installation](../../index.md#install-the-cli). - Docker installed and running. - An Anthropic API key available as `ANTHROPIC_API_KEY` in your environment or in `~/.claude.json`. diff --git a/docs/get-started/tutorials/run-openclaw.md b/docs/get-started/tutorials/run-openclaw.md index f384461f..0e87e590 100644 --- a/docs/get-started/tutorials/run-openclaw.md +++ b/docs/get-started/tutorials/run-openclaw.md @@ -9,7 +9,7 @@ Run OpenClaw inside a NemoClaw sandbox with zero code changes. This tutorial tak ## Prerequisites -- NemoClaw CLI installed. Refer to [Installation](../installation.md). +- NemoClaw CLI installed. Refer to [Installation](../../index.md#install-the-cli). - Docker installed and running. ## Step 1: Deploy a Cluster diff --git a/docs/index.md b/docs/index.md index 853f4f23..73cbfc37 100644 --- a/docs/index.md +++ b/docs/index.md @@ -22,7 +22,7 @@ content: SPDX-License-Identifier: Apache-2.0 --> -# NVIDIA NemoClaw Developer Guide +# NVIDIA NemoClaw {bdg-link-secondary}`GitHub ` {bdg-link-primary}`PyPI ` @@ -32,24 +32,24 @@ that protect your data, credentials, and infrastructure — agents run with exac nothing more, governed by declarative policies that prevent unauthorized file access, data exfiltration, and uncontrolled network activity. -# Install and Create a Sandbox +## Install and Create a Sandbox NemoClaw is designed for minimal setup with safety and privacy built in from the start. Two commands take you from zero to a running, policy-enforced sandbox. -## Prerequisites +### Prerequisites The following are the prerequisites for the NemoClaw CLI. - Docker must be running. - Python 3.12+ is required. -## Install the CLI +### Install the CLI ```console $ pip install nemoclaw ``` -## Create a Sandbox +### Create a Sandbox ::::{tab-set} @@ -82,7 +82,7 @@ The `--from` flag pulls from the [NemoClaw Community](https://github.com/NVIDIA/ The agent runs with filesystem, network, process, and inference protection active. Credentials stay inside the sandbox, network access follows your policy, and inference traffic remains private. A single YAML policy controls all four protection layers and is hot-reloadable on a running sandbox. -For opencode or Codex, see the [Tutorials](tutorials/index.md) for agent-specific setup. +For opencode or Codex, see the [Tutorials](get-started/tutorials/index.md) for agent-specific setup. --- @@ -139,15 +139,6 @@ Install the CLI, bootstrap a cluster, and create your first sandbox. ::::{grid} 1 1 2 2 :gutter: 3 -:::{grid-item-card} About Getting Started -:link: get-started/installation -:link-type: doc - -Install the CLI, bootstrap a cluster, and launch your first sandbox in minutes. -+++ -{bdg-secondary}`Get Started` -::: - :::{grid-item-card} Tutorials :link: get-started/tutorials/index :link-type: doc From a021341bb292b7f42d7326bb14f1bbfa0858d855 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 5 Mar 2026 16:21:01 -0800 Subject: [PATCH 10/39] minor fixes and fix badges --- docs/about/release-notes.md | 25 ++-------------------- docs/get-started/tutorials/index.md | 2 +- docs/get-started/tutorials/run-opencode.md | 10 ++++----- docs/index.md | 5 +++-- 4 files changed, 11 insertions(+), 31 deletions(-) diff --git a/docs/about/release-notes.md b/docs/about/release-notes.md index b262db37..60ae674a 100644 --- a/docs/about/release-notes.md +++ b/docs/about/release-notes.md @@ -6,30 +6,9 @@ # Release Notes This page tracks changes, new features, and fixes for each NemoClaw release. +This page covers the highlights of the release. +For more details, refer to the [NemoClaw GitHub Releases](https://github.com/NVIDIA/NemoClaw/releases). ## 0.1.0 The first release of NVIDIA NemoClaw, introducing sandboxed AI agent execution with kernel-level isolation, policy enforcement, and credential management. - -### Key Features - -The following table summarizes the key features included in this release. - -| Feature | Description | -|---------|-------------| -| Sandbox execution environment | Isolated AI agent runtime with Landlock filesystem restrictions, seccomp system call filtering, network namespace isolation, and process privilege separation. | -| HTTP CONNECT proxy | Policy-enforcing network proxy with per-binary access control, binary integrity verification (TOFU), SSRF protection, and L7 HTTP inspection. | -| OPA/Rego policy engine | Embedded policy evaluation using the `regorus` pure-Rust Rego evaluator. No external OPA daemon required. | -| Live policy updates | Hot-reload `network_policies` and `inference` fields on running sandboxes without restart. | -| Provider system | First-class credential management with auto-discovery from local machine, secure gateway storage, and runtime injection. | -| Inference routing | Transparent interception and rerouting of OpenAI/Anthropic API calls to policy-controlled backends for inference privacy. | -| Cluster bootstrap | Single-container k3s deployment with Docker as the only dependency. Supports local and remote (SSH) targets. | -| CLI (`nemoclaw` / `ncl`) | Full command-line interface for cluster, sandbox, provider, and inference route management. | -| NemoClaw Terminal | Terminal dashboard for real-time cluster monitoring and sandbox management. | -| BYOC | Run custom container images as sandboxes with supervisor bootstrap. | -| SSH tunneling | Secure access to sandboxes through the gateway with session tokens and mTLS. | -| File sync | Push and pull files to/from sandboxes via tar-over-SSH. | -| Port forwarding | Forward local ports into sandboxes via SSH tunnels. | -| mTLS | Automatic PKI bootstrap and mutual TLS for all gateway communication. | - -For supported providers, inference protocols, and platform requirements, refer to the [Support Matrix](support-matrix.md). diff --git a/docs/get-started/tutorials/index.md b/docs/get-started/tutorials/index.md index 79882f0d..bcfea9fb 100644 --- a/docs/get-started/tutorials/index.md +++ b/docs/get-started/tutorials/index.md @@ -25,7 +25,7 @@ Run Anthropic Claude as a coding agent with credential management, inference rou {bdg-secondary}`Tutorial` ::: -:::{grid-item-card} Run Opencode with NVIDIA Inference +:::{grid-item-card} Run OpenCode with NVIDIA Inference :link: run-opencode :link-type: doc diff --git a/docs/get-started/tutorials/run-opencode.md b/docs/get-started/tutorials/run-opencode.md index b6e8a149..357921da 100644 --- a/docs/get-started/tutorials/run-opencode.md +++ b/docs/get-started/tutorials/run-opencode.md @@ -3,9 +3,9 @@ SPDX-License-Identifier: Apache-2.0 --> -# Run opencode with NVIDIA Inference +# Run OpenCode with NVIDIA Inference -This tutorial walks through a realistic setup where you run [opencode](https://opencode.ai) inside a NemoClaw sandbox with inference routed to NVIDIA API endpoints. Along the way, you will hit policy problems, diagnose them from logs, write a custom policy, and configure inference routing --- the full policy iteration loop. +This tutorial walks through a realistic setup where you run [OpenCode](https://opencode.ai) inside a NemoClaw sandbox with inference routed to NVIDIA API endpoints. Along the way, you will hit policy problems, diagnose them from logs, write a custom policy, and configure inference routing --- the full policy iteration loop. **What you will learn:** @@ -41,17 +41,17 @@ $ nemoclaw provider list ## Step 2: Create the Sandbox -Create a sandbox with the NVIDIA provider attached and opencode as the startup command: +Create a sandbox with the NVIDIA provider attached and OpenCode as the startup command: ```console $ nemoclaw sandbox create --name opencode-sandbox --provider nvidia --keep -- opencode ``` -The `--keep` flag keeps the sandbox alive after you exit, which you will need for the iteration steps ahead. The CLI creates the sandbox with the default policy, injects the NVIDIA credentials, and starts opencode. +The `--keep` flag keeps the sandbox alive after you exit, which you will need for the iteration steps ahead. The CLI creates the sandbox with the default policy, injects the NVIDIA credentials, and starts OpenCode. ## Step 3: Hit a Problem -Try using opencode inside the sandbox. You will likely find that calls to NVIDIA inference endpoints fail or behave unexpectedly. The default policy is designed around Claude Code, not opencode. +Try using OpenCode inside the sandbox. You will likely find that calls to NVIDIA inference endpoints fail or behave unexpectedly. The default policy is designed around Claude Code, not OpenCode. Open a second terminal and check the logs: diff --git a/docs/index.md b/docs/index.md index 73cbfc37..08a4fef9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -24,8 +24,9 @@ content: # NVIDIA NemoClaw -{bdg-link-secondary}`GitHub ` -{bdg-link-primary}`PyPI ` +[![GitHub](https://img.shields.io/badge/github-repo-green?logo=github)](https://github.com/NVIDIA/NemoClaw) +[![License](https://img.shields.io/badge/License-Apache_2.0-blue)](https://github.com/NVIDIA/NemoClaw/blob/main/LICENSE) +[![PyPI](https://img.shields.io/badge/PyPI-nemoclaw-orange?logo=pypi)](https://pypi.org/project/nemoclaw/) NemoClaw is the safe, private runtime for autonomous AI agents. It provides sandboxed execution environments that protect your data, credentials, and infrastructure — agents run with exactly the permissions they need and From 3d3507dd39329aafda22fe006ff758fdae43e508 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 5 Mar 2026 16:30:29 -0800 Subject: [PATCH 11/39] minor fixes --- docs/get-started/tutorials/index.md | 2 +- docs/get-started/tutorials/run-agents.md | 2 +- docs/get-started/tutorials/run-claude.md | 2 +- docs/get-started/tutorials/run-openclaw.md | 2 +- docs/index.md | 127 ++++----------------- 5 files changed, 28 insertions(+), 107 deletions(-) diff --git a/docs/get-started/tutorials/index.md b/docs/get-started/tutorials/index.md index bcfea9fb..f6b0c904 100644 --- a/docs/get-started/tutorials/index.md +++ b/docs/get-started/tutorials/index.md @@ -2,7 +2,7 @@ Each tutorial walks through an end-to-end workflow from bootstrapping a cluster to running an agent inside a policy-enforced sandbox. Pick the tutorial that matches your agent and follow along. -All tutorials assume you have [installed the CLI](../../index.md#install-the-cli) and have Docker running. +All tutorials assume you have [installed the CLI](../../index.md#install-the-nemoclaw-cli) and have Docker running. ::::{grid} 1 1 2 2 :gutter: 3 diff --git a/docs/get-started/tutorials/run-agents.md b/docs/get-started/tutorials/run-agents.md index 76758d21..17dc1c31 100644 --- a/docs/get-started/tutorials/run-agents.md +++ b/docs/get-started/tutorials/run-agents.md @@ -11,7 +11,7 @@ This tutorial shows how to run OpenClaw inside NemoClaw with zero code changes. Before you begin, ensure the following are in place. -- NemoClaw CLI installed. Refer to [Installation](../../index.md#install-the-cli). +- NemoClaw CLI installed. Refer to [Installation](../../index.md#install-the-nemoclaw-cli). - A running cluster. Run `nemoclaw cluster admin deploy` to create one. ## Why NemoClaw diff --git a/docs/get-started/tutorials/run-claude.md b/docs/get-started/tutorials/run-claude.md index 093364b2..039fbbe9 100644 --- a/docs/get-started/tutorials/run-claude.md +++ b/docs/get-started/tutorials/run-claude.md @@ -9,7 +9,7 @@ Run Anthropic Claude as a coding agent inside a NemoClaw sandbox. This tutorial ## Prerequisites -- NemoClaw CLI installed. Refer to [Installation](../../index.md#install-the-cli). +- NemoClaw CLI installed. Refer to [Installation](../../index.md#install-the-nemoclaw-cli). - Docker installed and running. - An Anthropic API key available as `ANTHROPIC_API_KEY` in your environment or in `~/.claude.json`. diff --git a/docs/get-started/tutorials/run-openclaw.md b/docs/get-started/tutorials/run-openclaw.md index 0e87e590..22551889 100644 --- a/docs/get-started/tutorials/run-openclaw.md +++ b/docs/get-started/tutorials/run-openclaw.md @@ -9,7 +9,7 @@ Run OpenClaw inside a NemoClaw sandbox with zero code changes. This tutorial tak ## Prerequisites -- NemoClaw CLI installed. Refer to [Installation](../../index.md#install-the-cli). +- NemoClaw CLI installed. Refer to [Installation](../../index.md#install-the-nemoclaw-cli). - Docker installed and running. ## Step 1: Deploy a Cluster diff --git a/docs/index.md b/docs/index.md index 08a4fef9..9cd0fd73 100644 --- a/docs/index.md +++ b/docs/index.md @@ -44,13 +44,13 @@ The following are the prerequisites for the NemoClaw CLI. - Docker must be running. - Python 3.12+ is required. -### Install the CLI +### Install the NemoClaw CLI ```console $ pip install nemoclaw ``` -### Create a Sandbox +### Create Your First NemoClaw Sandbox ::::{tab-set} @@ -83,86 +83,51 @@ The `--from` flag pulls from the [NemoClaw Community](https://github.com/NVIDIA/ The agent runs with filesystem, network, process, and inference protection active. Credentials stay inside the sandbox, network access follows your policy, and inference traffic remains private. A single YAML policy controls all four protection layers and is hot-reloadable on a running sandbox. -For opencode or Codex, see the [Tutorials](get-started/tutorials/index.md) for agent-specific setup. - +For OpenCode or Codex, see the [](get-started/tutorials/run-opencode.md) tutorial for agent-specific setup. --- -## About NemoClaw - -Understand what NemoClaw is, how the subsystems fit together, and what is new in the latest release. +## Next Steps -::::{grid} 1 1 2 2 +::::{grid} 2 2 3 3 :gutter: 3 -:::{grid-item-card} NemoClaw Overview -:link: about/index +:::{grid-item-card} Tutorials +:link: get-started/tutorials/index :link-type: doc -Learn about the safety and privacy model, key capabilities, and use cases for sandboxed agent execution. -+++ -{bdg-secondary}`Concept` -::: - -:::{grid-item-card} How It Works -:link: about/how-it-works -:link-type: doc +Step-by-step walkthroughs for Claude Code, OpenClaw, and OpenCode with NVIDIA inference. -Explore the architecture, major subsystems, and the end-to-end flow from cluster bootstrap to running sandbox. +++ -{bdg-secondary}`Concept` +{bdg-secondary}`Tutorial` ::: -:::{grid-item-card} Support Matrix -:link: about/support-matrix +:::{grid-item-card} Security Model +:link: safety-and-privacy/security-model :link-type: doc -Platform requirements, supported providers, agent tools, and compatibility details. -+++ -{bdg-secondary}`Reference` -::: - -:::{grid-item-card} Release Notes -:link: about/release-notes -:link-type: doc +How NemoClaw protects against data exfiltration, credential theft, unauthorized API calls, and privilege escalation. -Track what changed in each version. +++ -{bdg-secondary}`Reference` +{bdg-secondary}`Concept` ::: -:::: - -## Get Started - -Install the CLI, bootstrap a cluster, and create your first sandbox. - -::::{grid} 1 1 2 2 -:gutter: 3 - -:::{grid-item-card} Tutorials -:link: get-started/tutorials/index +:::{grid-item-card} Sandboxes +:link: sandboxes/create-and-manage :link-type: doc -Create, connect to, and manage sandboxes. Configure providers, sync files, forward ports, and bring your own containers. +Create, manage, and customize sandboxes. Use community images or bring your own container. + +++ -{bdg-secondary}`How To` +{bdg-secondary}`Concept` ::: -:::: - -## Developer Guides - -Configure safety policies, route inference traffic, manage clusters, and monitor agent activity. - -::::{grid} 1 1 2 2 -:gutter: 3 - :::{grid-item-card} Safety and Privacy :link: safety-and-privacy/index :link-type: doc -Understand how NemoClaw keeps your data safe and private — and write policies that control filesystem, network, and inference access. +Write policies that control what agents can access. Iterate on network rules in real time. + +++ {bdg-secondary}`Concept` ::: @@ -171,68 +136,24 @@ Understand how NemoClaw keeps your data safe and private — and write policies :link: inference/index :link-type: doc -Keep inference traffic private by routing AI API calls to local or self-hosted backends — without modifying agent code. -+++ -{bdg-secondary}`How To` -::: - -:::{grid-item-card} Clusters -:link: clusters/index -:link-type: doc +Keep inference traffic private by routing API calls to local or self-hosted backends. -Bootstrap, manage, and deploy NemoClaw clusters locally or on remote hosts via SSH. +++ -{bdg-secondary}`How To` -::: - -:::{grid-item-card} Observability -:link: observability/index -:link-type: doc - -Stream sandbox logs, audit agent activity, and monitor policy enforcement with the NemoClaw Terminal and CLI. -+++ -{bdg-secondary}`How To` +{bdg-secondary}`Concept` ::: -:::: - -## References - -Look up CLI commands, policy schemas, environment variables, and troubleshooting guidance. - -::::{grid} 1 1 2 2 -:gutter: 3 - :::{grid-item-card} Reference -:link: reference/index +:link: reference/cli :link-type: doc -CLI command reference, policy schema, environment variables, and system architecture diagrams. -+++ -{bdg-secondary}`Reference` -::: +CLI commands, policy schema, environment variables, and system architecture. -:::{grid-item-card} Troubleshooting -:link: troubleshooting/cluster-issues -:link-type: doc - -Diagnose common issues with clusters, sandboxes, and networking. -+++ -{bdg-secondary}`Troubleshooting` -::: - -:::{grid-item-card} Resources -:link: resources/index -:link-type: doc - -Links to the GitHub repository, related projects, and additional learning materials. +++ {bdg-secondary}`Reference` ::: :::: - ```{toctree} :hidden: From ceeecaaf555597d1200cd1fcc0b37981b89b8ea3 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 5 Mar 2026 16:37:56 -0800 Subject: [PATCH 12/39] incorporate missed content --- docs/about/support-matrix.md | 25 ++++--- docs/sandboxes/custom-containers.md | 87 ++++++++++++----------- docs/sandboxes/providers.md | 103 ++++++++++++---------------- 3 files changed, 101 insertions(+), 114 deletions(-) diff --git a/docs/about/support-matrix.md b/docs/about/support-matrix.md index e696727f..c773b440 100644 --- a/docs/about/support-matrix.md +++ b/docs/about/support-matrix.md @@ -38,16 +38,21 @@ When `landlock.compatibility` is set to `best_effort` (the default), the sandbox Providers supply credentials to sandboxes. NemoClaw can auto-discover credentials from environment variables and config files on your local machine. -| Provider | Type Slug | Auto-Discovery | -|----------|-----------|----------------| -| Anthropic Claude | `claude` | `ANTHROPIC_API_KEY`, `CLAUDE_API_KEY`, `~/.claude.json` | -| OpenAI Codex | `codex` | `OPENAI_API_KEY`, `~/.config/codex/config.json` | -| OpenCode | `opencode` | `OPENCODE_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY` | -| GitHub | `github` | `GITHUB_TOKEN`, `GH_TOKEN`, `~/.config/gh/hosts.yml` | -| GitLab | `gitlab` | `GITLAB_TOKEN`, `GLAB_TOKEN`, `~/.config/glab-cli/config.yml` | -| NVIDIA | `nvidia` | `NVIDIA_API_KEY` | -| Generic | `generic` | Manual only (`--credential KEY=VALUE`) | -| Outlook | `outlook` | Manual only | +| Type | Environment Variables Injected | Typical Use | +|---|---|---| +| `claude` | `ANTHROPIC_API_KEY`, `CLAUDE_API_KEY` | Claude Code, Anthropic API | +| `codex` | `OPENAI_API_KEY` | OpenAI Codex | +| `opencode` | `OPENCODE_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY` | opencode tool | +| `github` | `GITHUB_TOKEN`, `GH_TOKEN` | GitHub API, `gh` CLI | +| `gitlab` | `GITLAB_TOKEN`, `GLAB_TOKEN`, `CI_JOB_TOKEN` | GitLab API, `glab` CLI | +| `nvidia` | `NVIDIA_API_KEY` | NVIDIA API Catalog | +| `generic` | User-defined | Any service with custom credentials | +| `outlook` | *(none --- no auto-discovery)* | Microsoft Outlook integration | + +:::{tip} +Use the `generic` type for any service not listed above. You define the +environment variable names and values yourself with `--credential`. +::: ## Supported Inference Protocols diff --git a/docs/sandboxes/custom-containers.md b/docs/sandboxes/custom-containers.md index 4654d245..89e2231f 100644 --- a/docs/sandboxes/custom-containers.md +++ b/docs/sandboxes/custom-containers.md @@ -5,77 +5,74 @@ # Custom Containers -You can run any Linux container image as a sandbox while keeping the NemoClaw supervisor in control of security enforcement. +Build a custom container image and run it as a NemoClaw sandbox. -## How It Works +## Prerequisites -When you specify `--from` with a container image reference, the server activates supervisor bootstrap mode. The `navigator-sandbox` supervisor binary is side-loaded from the default sandbox image via a Kubernetes init container, then mounted read-only into your custom container. This means you do not need to build the supervisor into your image. +- NemoClaw CLI installed (`pip install nemoclaw`) +- Docker running on your machine +- A Dockerfile for your workload -```{mermaid} -flowchart TB - subgraph pod["Pod"] - subgraph init["Init Container · copy-supervisor"] - init_desc["Image: default sandbox image\nCopies navigator-sandbox binary\ninto shared volume"] - end +## Step 1: Create a Sandbox from Your Dockerfile - init -- "shared volume" --> agent +Point `--from` at the directory containing your Dockerfile: - subgraph agent["Agent Container"] - agent_desc["Image: your custom image\nRuns navigator-sandbox as entrypoint\nFull sandbox policy enforcement"] - end - end +```console +$ nemoclaw sandbox create --from ./my-app --keep --name my-app ``` -## Building and Pushing Images +The CLI builds the image locally via Docker, pushes it into the cluster, and +creates the sandbox --- all in one step. No external container registry is +needed. -Build a custom container image and import it into the cluster: +You can also pass a full container image reference if the image is already +built: ```console -$ nemoclaw sandbox image push \ - --dockerfile ./Dockerfile \ - --tag my-app:latest \ - --context . +$ nemoclaw sandbox create --from my-registry.example.com/my-image:latest --keep --name my-app ``` -The image is built locally via Docker and imported directly into the cluster's containerd runtime. No external registry is needed. - -| Flag | Description | -|------|-------------| -| `--dockerfile` (required) | Path to the Dockerfile. | -| `--tag` | Image name and tag (default: auto-generated timestamp). | -| `--context` | Build context directory (default: Dockerfile parent). | -| `--build-arg KEY=VALUE` | Docker build argument (repeatable). | +## Step 2: Forward Ports -## Creating a Sandbox with a Custom Image +If your container runs a service, forward the port to your host: ```console -$ nemoclaw sandbox create --from my-app:latest --keep --name my-app +$ nemoclaw sandbox forward start 8080 my-app -d ``` -When `--from` specifies a container image, the CLI clears the default `run_as_user`/`run_as_group` policy, since custom images may not have the default `sandbox` user. +The `-d` flag runs the forward in the background so you can continue using +your terminal. -### With Port Forwarding +## Step 3: Iterate -If your container runs a service: +When you change your Dockerfile, delete the sandbox and recreate: ```console -$ nemoclaw sandbox create --from my-app:latest --forward 8080 --keep -- ./start-server.sh +$ nemoclaw sandbox delete my-app && \ + nemoclaw sandbox create --from ./my-app --keep --name my-app ``` -The `--forward` flag starts a background port forward before the command runs, so the service is reachable at `localhost:8080` immediately. - -## Updating a Custom Image +## Shortcut: Create with Forwarding and a Startup Command -To iterate on your container: +You can combine port forwarding and a startup command in a single step: ```console -$ nemoclaw sandbox delete my-app -$ nemoclaw sandbox image push --dockerfile ./Dockerfile --tag my-app:v2 -$ nemoclaw sandbox create --from my-app:v2 --keep --name my-app +$ nemoclaw sandbox create --from ./my-app --forward 8080 --keep -- ./start-server.sh ``` -## Limitations +This creates the sandbox, sets up port forwarding on port 8080, and runs +`./start-server.sh` as the sandbox command. + +:::{warning} +Distroless and `FROM scratch` images are not supported. The NemoClaw +supervisor requires glibc, `/proc`, and a shell to operate. Images missing +`iproute2` or required Linux capabilities will fail to start in proxy mode. +Ensure your base image includes these dependencies. +::: + +## Next Steps -- **Distroless / `FROM scratch` images are not supported.** The supervisor needs glibc, `/proc`, and a shell. -- **Missing `iproute2` blocks proxy mode.** Network namespace isolation requires `iproute2` and the `CAP_NET_ADMIN`/`CAP_SYS_ADMIN` capabilities. -- The init container assumes the supervisor binary is at a fixed path in the default sandbox image. +- {doc}`create-and-manage` --- full sandbox lifecycle commands +- {doc}`providers` --- attach credentials to your custom container +- {doc}`/safety-and-privacy/policies` --- write a policy tailored to your workload +- {doc}`/safety-and-privacy/security-model` --- understand the isolation layers applied to custom images \ No newline at end of file diff --git a/docs/sandboxes/providers.md b/docs/sandboxes/providers.md index 92f7ca6f..9d17effb 100644 --- a/docs/sandboxes/providers.md +++ b/docs/sandboxes/providers.md @@ -5,71 +5,79 @@ # Providers -AI agents typically need credentials to access external services — an API key for the AI model provider, a token for GitHub or GitLab, and so on. NemoClaw manages these credentials as first-class entities called **providers**. +AI agents typically need credentials to access external services — an API key for the AI model provider, a token for GitHub or GitLab, and so on. NemoClaw manages these credentials as first-class entities called *providers*. -## How Providers Work +Create and manage providers that supply credentials to sandboxes. -1. **You configure a provider once** — either by letting the CLI discover credentials from your local machine, or by providing them explicitly. -2. **Credentials are stored on the gateway** — separate from sandbox definitions. They never appear in Kubernetes pod specifications. -3. **Sandboxes receive credentials at runtime** — when a sandbox starts, the supervisor fetches credentials from the gateway and injects them as environment variables into every process it spawns. +## Create a Provider -This means you configure credentials once, and every sandbox that needs them receives them automatically. +### From Local Credentials -## Supported Provider Types - -| Type | Discovered Environment Variables | Discovered Config Paths | -|------|----------------------------------|------------------------| -| `claude` | `ANTHROPIC_API_KEY`, `CLAUDE_API_KEY` | `~/.claude.json`, `~/.claude/credentials.json`, `~/.config/claude/config.json` | -| `codex` | `OPENAI_API_KEY` | `~/.config/codex/config.json`, `~/.codex/config.json` | -| `opencode` | `OPENCODE_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY` | `~/.config/opencode/config.json` | -| `github` | `GITHUB_TOKEN`, `GH_TOKEN` | `~/.config/gh/hosts.yml` | -| `gitlab` | `GITLAB_TOKEN`, `GLAB_TOKEN`, `CI_JOB_TOKEN` | `~/.config/glab-cli/config.yml` | -| `nvidia` | `NVIDIA_API_KEY` | — | -| `generic` | — | — | -| `outlook` | — | — | - -## Creating Providers - -### From Local Credentials (Auto-Discovery) - -The easiest way to create a provider — the CLI scans your machine for existing credentials: +The fastest way to create a provider is to let the CLI discover credentials from +your shell environment: ```console $ nemoclaw provider create --name my-claude --type claude --from-existing ``` +This reads `ANTHROPIC_API_KEY` or `CLAUDE_API_KEY` from your current environment +and stores them in the provider. + ### With Explicit Credentials +Supply a credential value directly: + ```console -$ nemoclaw provider create --name my-api --type generic \ - --credential API_KEY=sk-abc123 \ - --config base_url=https://api.example.com +$ nemoclaw provider create --name my-api --type generic --credential API_KEY=sk-abc123 ``` -A bare key (without `=VALUE`) reads the value from the environment variable of that name: +### Bare Key Form + +Pass a key name without a value to read the value from the environment variable +of that name: ```console $ nemoclaw provider create --name my-api --type generic --credential API_KEY ``` -## Managing Providers +This looks up the current value of `$API_KEY` in your shell and stores it. + +## Manage Providers + +List all providers: ```console $ nemoclaw provider list +``` + +Inspect a provider: + +```console $ nemoclaw provider get my-claude +``` + +Update a provider's credentials: + +```console $ nemoclaw provider update my-claude --type claude --from-existing +``` + +Delete a provider: + +```console $ nemoclaw provider delete my-claude ``` -## Attaching Providers to Sandboxes +## Attach Providers to Sandboxes -Specify providers at sandbox creation time: +Pass one or more `--provider` flags when creating a sandbox: ```console $ nemoclaw sandbox create --provider my-claude --provider my-github -- claude ``` -Each attached provider's credentials are injected as environment variables into the sandbox. If multiple providers define the same environment variable, the first provider's value wins. +Each `--provider` flag attaches one provider. The sandbox receives all +credentials from every attached provider at runtime. :::{warning} Providers cannot be added to a running sandbox. If you need to attach an @@ -77,15 +85,6 @@ additional provider, delete the sandbox and recreate it with all required providers specified. ::: -## Privacy & Safety - -NemoClaw manages credentials with a privacy-first design: - -- **Credentials stay private** — stored separately from sandbox definitions, never in Kubernetes pod specs or container configurations. -- **Runtime-only injection** — credentials are fetched at runtime by the sandbox supervisor, minimizing exposure surface. -- **No credential leakage** — the CLI never displays credential values in its output. -- **Strict key validation** — only credential keys that are valid environment variable names (`^[A-Za-z_][A-Za-z0-9_]*$`) are injected; invalid keys are silently skipped. - ### Auto-Discovery Shortcut When the trailing command in `nemoclaw sandbox create` is a recognized tool name @@ -130,26 +129,12 @@ means credentials are not visible in container inspection, image layers, or environment dumps of the container spec. ::: -## Supported Types - -| Type | Environment Variables Injected | Typical Use | -|---|---|---| -| `claude` | `ANTHROPIC_API_KEY`, `CLAUDE_API_KEY` | Claude Code, Anthropic API | -| `codex` | `OPENAI_API_KEY` | OpenAI Codex | -| `opencode` | `OPENCODE_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY` | opencode tool | -| `github` | `GITHUB_TOKEN`, `GH_TOKEN` | GitHub API, `gh` CLI | -| `gitlab` | `GITLAB_TOKEN`, `GLAB_TOKEN`, `CI_JOB_TOKEN` | GitLab API, `glab` CLI | -| `nvidia` | `NVIDIA_API_KEY` | NVIDIA API Catalog | -| `generic` | User-defined | Any service with custom credentials | -| `outlook` | *(none --- no auto-discovery)* | Microsoft Outlook integration | - -:::{tip} -Use the `generic` type for any service not listed above. You define the -environment variable names and values yourself with `--credential`. -::: +## Supported Provider Types + +For a list of supported provider types, refer to the [Support Matrix](../about/support-matrix.md#supported-provider-types). ## Next Steps - {doc}`create-and-manage` --- full sandbox lifecycle management - {doc}`custom-containers` --- use providers with custom container images -- {doc}`/safety-and-privacy/security-model` --- why credential isolation matters \ No newline at end of file +- {doc}`../safety-and-privacy/security-model` --- why credential isolation matters \ No newline at end of file From 37f4a05bac2569d26f9601b41734d9ad4f5e5f49 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 5 Mar 2026 16:41:23 -0800 Subject: [PATCH 13/39] minor improvements --- docs/index.md | 1 - docs/sandboxes/community-sandboxes.md | 2 + docs/sandboxes/create-and-manage.md | 12 ++++++ docs/sandboxes/custom-containers.md | 2 + docs/sandboxes/index.md | 7 +++- docs/sandboxes/port-forwarding.md | 60 --------------------------- docs/sandboxes/providers.md | 4 ++ docs/sandboxes/terminal.md | 4 ++ 8 files changed, 30 insertions(+), 62 deletions(-) delete mode 100644 docs/sandboxes/port-forwarding.md diff --git a/docs/index.md b/docs/index.md index 9cd0fd73..f0a025b8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -179,7 +179,6 @@ sandboxes/create-and-manage sandboxes/providers sandboxes/custom-containers sandboxes/community-sandboxes -sandboxes/port-forwarding sandboxes/terminal ``` diff --git a/docs/sandboxes/community-sandboxes.md b/docs/sandboxes/community-sandboxes.md index 6c869a9a..3fc3224a 100644 --- a/docs/sandboxes/community-sandboxes.md +++ b/docs/sandboxes/community-sandboxes.md @@ -17,6 +17,8 @@ into a single package that you can launch with one command. ## Current Catalog +The following community sandboxes are available in the catalog. + | Sandbox | Description | |---|---| | `base` | Foundational image with system tools and dev environment | diff --git a/docs/sandboxes/create-and-manage.md b/docs/sandboxes/create-and-manage.md index bd580990..900169f8 100644 --- a/docs/sandboxes/create-and-manage.md +++ b/docs/sandboxes/create-and-manage.md @@ -43,6 +43,8 @@ with `nemoclaw cluster use `. See the ## Prerequisites +Ensure the following are installed before creating sandboxes. + - NemoClaw CLI installed (`pip install nemoclaw`) - Docker running on your machine @@ -81,6 +83,8 @@ reconnect later from another terminal or VS Code. ## List and Inspect Sandboxes +Check the status of your sandboxes and retrieve detailed information about individual ones. + List all sandboxes: ```console @@ -95,6 +99,8 @@ $ nemoclaw sandbox get my-sandbox ## Connect to a Sandbox +Access a running sandbox through an interactive SSH session or VS Code Remote-SSH. + ### Interactive SSH Open an SSH session into a running sandbox: @@ -116,6 +122,8 @@ already, and connect to the host named `my-sandbox`. ## View Logs +Stream and filter sandbox logs to monitor agent activity and diagnose policy decisions. + Stream sandbox logs: ```console @@ -145,6 +153,8 @@ diagnosing blocked connections. ## Sync Files +Transfer files between your host machine and a running sandbox. + Push files from your host into the sandbox: ```console @@ -197,6 +207,8 @@ your workload exposes a service. ## Delete Sandboxes +Remove sandboxes when they are no longer needed. Deleting a sandbox stops all processes, releases cluster resources, and purges injected credentials. + Delete a sandbox by name: ```console diff --git a/docs/sandboxes/custom-containers.md b/docs/sandboxes/custom-containers.md index 89e2231f..df9f0658 100644 --- a/docs/sandboxes/custom-containers.md +++ b/docs/sandboxes/custom-containers.md @@ -9,6 +9,8 @@ Build a custom container image and run it as a NemoClaw sandbox. ## Prerequisites +Ensure the following are installed before building custom container sandboxes. + - NemoClaw CLI installed (`pip install nemoclaw`) - Docker running on your machine - A Dockerfile for your workload diff --git a/docs/sandboxes/index.md b/docs/sandboxes/index.md index a6e649e6..1c8f66fd 100644 --- a/docs/sandboxes/index.md +++ b/docs/sandboxes/index.md @@ -9,6 +9,8 @@ A sandbox is a safe, private execution environment for an AI agent. Each sandbox ## Concepts +The following concepts are fundamental to how sandboxes operate. + ### Lifecycle A sandbox goes through these phases: @@ -40,6 +42,8 @@ See [Safety & Privacy](../safety-and-privacy/index.md) for details. ## Quick Reference +Common sandbox operations and their CLI commands. + | Task | Command | |------|---------| | Create sandbox (interactive) | `nemoclaw sandbox create` | @@ -54,9 +58,10 @@ See [Safety & Privacy](../safety-and-privacy/index.md) for details. ## In This Section +Guides for each aspect of sandbox management. + - [Create and Manage](create-and-manage.md): About creating, listing, inspecting, and connecting to sandboxes. - [Providers](providers.md): About managing external credentials privately. - [Custom Containers](custom-containers.md): About bringing your own container images. - [Community Sandboxes](community-sandboxes.md): About using pre-built sandboxes from the NemoClaw Community catalog. -- [Port Forwarding](port-forwarding.md): About forwarding local ports into sandboxes. - [Terminal](terminal.md): About using NemoClaw Terminal to monitor sandbox activity and diagnose blocked connections. diff --git a/docs/sandboxes/port-forwarding.md b/docs/sandboxes/port-forwarding.md deleted file mode 100644 index cee0a015..00000000 --- a/docs/sandboxes/port-forwarding.md +++ /dev/null @@ -1,60 +0,0 @@ - - -# Port Forwarding - -Port forwarding lets you access services running inside a sandbox from your local machine. It uses SSH tunneling through the gateway — sandbox pods are never directly accessible from outside the cluster. - -## Starting a Port Forward - -### Foreground (blocks until interrupted) - -```console -$ nemoclaw sandbox forward start 8080 my-sandbox -``` - -### Background (returns immediately) - -```console -$ nemoclaw sandbox forward start 8080 my-sandbox -d -``` - -The service is now reachable at `localhost:8080`. - -## Managing Port Forwards - -### List Active Forwards - -```console -$ nemoclaw sandbox forward list -``` - -Shows all active port forwards with sandbox name, port, PID, and status. - -### Stop a Forward - -```console -$ nemoclaw sandbox forward stop 8080 my-sandbox -``` - -## Port Forward at Create Time - -You can start a port forward when creating a sandbox: - -```console -$ nemoclaw sandbox create --from my-app:latest --forward 8080 --keep -- ./start-server.sh -``` - -The `--forward` flag implies `--keep` (the sandbox stays alive after the command exits) and starts the forward before the command runs. - -## How It Works - -Port forwarding uses OpenSSH's `-L` flag (`-L :127.0.0.1:`) through the same `ProxyCommand`-based tunnel used by `sandbox connect`. Connections to `127.0.0.1:` on your local machine are forwarded to `127.0.0.1:` inside the sandbox. - -Background forwards are tracked via PID files in `~/.config/nemoclaw/forwards/`. Deleting a sandbox automatically stops any active forwards for that sandbox. - -## NemoClaw Terminal - -The NemoClaw Terminal also supports port forwarding. When creating a sandbox in the terminal, specify ports in the **Ports** field (comma-separated, e.g., `8080,3000`). Forwarded ports appear in the sandbox table's **NOTES** column. diff --git a/docs/sandboxes/providers.md b/docs/sandboxes/providers.md index 9d17effb..07759d71 100644 --- a/docs/sandboxes/providers.md +++ b/docs/sandboxes/providers.md @@ -11,6 +11,8 @@ Create and manage providers that supply credentials to sandboxes. ## Create a Provider +Providers can be created from local environment variables or with explicit credential values. + ### From Local Credentials The fastest way to create a provider is to let the CLI discover credentials from @@ -44,6 +46,8 @@ This looks up the current value of `$API_KEY` in your shell and stores it. ## Manage Providers +List, inspect, update, and delete providers from the active cluster. + List all providers: ```console diff --git a/docs/sandboxes/terminal.md b/docs/sandboxes/terminal.md index 23452918..265f0988 100644 --- a/docs/sandboxes/terminal.md +++ b/docs/sandboxes/terminal.md @@ -89,6 +89,8 @@ The dashboard provides filtering and navigation controls: ## Keyboard Shortcuts +The following keyboard shortcuts are available in the terminal dashboard. + | Key | Action | |---|---| | `j` / `k` | Navigate down / up in the log list. | @@ -101,6 +103,8 @@ The dashboard provides filtering and navigation controls: ## Related Topics +For deeper dives into topics covered by the terminal dashboard, see the following guides. + - **Blocked connections** — Follow {doc}`../safety-and-privacy/policies` to pull the current policy, add the missing endpoint, and push an update without restarting the sandbox. - **Inference interception** — See {doc}`../safety-and-privacy/network-access-rules` for the distinction between agent traffic (routed directly) and userland traffic (routed through inference routing). - **General troubleshooting** — See {doc}`../troubleshooting/cluster-issues` for common issues and diagnostics. From 864dd92d9e9c3d5c77977ded53e118862b0345d4 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 5 Mar 2026 16:52:03 -0800 Subject: [PATCH 14/39] clean up --- docs/about/how-it-works.md | 2 +- docs/clusters/index.md | 77 ---------------------------------- docs/clusters/remote-deploy.md | 63 ---------------------------- docs/index.md | 10 ----- docs/observability/index.md | 31 -------------- docs/reference/index.md | 15 ------- 6 files changed, 1 insertion(+), 197 deletions(-) delete mode 100644 docs/clusters/index.md delete mode 100644 docs/clusters/remote-deploy.md delete mode 100644 docs/observability/index.md delete mode 100644 docs/reference/index.md diff --git a/docs/about/how-it-works.md b/docs/about/how-it-works.md index 9463e00c..233d71b4 100644 --- a/docs/about/how-it-works.md +++ b/docs/about/how-it-works.md @@ -87,7 +87,7 @@ AI inference API calls are transparently intercepted and rerouted to policy-cont ### Cluster Infrastructure -The entire platform packages into a single Docker container running k3s. Docker is the only dependency. See [Clusters](../clusters/index.md). +The entire platform packages into a single Docker container running k3s. Docker is the only dependency. ## End-to-End Flow diff --git a/docs/clusters/index.md b/docs/clusters/index.md deleted file mode 100644 index 8c1a564a..00000000 --- a/docs/clusters/index.md +++ /dev/null @@ -1,77 +0,0 @@ - - -# About Clusters - -NemoClaw packages the entire platform — Kubernetes, the gateway, networking, and pre-loaded container images — into a single Docker container. Docker is the only dependency. - -## Bootstrapping a Cluster - -```console -$ nemoclaw cluster admin deploy -``` - -This provisions a local k3s cluster in Docker, pre-loaded with all required images and Helm charts. The cluster is automatically set as the active cluster. - -### What Gets Created - -- A Docker container running k3s (lightweight Kubernetes). -- The NemoClaw gateway (control plane) deployed as a Kubernetes service. -- Pre-loaded sandbox and gateway container images. -- mTLS certificates for secure communication. -- Cluster metadata stored in `~/.config/nemoclaw/clusters/`. - -## Cluster Lifecycle - -| Command | Description | -|---------|-------------| -| `nemoclaw cluster admin deploy` | Provision or restart a cluster (idempotent). | -| `nemoclaw cluster admin stop` | Stop the cluster container (preserves state). | -| `nemoclaw cluster admin destroy` | Destroy the cluster and all its state. | -| `nemoclaw cluster status` | Check gateway connectivity and version. | -| `nemoclaw cluster list` | List all provisioned clusters. | -| `nemoclaw cluster use ` | Set the active cluster. | - -### Idempotent Deploy - -Running `deploy` again is safe. It reuses existing infrastructure or recreates only what changed. - -### Stop vs. Destroy - -- **Stop** pauses the Docker container, preserving all state (sandboxes, providers, routes). Restarting with `deploy` brings everything back. -- **Destroy** permanently removes the container, volumes, kubeconfig, metadata, and mTLS certificates. - -## Cluster Resolution - -The CLI resolves which cluster to operate on through this priority chain: - -1. `--cluster` flag (explicit). -2. `NEMOCLAW_CLUSTER` environment variable. -3. Active cluster set by `nemoclaw cluster use`. - -## Multiple Clusters - -You can manage multiple clusters simultaneously: - -```console -$ nemoclaw cluster admin deploy --name dev -$ nemoclaw cluster admin deploy --name staging --port 8081 -$ nemoclaw cluster list -$ nemoclaw cluster use dev -``` - -## Remote Deployment - -Deploy NemoClaw on a remote host via SSH. See [Remote Deployment](remote-deploy.md). - -## Cluster Info - -View deployment details: - -```console -$ nemoclaw cluster admin info -``` - -Shows the gateway endpoint, kubeconfig path, kube port, and remote host (if applicable). diff --git a/docs/clusters/remote-deploy.md b/docs/clusters/remote-deploy.md deleted file mode 100644 index d5025150..00000000 --- a/docs/clusters/remote-deploy.md +++ /dev/null @@ -1,63 +0,0 @@ - - -# Remote Deployment - -NemoClaw can deploy clusters on remote hosts via SSH. The same bootstrap flow that works locally also works on remote machines — Docker on the remote host is the only requirement. - -## Deploying Remotely - -```console -$ nemoclaw cluster admin deploy --remote user@host --ssh-key ~/.ssh/id_rsa -``` - -This: - -1. Connects to the remote host via SSH. -2. Pulls the NemoClaw cluster image on the remote Docker daemon. -3. Provisions the k3s cluster, gateway, and all components on the remote host. -4. Extracts the kubeconfig and mTLS certificates back to your local machine. -5. Sets the remote cluster as the active cluster. - -All subsequent CLI commands (sandbox create, provider management, etc.) operate against the remote cluster transparently. - -## Creating Sandboxes Remotely - -You can bootstrap a remote cluster and create a sandbox in a single command: - -```console -$ nemoclaw sandbox create --remote user@host -- claude -``` - -If no cluster exists on the remote host, one is bootstrapped automatically. - -## Accessing the Kubernetes API - -For kubectl access to a remote cluster, use the tunnel command: - -```console -$ nemoclaw cluster admin tunnel --name my-remote-cluster -``` - -This starts an SSH tunnel so `kubectl` can reach the Kubernetes API on the remote host. - -To print the SSH command without executing it: - -```console -$ nemoclaw cluster admin tunnel --name my-remote-cluster --print-command -``` - -## Managing Remote Clusters - -All lifecycle commands accept `--remote` and `--ssh-key` flags: - -```console -$ nemoclaw cluster admin stop --remote user@host --ssh-key ~/.ssh/id_rsa -$ nemoclaw cluster admin destroy --remote user@host --ssh-key ~/.ssh/id_rsa -``` - -## How It Works - -Remote deployment uses the Docker daemon over SSH (`ssh://user@host`). All operations — image pulls, container creation, health checks, kubeconfig extraction — are executed via the Docker API on the remote daemon. No additional software needs to be installed on the remote host beyond Docker. diff --git a/docs/index.md b/docs/index.md index f0a025b8..3e0c0b18 100644 --- a/docs/index.md +++ b/docs/index.md @@ -202,19 +202,10 @@ inference/manage-routes inference/connect-sandboxes ``` -```{toctree} -:caption: Clusters -:hidden: - -clusters/index -clusters/remote-deploy -``` - ```{toctree} :caption: Observability :hidden: -observability/index observability/logs observability/health ``` @@ -223,7 +214,6 @@ observability/health :caption: Reference :hidden: -reference/index about/support-matrix reference/cli reference/policy-schema diff --git a/docs/observability/index.md b/docs/observability/index.md deleted file mode 100644 index c1e89618..00000000 --- a/docs/observability/index.md +++ /dev/null @@ -1,31 +0,0 @@ - - -# About Observability - -NemoClaw provides log streaming and monitoring for sandboxes and the gateway. You can stream logs from the CLI, monitor denied actions to iterate on policies, and use the NemoClaw Terminal for a real-time dashboard. - -::::{grid} 1 1 2 2 -:gutter: 3 - -:::{grid-item-card} Sandbox Logs -:link: logs -:link-type: doc - -Stream, filter, and monitor sandbox and gateway logs from the CLI. -+++ -{bdg-secondary}`How To` -::: - -:::{grid-item-card} Cluster and Sandbox Health -:link: health -:link-type: doc - -Check cluster and sandbox health from the CLI or the NemoClaw Terminal dashboard. -+++ -{bdg-secondary}`How To` -::: - -:::: diff --git a/docs/reference/index.md b/docs/reference/index.md deleted file mode 100644 index d3f7bca1..00000000 --- a/docs/reference/index.md +++ /dev/null @@ -1,15 +0,0 @@ - - -# About Reference - -Technical reference documentation for NemoClaw. - -## In This Section - -- [CLI Reference](cli.md) — complete command tree with all flags and options. -- [Policy Schema](policy-schema.md) — full YAML policy schema for sandbox policies. -- [Environment Variables](environment-variables.md) — configuration variables for the CLI, sandbox, and gateway. -- [Architecture](architecture.md) — system architecture diagrams and component overview. From 95b2cca0f49fb70b550cd3a3b2f043d9525fe9a6 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 5 Mar 2026 17:38:12 -0800 Subject: [PATCH 15/39] run dori style guide review --- docs/about/how-it-works.md | 46 ++-- docs/about/index.md | 10 +- docs/about/release-notes.md | 5 +- docs/about/support-matrix.md | 6 +- docs/get-started/tutorials/index.md | 3 +- docs/get-started/tutorials/run-agents.md | 200 ---------------- docs/get-started/tutorials/run-claude.md | 225 ++++-------------- docs/get-started/tutorials/run-openclaw.md | 201 ++++------------ docs/get-started/tutorials/run-opencode.md | 43 ++-- docs/index.md | 6 +- docs/inference/connect-sandboxes.md | 10 +- docs/inference/create-routes.md | 18 +- docs/inference/index.md | 26 +- docs/inference/manage-routes.md | 12 +- docs/observability/health.md | 26 +- docs/observability/logs.md | 12 +- docs/reference/architecture.md | 16 +- docs/reference/cli.md | 14 +- docs/reference/environment-variables.md | 2 +- docs/reference/policy-schema.md | 22 +- docs/resources/index.md | 10 +- docs/safety-and-privacy/index.md | 10 +- .../network-access-rules.md | 12 +- docs/safety-and-privacy/policies.md | 26 +- docs/safety-and-privacy/security-model.md | 14 +- docs/sandboxes/community-sandboxes.md | 24 +- docs/sandboxes/create-and-manage.md | 16 +- docs/sandboxes/custom-containers.md | 14 +- docs/sandboxes/index.md | 16 +- docs/sandboxes/providers.md | 19 +- docs/sandboxes/terminal.md | 20 +- docs/troubleshooting/cluster-issues.md | 4 +- docs/troubleshooting/provider-issues.md | 6 +- docs/troubleshooting/sandbox-issues.md | 8 +- 34 files changed, 339 insertions(+), 763 deletions(-) delete mode 100644 docs/get-started/tutorials/run-agents.md diff --git a/docs/about/how-it-works.md b/docs/about/how-it-works.md index 233d71b4..ef6d0615 100644 --- a/docs/about/how-it-works.md +++ b/docs/about/how-it-works.md @@ -55,16 +55,16 @@ Users interact through the CLI, which communicates with a central gateway. The g Each sandbox runs inside a container as two processes: a privileged **supervisor** and a restricted **child process** (the agent). Safety and privacy are enforced through four independent layers: -- **Filesystem restrictions** — the Linux Landlock LSM controls which directories the agent can read and write. Attempts to access files outside the allowed set are blocked by the kernel. -- **System call filtering** — seccomp prevents the agent from creating raw network sockets, eliminating proxy bypass. -- **Network namespace isolation** — the agent is placed in a separate network where the only reachable destination is the proxy, preventing data exfiltration. -- **Process privilege separation** — the agent runs as an unprivileged user, protecting against privilege escalation. +- **Filesystem restrictions**: The Linux Landlock LSM controls which directories the agent can read and write. Attempts to access files outside the allowed set are blocked by the kernel. +- **System call filtering**: Seccomp prevents the agent from creating raw network sockets, eliminating proxy bypass. +- **Network namespace isolation**: The agent is placed in a separate network where the only reachable destination is the proxy, preventing data exfiltration. +- **Process privilege separation**: The agent runs as an unprivileged user, protecting against privilege escalation. -All restrictions are driven by a YAML **policy** evaluated by an embedded OPA/Rego engine. See [Safety & Privacy](../safety-and-privacy/index.md). +All restrictions are driven by a YAML **policy** evaluated by an embedded OPA/Rego engine. Refer to [Safety & Privacy](../safety-and-privacy/index.md). ### Network Proxy -Every sandbox forces all outbound traffic through an HTTP CONNECT proxy — no data leaves without inspection. The proxy: +Every sandbox forces all outbound traffic through an HTTP CONNECT proxy. No data leaves without inspection. The proxy: 1. **Identifies the requesting program** via the process table. 2. **Verifies binary integrity** with trust-on-first-use SHA256 hashing. @@ -75,15 +75,15 @@ Every sandbox forces all outbound traffic through an HTTP CONNECT proxy — no d ### Gateway -The central orchestration service providing gRPC and HTTP APIs, sandbox lifecycle management, data persistence, TLS termination, SSH tunnel gateway, and real-time status streaming. +The gateway is the central orchestration service that provides gRPC and HTTP APIs, sandbox lifecycle management, data persistence, TLS termination, SSH tunnel gateway, and real-time status streaming. ### Providers -Credentials are managed with a privacy-first design. API keys and tokens are stored separately from sandbox definitions, never appear in pod specs, and are fetched only at runtime. See [Providers](../sandboxes/providers.md). +Credentials are managed with a privacy-first design. API keys and tokens are stored separately from sandbox definitions, never appear in pod specs, and are fetched only at runtime. Refer to [Providers](../sandboxes/providers.md). ### Inference Routing -AI inference API calls are transparently intercepted and rerouted to policy-controlled backends, keeping sensitive prompts and responses on private infrastructure. See [Inference Routing](../inference/index.md). +AI inference API calls are transparently intercepted and rerouted to policy-controlled backends, keeping sensitive prompts and responses on private infrastructure. Refer to [Inference Routing](../inference/index.md). ### Cluster Infrastructure @@ -126,15 +126,15 @@ sequenceDiagram When a sandbox starts, the supervisor executes this sequence: -1. **Load policy** — fetches the YAML policy from the gateway. The policy defines all filesystem, network, and process restrictions. -2. **Fetch credentials** — retrieves provider credentials via gRPC for injection into child processes. -3. **Set up filesystem isolation** — configures Landlock rules. Writable directories are created and ownership is set automatically. -4. **Generate ephemeral TLS certificates** — creates a per-sandbox CA for transparent TLS inspection. -5. **Create network namespace** — isolates the agent's network so the only reachable destination is the proxy. -6. **Start the proxy** — launches the HTTP CONNECT proxy with OPA policy evaluation. -7. **Start the SSH server** — launches the embedded SSH daemon for interactive access. -8. **Spawn the agent** — launches the child process with reduced privileges: seccomp filters, network namespace, Landlock rules, and credentials injected as environment variables. -9. **Begin policy polling** — checks for policy updates every 30 seconds, enabling live changes without restart. +1. **Load policy**: Fetches the YAML policy from the gateway. The policy defines all filesystem, network, and process restrictions. +2. **Fetch credentials**: Retrieves provider credentials via gRPC for injection into child processes. +3. **Set up filesystem isolation**: Configures Landlock rules. Writable directories are created and ownership is set automatically. +4. **Generate ephemeral TLS certificates**: Creates a per-sandbox CA for transparent TLS inspection. +5. **Create network namespace**: Isolates the agent's network so the only reachable destination is the proxy. +6. **Start the proxy**: Launches the HTTP CONNECT proxy with OPA policy evaluation. +7. **Start the SSH server**: Launches the embedded SSH daemon for interactive access. +8. **Spawn the agent**: Launches the child process with reduced privileges: seccomp filters, network namespace, Landlock rules, and credentials injected as environment variables. +9. **Begin policy polling**: Checks for policy updates every 30 seconds, enabling live changes without restart. ## How Network Safety Works @@ -162,10 +162,10 @@ Every connection is evaluated with three pieces of context: Credentials flow through a privacy-preserving pipeline: -1. **Discovery** — the CLI scans local environment variables and config files for credentials. -2. **Upload** — credentials are sent to the gateway over mTLS and stored separately from sandbox definitions. -3. **Injection** — the supervisor fetches credentials via gRPC and injects them as environment variables. They never appear in Kubernetes pod specs. -4. **Isolation** — the sandbox policy controls which endpoints the agent can reach, so credentials cannot be exfiltrated. +1. **Discovery**: The CLI scans local environment variables and config files for credentials. +2. **Upload**: Credentials are sent to the gateway over mTLS and stored separately from sandbox definitions. +3. **Injection**: The supervisor fetches credentials through gRPC and injects them as environment variables. They never appear in Kubernetes pod specs. +4. **Isolation**: The sandbox policy controls which endpoints the agent can reach, so credentials cannot be exfiltrated. ## How Inference Privacy Works @@ -174,7 +174,7 @@ When inference routing is configured, the proxy intercepts AI API calls and keep 1. The agent calls the OpenAI/Anthropic SDK as normal. 2. The proxy TLS-terminates the connection and detects the inference API pattern. 3. The proxy strips the original authorization header and routes the request to a configured backend. -4. The backend's API key is injected by the router — the sandbox never sees it. +4. The backend's API key is injected by the router. The sandbox never sees it. 5. The response flows back to the agent transparently. This keeps prompts and responses on your private infrastructure while the agent operates as if it were calling the original API. diff --git a/docs/about/index.md b/docs/about/index.md index e7a2cfea..09f8765d 100644 --- a/docs/about/index.md +++ b/docs/about/index.md @@ -19,7 +19,7 @@ content: # NVIDIA NemoClaw Overview -NVIDIA NemoClaw is a safe, private runtime for autonomous AI agents. It provides sandboxed execution environments that protect your data, credentials, and infrastructure while giving agents the system access they need to be useful. Each sandbox enforces declarative YAML policies through Linux kernel-level isolation, a policy-enforcing network proxy, and a credential management pipeline — agents run with exactly the permissions you grant and nothing more. +NVIDIA NemoClaw is a safe, private runtime for autonomous AI agents. It provides sandboxed execution environments that protect your data, credentials, and infrastructure while giving agents the system access they need to be useful. Each sandbox enforces declarative YAML policies through Linux kernel-level isolation, a policy-enforcing network proxy, and a credential management pipeline. Agents run with exactly the permissions you grant and nothing more. You do not modify agent code to use NemoClaw. Instead, the CLI bootstraps a local Kubernetes cluster packaged in a single Docker container, creates sandboxes with the safety policies you define, and connects you to the running agent through an SSH tunnel. @@ -49,13 +49,13 @@ flowchart LR linkStyle default stroke:#76b900,stroke-width:2px ``` -The CLI bootstraps a cluster, creates sandboxes, and connects you via SSH. Inside each sandbox, an agent process runs with kernel-level filesystem restrictions while all network traffic passes through a policy-enforcing proxy. The proxy evaluates every request against an OPA policy engine before allowing or denying access. For the full architecture and end-to-end flow, refer to [How It Works](how-it-works.md). +The CLI bootstraps a cluster, creates sandboxes, and connects you through SSH. Inside each sandbox, an agent process runs with kernel-level filesystem restrictions while all network traffic passes through a policy-enforcing proxy. The proxy evaluates every request against an OPA policy engine before allowing or denying access. For the full architecture and end-to-end flow, refer to [How It Works](how-it-works.md). ## Key Capabilities :::{dropdown} Data Safety -Filesystem restrictions prevent agents from reading sensitive files or writing outside designated directories. The Linux Landlock LSM controls which paths the agent can access, and seccomp filters block raw network socket creation. Restrictions are enforced at the kernel level — they cannot be bypassed by the agent process. +Filesystem restrictions prevent agents from reading sensitive files or writing outside designated directories. The Linux Landlock LSM controls which paths the agent can access, and seccomp filters block raw network socket creation. Restrictions are enforced at the kernel level. They cannot be bypassed by the agent process. ::: :::{dropdown} Network Privacy @@ -70,12 +70,12 @@ API keys and tokens are stored separately from sandbox definitions, never appear :::{dropdown} Inference Privacy -AI API calls (OpenAI, Anthropic) are transparently intercepted by the proxy and rerouted to local or self-hosted backends such as LM Studio or vLLM. The agent calls its SDK as normal — NemoClaw swaps the destination and injects the backend's API key without the sandbox ever seeing it. Prompts and responses stay on your infrastructure. Refer to [Inference Routing](../inference/index.md) for configuration details. +AI API calls (OpenAI, Anthropic) are transparently intercepted by the proxy and rerouted to local or self-hosted backends such as LM Studio or vLLM. The agent calls its SDK as normal. NemoClaw swaps the destination and injects the backend's API key without the sandbox ever seeing it. Prompts and responses stay on your infrastructure. Refer to [Inference Routing](../inference/index.md) for configuration details. ::: :::{dropdown} Declarative Policies -YAML policies define what each sandbox can access — filesystems, network endpoints, inference routes, and credential bindings. Policies can be updated on running sandboxes without restart: push a new policy revision and the OPA engine reloads atomically within 30 seconds. Refer to [Policies](../safety-and-privacy/policies.md) for the schema and examples. +YAML policies define what each sandbox can access: filesystems, network endpoints, inference routes, and credential bindings. Policies can be updated on running sandboxes without restart: push a new policy revision and the OPA engine reloads atomically within 30 seconds. Refer to [Policies](../safety-and-privacy/policies.md) for the schema and examples. ::: :::{dropdown} Zero-Config Deployment diff --git a/docs/about/release-notes.md b/docs/about/release-notes.md index 60ae674a..92d87ffa 100644 --- a/docs/about/release-notes.md +++ b/docs/about/release-notes.md @@ -5,10 +5,9 @@ # Release Notes -This page tracks changes, new features, and fixes for each NemoClaw release. -This page covers the highlights of the release. +This page covers the highlights of each NemoClaw release. For more details, refer to the [NemoClaw GitHub Releases](https://github.com/NVIDIA/NemoClaw/releases). ## 0.1.0 -The first release of NVIDIA NemoClaw, introducing sandboxed AI agent execution with kernel-level isolation, policy enforcement, and credential management. +This is the first release of NVIDIA NemoClaw. It introduces sandboxed AI agent execution with kernel-level isolation, policy enforcement, and credential management. diff --git a/docs/about/support-matrix.md b/docs/about/support-matrix.md index c773b440..e2c23ebe 100644 --- a/docs/about/support-matrix.md +++ b/docs/about/support-matrix.md @@ -15,9 +15,9 @@ The following software and runtime dependencies are required to install and run |-------------|-----------| | **Operating System** | Linux (sandbox runtime). macOS and Linux (CLI). | | **Docker** | Required for cluster bootstrap. | -| **Python** | 3.12+ (for CLI installation via `pip`). | +| **Python** | 3.12+ (for CLI installation with `pip`). | | **Rust** | 1.88+ (for building from source). | -| **Kubernetes** | k3s (bundled — no external cluster needed). | +| **Kubernetes** | k3s (bundled, no external cluster needed). | ## Linux Kernel Features @@ -47,7 +47,7 @@ Providers supply credentials to sandboxes. NemoClaw can auto-discover credential | `gitlab` | `GITLAB_TOKEN`, `GLAB_TOKEN`, `CI_JOB_TOKEN` | GitLab API, `glab` CLI | | `nvidia` | `NVIDIA_API_KEY` | NVIDIA API Catalog | | `generic` | User-defined | Any service with custom credentials | -| `outlook` | *(none --- no auto-discovery)* | Microsoft Outlook integration | +| `outlook` | *(none, no auto-discovery)* | Microsoft Outlook integration | :::{tip} Use the `generic` type for any service not listed above. You define the diff --git a/docs/get-started/tutorials/index.md b/docs/get-started/tutorials/index.md index f6b0c904..f14eeccb 100644 --- a/docs/get-started/tutorials/index.md +++ b/docs/get-started/tutorials/index.md @@ -42,6 +42,5 @@ Set up opencode with NVIDIA inference routing, custom policies, and the full pol Run OpenClaw Safely Run Claude Safely -Run Opencode with NVIDIA Inference -Run Any Agent Safely +Run OpenCode with NVIDIA Inference ``` diff --git a/docs/get-started/tutorials/run-agents.md b/docs/get-started/tutorials/run-agents.md deleted file mode 100644 index 17dc1c31..00000000 --- a/docs/get-started/tutorials/run-agents.md +++ /dev/null @@ -1,200 +0,0 @@ - - -# Run AI Agents Safely inside NemoClaw - -This tutorial shows how to run OpenClaw inside NemoClaw with zero code changes. You will learn how the platform delivers safe, autonomous, long-running agent execution through isolation, privacy routing, and declarative policy. - -## Prerequisites - -Before you begin, ensure the following are in place. - -- NemoClaw CLI installed. Refer to [Installation](../../index.md#install-the-nemoclaw-cli). -- A running cluster. Run `nemoclaw cluster admin deploy` to create one. - -## Why NemoClaw - -Coding agents like OpenClaw run for hours, maintain state across sessions, spawn subagents, and build their own tools on the fly. Giving an agent persistent shell access, common developer tools, and the ability to spawn subagents against APIs that touch sensitive data is productive — but without an infrastructure layer, accumulated sensitive context leaks to a frontier model, unreviewed skills get filesystem and network access, and subagents inherit permissions they were never meant to have. - -NemoClaw solves this by running any agent inside an isolated sandbox with zero code changes. Agents are isolated by default and controlled by policy. - -## Run OpenClaw in One Command - -You can run OpenClaw inside a NemoClaw sandbox with a single command. The sandbox image includes OpenClaw, the onboarding flow, and a helper script that configures the gateway and prints the access URL. - -```console -$ nemoclaw sandbox create --forward 18789 -- openclaw-start -``` - -- `--forward 18789` — forwards sandbox port 18789 to your machine so the OpenClaw UI is available locally. -- `openclaw-start` — a script pre-installed in the sandbox that runs `openclaw onboard`, starts the gateway in the background, and prints the UI URL and token. - -The CLI returns when the script finishes; the port forward keeps running in the background. Once it completes: - -- **Control UI:** `http://127.0.0.1:18789/` (use the token printed during onboarding). -- **Health:** `openclaw health` from your host or inside the sandbox. - -No changes are required in OpenClaw itself; it runs as-is inside the sandbox. - -### What `openclaw-start` Does - -Under the hood, the helper script does: - -```bash -openclaw onboard -nohup openclaw gateway run > /tmp/gateway.log 2>&1 & -# Prints UI URL and token from ~/.openclaw/openclaw.json -``` - -### Step-by-Step Alternative - -If you prefer to drive steps yourself (for example, for automation or debugging): - -```console -$ nemoclaw sandbox create --keep --forward 18789 -``` - -Then inside the sandbox: - -```bash -openclaw onboard -nohup openclaw gateway run > /tmp/gateway.log 2>&1 & -exit -``` - -The sandbox stays up with the `--keep` flag, and the `--forward` flag gives you local access to the gateway. - -## Long-Lived Sandboxes and File Sync - -For development workflows, you can keep a sandbox running, sync in your repo, and run commands against it. - -```console -$ nemoclaw sandbox create --name --keep --sync -- python main.py -``` - -- `--name `: Name of the sandbox for reuse with `nemoclaw sandbox connect `. -- `--sync`: Syncs git-tracked files into `/sandbox` before running the command. -- `--keep`: Leaves the sandbox running after the command (for example, for interactive use). - -You can reconnect to the same environment later: - -```console -$ nemoclaw sandbox connect my-agent -``` - -## How NemoClaw Delivers Safety - -NemoClaw organizes controls around Access, Privacy, and Skills. Four primitives implement them. - -### Gateway — Control Plane and Auth - -The *Gateway* is the control-plane API that coordinates sandbox lifecycle and state, acts as the auth boundary, and brokers requests. Everything flows through it: sandbox create/delete, policy updates, inference route management, and policy and route delivery to sandboxes. - -When you run `nemoclaw sandbox create -- openclaw-start`, the CLI talks to the Gateway to create the sandbox, attach policy, and (optionally) set up port forwarding. Sandboxes fetch their policy and inference bundle from the Gateway and report policy load status back. - -### Sandbox — Isolation and Policy at the Edge - -The *Sandbox* is the execution environment for long-running agents. It provides skill development and verification, programmable system and network isolation, and isolated execution so agents can break things without touching the host. - -The sandbox is a supervised child process with: - -- **Filesystem isolation** — Landlock with a policy-defined allowlist: read-only versus read-write paths (for example, `/sandbox` and `/tmp` writable; `/usr` and `/etc` read-only). -- **Process identity** — runs as an unprivileged user/group (for example, `sandbox:sandbox`). -- **Network** — in Proxy mode, the sandbox gets an isolated network namespace. All outbound TCP goes through an in-sandbox HTTP CONNECT proxy. Every connection is evaluated by the Policy Engine. -- **Policy updates** — the sandbox polls the Gateway for policy updates and applies them live at sandbox scope (network and inference rules only; filesystem/process are fixed at create time). You can approve new endpoints or routes without restarting the agent. - -### Privacy Router and Inference Routing - -The *Privacy Router* is a privacy-aware LLM routing layer that keeps sensitive context on sandbox (or on-prem) compute. Only non-sensitive work goes to frontier cloud models. - -NemoClaw implements this as inference routing: - -1. The sandbox intercepts outbound HTTPS from the agent (for example, OpenAI SDK, Anthropic SDK). -2. The proxy TLS-terminates, parses the request, and detects inference API patterns (for example, `POST /v1/chat/completions`, `POST /v1/messages`). -3. A route configuration maps a routing hint (for example, `local`) to a backend: base URL, model ID, protocol, and API key. -4. The proxy forwards the request to the allowed backend and returns the response to the agent. The agent's code does not change; it still targets `api.openai.com` or similar — NemoClaw rewrites destination and model as per policy. - -You can point `local` to an on-prem model for private work and use other routes for cloud reasoning/planning. The router decides based on your cost and privacy policy, not the agent's. - -#### Create an Inference Route - -Use the CLI to create a route: - -```console -$ nemoclaw inference create \ - --routing-hint local \ - --base-url https://integrate.api.nvidia.com/ \ - --model-id nvidia/nemotron-3-nano-30b-a3b \ - --api-key $NVIDIA_API_KEY -``` - -Then allow the route in sandbox policy: - -```yaml -inference: - allowed_routes: - - local -``` - -Only routes listed in `allowed_routes` are available to that sandbox. Refer to [Inference Routing](../../inference/index.md) for the full configuration reference. - -### Policy Engine — Granular, Explainable Enforcement - -The *Policy Engine* handles policy definition and enforcement for filesystem, network, and process. Enforcement is out-of-process: the proxy and OPA/Rego run in the sandbox supervisor, not inside the agent process. The thing being guarded cannot bypass the guardrails; the constraints are structural, not behavioral. - -Policy is expressed in a YAML file with five sections. - -- `filesystem_policy`: lists directories the agent can read (`read_only`) or read and write (`read_write`). Set `include_workdir` to make the current working directory writable automatically. -- `landlock`: controls Linux Landlock LSM behavior. Use `compatibility: best_effort` to run with the best available kernel ABI. -- `process`: sets the unprivileged user and group the agent runs as (`run_as_user`, `run_as_group`). -- `network_policies`: defines named `network_policies` that pair specific binaries with the endpoints they may reach, identified by host, port, and protocol. Endpoints can include L7 HTTP rules that restrict allowed methods and paths, TLS termination, and an enforcement mode. -- `inference`: specifies which routing hints the sandbox may use through `allowed_routes`. - -Every outbound connection is evaluated by destination, method, path, and binary. When inference routing is enabled, connections that do not match any network policy are inspected for inference. If they match a known inference API pattern, they are routed according to the inference configuration. - -#### An Example of a Minimal Policy - -```yaml -version: 1 -filesystem_policy: - include_workdir: true - read_only: [/usr, /lib, /etc, /app, /var/log] - read_write: [/sandbox, /tmp, /dev/null] -landlock: - compatibility: best_effort -process: - run_as_user: sandbox - run_as_group: sandbox -inference: - allowed_routes: - - local -``` - -In this example, there are no `network_policies`, which means no explicit allowlist. With `inference.allowed_routes` set, the engine treats unknown endpoints as "inspect for inference," and only inference-shaped traffic is allowed and routed. - -Create a sandbox with this policy: - -```console -$ nemoclaw sandbox create --policy ./policy-with-inference.yaml -- claude -``` - -## Live Policy Iteration - -You can update network and inference policy on a running sandbox without restarting it. - -```console -$ nemoclaw sandbox policy get my-agent --full > current-policy.yaml -# Edit current-policy.yaml to add a network_policy or inference route -$ nemoclaw sandbox policy set my-agent --policy current-policy.yaml --wait -``` - -Refer to [Policies](../../safety-and-privacy/policies.md) for the full policy iteration workflow. - -## Next Steps - -- [Sandboxes](../../sandboxes/index.md) — full sandbox lifecycle management. -- [Inference Routing](../../inference/index.md) — route AI API calls to local or self-hosted backends. -- [Safety & Privacy](../../safety-and-privacy/index.md) — understanding and customizing sandbox policies. -- [Network Access Control](../../safety-and-privacy/network-access-rules.md) — per-binary, per-endpoint network rules. diff --git a/docs/get-started/tutorials/run-claude.md b/docs/get-started/tutorials/run-claude.md index 039fbbe9..bd63b67a 100644 --- a/docs/get-started/tutorials/run-claude.md +++ b/docs/get-started/tutorials/run-claude.md @@ -3,233 +3,112 @@ SPDX-License-Identifier: Apache-2.0 --> -# Run Claude Safely +# Run Claude Code Inside a NemoClaw Sandbox -Run Anthropic Claude as a coding agent inside a NemoClaw sandbox. This tutorial takes you from a fresh cluster to an interactive Claude session with credential management, inference routing, and policy enforcement. +This tutorial walks you through the simplest path to running Claude Code inside a NemoClaw sandbox. By the end, you will have an isolated environment with Claude Code running, your credentials securely injected, and a default policy controlling what the agent can access. -## Prerequisites +**What you will learn:** -- NemoClaw CLI installed. Refer to [Installation](../../index.md#install-the-nemoclaw-cli). -- Docker installed and running. -- An Anthropic API key available as `ANTHROPIC_API_KEY` in your environment or in `~/.claude.json`. +- Creating a sandbox with a single command +- How NemoClaw auto-discovers provider credentials +- What the default policy allows and denies +- Connecting to a sandbox and working inside it -## Step 1: Deploy a Cluster +## Step 1: Create a Sandbox -NemoClaw runs sandboxes on a lightweight Kubernetes cluster packaged in a single Docker container. +Run the following command: ```console -$ nemoclaw cluster admin deploy +$ nemoclaw sandbox create -- claude ``` -Verify that the cluster is healthy. +This single command does several things: -```console -$ nemoclaw cluster status -``` +1. **Bootstraps the runtime.** If this is your first time using NemoClaw, the CLI provisions a local k3s cluster inside Docker and deploys the NemoClaw control plane. This happens once---subsequent commands reuse the existing cluster. +2. **Auto-discovers credentials.** The CLI detects that `claude` is a recognized tool and looks for your Anthropic credentials. It reads the `ANTHROPIC_API_KEY` environment variable and creates a provider automatically. +3. **Creates the sandbox.** The CLI provisions an isolated environment and applies the default policy. The policy allows Claude Code to reach `api.anthropic.com` and a small set of supporting endpoints while blocking everything else. +4. **Drops you into the sandbox.** You land in an interactive SSH session inside the sandbox, ready to work. -You should see the cluster version and a healthy status. If you already have a running cluster, skip this step. +:::{note} +The first bootstrap takes a few minutes depending on your network speed. The CLI prints progress as each component starts. Subsequent sandbox creations are much faster. +::: -## Step 2: Create a Claude Sandbox +## Step 2: Work Inside the Sandbox -The simplest way to start Claude in a sandbox auto-discovers your local credentials and drops you into an interactive shell. +You are now in an SSH session inside the sandbox. Start Claude Code: ```console -$ nemoclaw sandbox create --name my-claude -- claude +$ claude ``` -- `--name my-claude` — gives the sandbox a name for reconnection and management. -- `-- claude` — tells NemoClaw to auto-discover Anthropic credentials (`ANTHROPIC_API_KEY`, `CLAUDE_API_KEY`, `~/.claude.json`) and launch Claude inside the sandbox. - -The CLI creates a provider from your local credentials, uploads them to the gateway, and opens an interactive SSH session into the sandbox. - -### With File Sync and Additional Providers - -For working on a project with GitHub access: +Your credentials are available as environment variables inside the sandbox. You can verify this: ```console -$ nemoclaw sandbox create \ - --name my-claude \ - --provider my-github \ - --sync \ - -- claude -``` - -- `--provider my-github` — attaches a previously created GitHub provider (repeatable for multiple providers). -- `--sync` — pushes local git-tracked files to `/sandbox` in the container. - -## Step 3: Work Inside the Sandbox - -Once connected, you are inside an isolated environment. Provider credentials are available as environment variables. - -```console -sandbox@my-claude:~$ echo $ANTHROPIC_API_KEY +$ echo $ANTHROPIC_API_KEY sk-ant-... - -sandbox@my-claude:~$ claude ``` -The sandbox enforces its safety and privacy policy: - -- Filesystem access is restricted to allowed directories. -- All network connections go through the policy-enforcing proxy. -- Only explicitly permitted hosts and programs can reach the internet. +The sandbox has a working directory at `/sandbox` where you can create and edit files. Claude Code has access to standard development tools---git, common language runtimes, and package managers---within the boundaries set by the policy. -## Step 4: Route Inference to a Private Model +## Step 3: Check Sandbox Status -By default, Claude's API calls go through the sandbox proxy. You can reroute them to a private or self-hosted model to keep prompts and responses on your own infrastructure. +Open a second terminal on your host machine. You can inspect running sandboxes from there. -### Create the Route +List all sandboxes: ```console -$ nemoclaw inference create \ - --routing-hint local \ - --base-url https://integrate.api.nvidia.com/ \ - --model-id nvidia/nemotron-3-nano-30b-a3b \ - --api-key $NVIDIA_API_KEY +$ nemoclaw sandbox list ``` -### Apply a Policy with the Route - -Create a policy file `claude-policy.yaml`: - -```yaml -version: 1 -filesystem_policy: - include_workdir: true - read_only: [/usr, /lib, /etc, /app, /var/log] - read_write: [/sandbox, /tmp, /dev/null] -landlock: - compatibility: best_effort -process: - run_as_user: sandbox - run_as_group: sandbox -network_policies: - anthropic: - endpoints: - - host: api.anthropic.com - port: 443 - binaries: - - path_patterns: ["**/claude"] - - path_patterns: ["**/node"] -inference: - allowed_routes: - - local -``` - -This policy explicitly allows the Claude binary to reach `api.anthropic.com` and routes any other inference-shaped traffic to the `local` backend. - -Update the running sandbox with the new policy. +For a live dashboard view, launch the NemoClaw Terminal: ```console -$ nemoclaw sandbox policy set my-claude --policy claude-policy.yaml --wait +$ nemoclaw gator ``` -Claude continues to work as normal — it still calls the Anthropic SDK as usual, but NemoClaw controls which requests go to the cloud and which are routed to your private model. +The terminal dashboard shows sandbox status, active network connections, and policy decisions in real time. -## Step 5: Monitor and Iterate on Policy +## Step 4: Connect from VS Code -Watch sandbox logs to see which connections are allowed or denied. +If you prefer to work in VS Code rather than a terminal, you can connect using Remote-SSH. -```console -$ nemoclaw sandbox logs my-claude --tail --source sandbox -``` - -If Claude needs access to additional endpoints (for example, GitHub for code retrieval or npm for package installation), pull the current policy, add the missing entry, and push it back. +First, export the sandbox's SSH configuration: ```console -$ nemoclaw sandbox policy get my-claude --full > current-policy.yaml +$ nemoclaw sandbox ssh-config my-sandbox >> ~/.ssh/config ``` -Edit `current-policy.yaml` to add a `network_policies` entry, then push it. +Then open VS Code, install the **Remote - SSH** extension if you have not already, and connect to the host named `my-sandbox`. VS Code opens a full editor session inside the sandbox. -```console -$ nemoclaw sandbox policy set my-claude --policy current-policy.yaml --wait -``` - -Refer to [Policies](../../safety-and-privacy/policies.md) for the full policy iteration workflow. +:::{tip} +Replace `my-sandbox` with the actual name of your sandbox. Run `nemoclaw sandbox list` to find it if you did not specify a name at creation time. +::: -## Step 6: Reconnect or Open a Second Session +## Step 5: Clean Up -You can reconnect to the sandbox from any terminal. +When you are done, exit the sandbox shell: ```console -$ nemoclaw sandbox connect my-claude +$ exit ``` -For VS Code Remote-SSH access: +Then delete the sandbox: ```console -$ nemoclaw sandbox ssh-config my-claude >> ~/.ssh/config +$ nemoclaw sandbox delete my-sandbox ``` -Then connect via VS Code's Remote-SSH extension to the host `my-claude`. - -## Step 7: Verify Policy Enforcement - -With Claude running inside the sandbox, confirm that the policy is doing its job. - -### Test a Blocked Action - -From inside the sandbox, attempt to reach an endpoint that is not in the policy. +:::{tip} +Use the `--keep` flag when you want the sandbox to stay alive after the command exits. This is useful when you plan to connect later or want to iterate on the policy while the sandbox runs. ```console -sandbox@my-claude:~$ curl https://example.com +$ nemoclaw sandbox create --keep -- claude ``` - -The proxy blocks the connection because `example.com` is not in any `network_policies` entry and the request is not an inference API pattern. You should see a connection-refused or proxy-denied error. - -### Test a Blocked File Access - -Try to write to a read-only directory. - -```console -sandbox@my-claude:~$ touch /usr/test-file -touch: cannot touch '/usr/test-file': Permission denied -``` - -Landlock prevents writes outside the `read_write` paths defined in your policy. - -### Check the Denial in Logs - -From your host, view the sandbox logs to see the deny entries. - -```console -$ nemoclaw sandbox logs my-claude --tail --source sandbox -``` - -Look for log lines with `action: deny` showing the destination host, port, binary, and the reason. This confirms that the policy engine is evaluating every outbound connection and only allowing traffic that matches your policy. - -### Confirm Claude Works Through Policy - -Ask Claude to perform a task — for example, reading a file in `/sandbox` or writing code. Claude operates normally within the boundaries of the policy. If you configured an inference route in Step 4, the logs show whether inference calls were intercepted and routed to your private backend. - -```console -sandbox@my-claude:~$ claude "List the files in /sandbox" -``` - -## Step 8: Clean Up - -Delete the sandbox when you are finished to free cluster resources. - -```console -$ nemoclaw sandbox delete my-claude -``` - -## Quick Reference - -| Goal | How | -| ---- | --- | -| Launch Claude | `nemoclaw sandbox create --name my-claude -- claude` | -| Launch with file sync | `nemoclaw sandbox create --name my-claude --sync -- claude` | -| Reconnect | `nemoclaw sandbox connect my-claude` | -| Route inference to a private model | `nemoclaw inference create --routing-hint local --base-url --model-id --api-key ` and set `inference.allowed_routes: [local]` in policy | -| Update policy live | `nemoclaw sandbox policy set my-claude --policy updated.yaml --wait` | -| View logs | `nemoclaw sandbox logs my-claude --tail --source sandbox` | -| Delete | `nemoclaw sandbox delete my-claude` | +::: ## Next Steps -- [Sandboxes](../../sandboxes/index.md) — full sandbox lifecycle management. -- [Providers](../../sandboxes/providers.md) — managing credentials and auto-discovery. -- [Inference Routing](../../inference/index.md) — route AI API calls to local or self-hosted backends. -- [Safety & Privacy](../../safety-and-privacy/index.md) — understanding and customizing sandbox policies. +- {doc}`../../sandboxes/create-and-manage`: Understand the isolation model and sandbox lifecycle +- {doc}`../../sandboxes/providers`: How credentials are injected without exposing them to agent code +- {doc}`../../safety-and-privacy/policies`: Learn how the default policy works and how to customize it +- {doc}`../../safety-and-privacy/network-access-rules`: Dig into the network proxy and per-endpoint rules diff --git a/docs/get-started/tutorials/run-openclaw.md b/docs/get-started/tutorials/run-openclaw.md index 22551889..d9a7d240 100644 --- a/docs/get-started/tutorials/run-openclaw.md +++ b/docs/get-started/tutorials/run-openclaw.md @@ -3,199 +3,102 @@ SPDX-License-Identifier: Apache-2.0 --> -# Run OpenClaw Safely +# Run OpenClaw Inside a NemoClaw Sandbox -Run OpenClaw inside a NemoClaw sandbox with zero code changes. This tutorial takes you from a fresh cluster to an OpenClaw instance with inference routing and policy enforcement. +This tutorial shows you how to launch a community sandbox using the `--from` flag. Community sandboxes are pre-built configurations published to the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) repository. They bundle a container image, a tailored policy, and optional skills into a single package you can run with one command. -## Prerequisites - -- NemoClaw CLI installed. Refer to [Installation](../../index.md#install-the-nemoclaw-cli). -- Docker installed and running. - -## Step 1: Deploy a Cluster - -NemoClaw runs sandboxes on a lightweight Kubernetes cluster packaged in a single Docker container. - -```console -$ nemoclaw cluster admin deploy -``` - -Verify that the cluster is healthy. - -```console -$ nemoclaw cluster status -``` - -You should see the cluster version and a healthy status. If you already have a running cluster, skip this step. - -## Step 2: Launch OpenClaw +**What you will learn:** -The sandbox image includes OpenClaw, the onboarding flow, and a helper script that configures the gateway and prints the access URL. One command starts everything. +- What community sandboxes are and how they differ from default sandboxes +- How the `--from` flag pulls and builds a complete sandbox configuration +- How to inspect the bundled policy that ships with a community sandbox -```console -$ nemoclaw sandbox create --name my-openclaw --forward 18789 -- openclaw-start -``` - -- `--name my-openclaw` — gives the sandbox a name for reconnection and management. -- `--forward 18789` — forwards sandbox port 18789 to your machine so the OpenClaw UI is reachable locally. -- `openclaw-start` — runs `openclaw onboard`, starts the OpenClaw gateway in the background, and prints the UI URL and token. - -The CLI returns when the script finishes. The port forward keeps running in the background. - -## Step 3: Access the OpenClaw UI - -Once the sandbox is ready, open the Control UI and verify health. - -- **Control UI:** `http://127.0.0.1:18789/` — use the token printed during onboarding. -- **Health check:** run `openclaw health` from your host or inside the sandbox. - -No changes are required in OpenClaw itself. It runs as-is inside the sandbox with full isolation. - -### What `openclaw-start` Does - -Under the hood, the helper script runs: - -```bash -openclaw onboard -nohup openclaw gateway run > /tmp/gateway.log 2>&1 & -``` - -It then prints the UI URL and token from `~/.openclaw/openclaw.json`. - -## Step 4: Route Inference to a Private Model - -By default, the sandbox blocks outbound traffic that does not match an explicit network policy. To route OpenClaw's inference calls to a private or self-hosted model, create an inference route and allow it in sandbox policy. +## Prerequisites -### Create the Route +Before you begin, make sure you have: -```console -$ nemoclaw inference create \ - --routing-hint local \ - --base-url https://integrate.api.nvidia.com/ \ - --model-id nvidia/nemotron-3-nano-30b-a3b \ - --api-key $NVIDIA_API_KEY -``` +- **Docker** running on your machine. +- **NVIDIA GPU with drivers** installed. Required for GPU-accelerated workloads in the OpenClaw sandbox. +- [**NemoClaw CLI** installed](../../index.md#install-the-nemoclaw-cli) -### Apply a Policy with the Route - -Create a policy file `openclaw-policy.yaml`: - -```yaml -version: 1 -filesystem_policy: - include_workdir: true - read_only: [/usr, /lib, /etc, /app, /var/log] - read_write: [/sandbox, /tmp, /dev/null] -landlock: - compatibility: best_effort -process: - run_as_user: sandbox - run_as_group: sandbox -inference: - allowed_routes: - - local -``` +## Step 1: Create a Sandbox from the Community Image -Update the running sandbox with the new policy. +Run the following command: ```console -$ nemoclaw sandbox policy set my-openclaw --policy openclaw-policy.yaml --wait +$ nemoclaw sandbox create --from openclaw --keep ``` -OpenClaw's inference calls are now transparently intercepted and routed to the configured backend. The agent's code does not change — it still targets the original API, and NemoClaw rewrites the destination and model per policy. - -## Step 5: Monitor and Iterate on Policy - -Watch sandbox logs to see which connections are allowed or denied. +The `--from` flag tells the CLI to pull a sandbox definition from the NemoClaw Community catalog. Here is what happens: -```console -$ nemoclaw sandbox logs my-openclaw --tail --source sandbox -``` +1. **Fetches the definition.** The CLI downloads the OpenClaw sandbox definition from the NemoClaw-Community repository. This includes a Dockerfile, a policy YAML, and any bundled skills. +2. **Builds the image.** The CLI builds the Dockerfile locally using Docker. The image includes all tools and dependencies that OpenClaw needs. +3. **Applies the bundled policy.** Instead of the generic default policy, the sandbox starts with a policy specifically written for the OpenClaw workload---it allows the endpoints and binaries that OpenClaw requires. +4. **Creates and keeps the sandbox.** The `--keep` flag ensures the sandbox stays running after creation so you can connect and disconnect freely. -If you see denied actions that should be allowed, pull the current policy, add the missing network policy entry, and push it back. +:::{note} +The first build takes longer because Docker needs to pull base layers and install dependencies. Subsequent creates reuse the cached image. +::: -```console -$ nemoclaw sandbox policy get my-openclaw --full > current-policy.yaml -``` +## Step 2: Connect to the Sandbox -Edit `current-policy.yaml` to add a `network_policies` entry for the denied endpoint, then push it. +After the sandbox is running, connect to it: ```console -$ nemoclaw sandbox policy set my-openclaw --policy current-policy.yaml --wait +$ nemoclaw sandbox connect ``` -Refer to [Policies](../../safety-and-privacy/policies.md) for the full policy iteration workflow. +Replace `` with the sandbox name shown in the creation output. If you did not specify a name with `--name`, the CLI assigns one automatically. Run `nemoclaw sandbox list` to find it. -## Step 6: Reconnect or Open a Second Session +## Step 3: Explore the Environment -You can reconnect to the sandbox from any terminal. +The sandbox comes pre-configured for the OpenClaw workload. The tools, runtimes, and libraries that OpenClaw needs are already installed in the container image. The policy is tuned to allow the specific network endpoints and operations that OpenClaw uses, so you can start working immediately without policy adjustments. -```console -$ nemoclaw sandbox connect my-openclaw -``` +## Step 4: Check the Bundled Policy -For VS Code Remote-SSH access: +To see exactly what the sandbox is allowed to do, pull the full policy: ```console -$ nemoclaw sandbox ssh-config my-openclaw >> ~/.ssh/config +$ nemoclaw sandbox policy get --full ``` -Then connect via VS Code's Remote-SSH extension to the host `my-openclaw`. - -## Step 7: Verify Policy Enforcement - -With the sandbox running and the OpenClaw UI accessible, confirm that the policy is doing its job. - -### Confirm the UI Is Accessible +This outputs the complete policy YAML, including: -Open `http://127.0.0.1:18789/` in your browser and sign in with the token printed during onboarding. You should see the OpenClaw control dashboard. +- **Network policies**---which hosts and ports the sandbox can reach, and which binaries are allowed to initiate those connections +- **Filesystem policy**---which paths are read-only and which are read-write +- **Process restrictions**---the user and group the sandbox runs as +- **Inference rules**---which inference routing hints are allowed -### Test a Blocked Action +Reviewing the bundled policy is a good way to understand what a community sandbox has access to before you start using it for sensitive work. -From inside the sandbox, attempt to reach an endpoint that is not in the policy. +:::{tip} +You can save the policy to a file for reference or as a starting point for customization: ```console -sandbox@my-openclaw:~$ curl https://example.com +$ nemoclaw sandbox policy get --full > openclaw-policy.yaml ``` +::: -The proxy blocks the connection because `example.com` is not in any `network_policies` entry and the request is not an inference API pattern. You should see a connection-refused or proxy-denied error. +## Step 5: Clean Up -### Check the Denial in Logs - -From your host, view the sandbox logs to see the deny entry. +When you are finished, exit the sandbox if you are connected: ```console -$ nemoclaw sandbox logs my-openclaw --tail --source sandbox +$ exit ``` -Look for a log line with `action: deny` showing the destination host, port, binary (`curl`), and the reason. This confirms that the policy engine is evaluating every outbound connection and only allowing traffic that matches your policy. - -### Confirm Inference Routing - -If you configured an inference route in Step 4, ask OpenClaw to perform a task that triggers an inference call through the UI. The logs show whether the request was intercepted and routed to your configured backend rather than the original API endpoint. - -## Step 8: Clean Up - -Delete the sandbox when you are finished to free cluster resources. +Then delete it: ```console -$ nemoclaw sandbox delete my-openclaw +$ nemoclaw sandbox delete ``` -## Quick Reference - -| Goal | How | -| ---- | --- | -| Launch OpenClaw | `nemoclaw sandbox create --name my-openclaw --forward 18789 -- openclaw-start` | -| Reconnect | `nemoclaw sandbox connect my-openclaw` | -| Route inference to a private model | `nemoclaw inference create --routing-hint local --base-url --model-id --api-key ` and set `inference.allowed_routes: [local]` in policy | -| Update policy live | `nemoclaw sandbox policy set my-openclaw --policy updated.yaml --wait` | -| View logs | `nemoclaw sandbox logs my-openclaw --tail --source sandbox` | -| Delete | `nemoclaw sandbox delete my-openclaw` | +:::{note} +The NemoClaw Community repository accepts contributions. If you build a sandbox configuration that would be useful to others, you can submit it to the [NemoClaw-Community](https://github.com/NVIDIA/NemoClaw-Community) repository. +::: ## Next Steps -- [Sandboxes](../../sandboxes/index.md) — full sandbox lifecycle management. -- [Inference Routing](../../inference/index.md) — route AI API calls to local or self-hosted backends. -- [Safety & Privacy](../../safety-and-privacy/index.md) — understanding and customizing sandbox policies. -- [Network Access Control](../../safety-and-privacy/network-access-rules.md) — per-binary, per-endpoint network rules. +- {doc}`../../sandboxes/community-sandboxes`: Full reference on community sandbox definitions, available images, and how to contribute your own +- {doc}`../../safety-and-privacy/policies`: Understand the policy format and how to customize what a sandbox can do +- {doc}`../../sandboxes/create-and-manage`: The isolation model and lifecycle behind every sandbox \ No newline at end of file diff --git a/docs/get-started/tutorials/run-opencode.md b/docs/get-started/tutorials/run-opencode.md index 357921da..841320d8 100644 --- a/docs/get-started/tutorials/run-opencode.md +++ b/docs/get-started/tutorials/run-opencode.md @@ -5,7 +5,7 @@ # Run OpenCode with NVIDIA Inference -This tutorial walks through a realistic setup where you run [OpenCode](https://opencode.ai) inside a NemoClaw sandbox with inference routed to NVIDIA API endpoints. Along the way, you will hit policy problems, diagnose them from logs, write a custom policy, and configure inference routing --- the full policy iteration loop. +This tutorial walks through a realistic setup where you run [opencode](https://opencode.ai) inside a NemoClaw sandbox with inference routed to NVIDIA API endpoints. Along the way, you will hit policy problems, diagnose them from logs, write a custom policy, and configure inference routing. This is the full policy iteration loop. **What you will learn:** @@ -21,7 +21,6 @@ Before you begin: - **`NVIDIA_API_KEY` environment variable** set on your host machine with a valid NVIDIA API key - **NemoClaw CLI** installed (`pip install nemoclaw`) -- Docker installed and running. ## Step 1: Create the Provider @@ -33,7 +32,7 @@ $ nemoclaw provider create --name nvidia --type nvidia --from-existing The `--from-existing` flag tells the CLI to discover credentials from your local environment. It finds `NVIDIA_API_KEY` and stores it securely. The provider is now available to attach to any sandbox. -Verify it was created: +Verify the provider: ```console $ nemoclaw provider list @@ -41,17 +40,17 @@ $ nemoclaw provider list ## Step 2: Create the Sandbox -Create a sandbox with the NVIDIA provider attached and OpenCode as the startup command: +Create a sandbox with the NVIDIA provider attached and opencode as the startup command: ```console $ nemoclaw sandbox create --name opencode-sandbox --provider nvidia --keep -- opencode ``` -The `--keep` flag keeps the sandbox alive after you exit, which you will need for the iteration steps ahead. The CLI creates the sandbox with the default policy, injects the NVIDIA credentials, and starts OpenCode. +The `--keep` flag keeps the sandbox alive after you exit, which you will need for the iteration steps ahead. The CLI creates the sandbox with the default policy, injects the NVIDIA credentials, and starts opencode. ## Step 3: Hit a Problem -Try using OpenCode inside the sandbox. You will likely find that calls to NVIDIA inference endpoints fail or behave unexpectedly. The default policy is designed around Claude Code, not OpenCode. +Try using opencode inside the sandbox. You will likely find that calls to NVIDIA inference endpoints fail or behave unexpectedly. The default policy is designed around Claude Code, not opencode. Open a second terminal and check the logs: @@ -62,7 +61,7 @@ $ nemoclaw sandbox logs opencode-sandbox --tail Or launch the NemoClaw Terminal for a live view: ```console -$ nemoclaw term +$ nemoclaw gator ``` Look for lines like these in the output: @@ -73,18 +72,18 @@ action=deny host=opencode.ai binary=/usr/bin/node reas action=inspect_for_inference host=integrate.api.nvidia.com binary=/bin/bash ``` -These log entries tell you exactly what is being blocked and why. +These log entries tell you exactly what the policy blocks and why. ## Step 4: Understand Why -The default policy has a `nvidia_inference` network policy entry, but it is configured for a narrow set of binaries --- typically `/usr/local/bin/claude` and `/usr/bin/node`. If opencode makes HTTP calls through a different binary (its own binary, `curl`, or a shell subprocess), those connections do not match any policy rule and get denied. +The default policy has a `nvidia_inference` network policy entry, but it is configured for a narrow set of binaries---typically `/usr/local/bin/claude` and `/usr/bin/node`. If opencode makes HTTP calls through a different binary (its own binary, `curl`, or a shell subprocess), those connections do not match any policy rule and get denied. There are two separate problems: 1. **opencode's own traffic.** opencode contacts `opencode.ai` for its API and `integrate.api.nvidia.com` for inference. Neither of these endpoints has a matching policy entry for the binaries opencode uses. 2. **No opencode.ai endpoint.** The default policy has no entry for `opencode.ai` at all. Even if the binary matched, the destination is not listed. -This is the expected behavior --- NemoClaw denies by default. You need to write a policy that explicitly allows what opencode needs. +This is the expected behavior---NemoClaw denies by default. You need to write a policy that explicitly allows what opencode needs. ## Step 5: Write a Custom Policy @@ -185,13 +184,13 @@ network_policies: Compared to the default policy, this adds: -- **`opencode_api`** --- allows opencode and Node.js to reach `opencode.ai:443` -- **Broader `nvidia_inference` binaries** --- adds `/usr/local/bin/opencode`, `/usr/bin/curl`, and `/bin/bash` so opencode's subprocesses can reach the NVIDIA endpoint -- **`inference.allowed_routes`** --- includes `nvidia` so inference routing works for userland code +- **`opencode_api`**---allows opencode and Node.js to reach `opencode.ai:443` +- **Broader `nvidia_inference` binaries**---adds `/usr/local/bin/opencode`, `/usr/bin/curl`, and `/bin/bash` so opencode's subprocesses can reach the NVIDIA endpoint +- **`inference.allowed_routes`**---includes `nvidia` so inference routing works for userland code - **GitHub access** scoped for opencode's git operations :::{warning} -The `filesystem_policy`, `landlock`, and `process` sections are static --- they are set at sandbox creation time and cannot be changed on a running sandbox. If you need to modify these, you must delete and recreate the sandbox. The `network_policies` and `inference` sections are dynamic and can be hot-reloaded. +The `filesystem_policy`, `landlock`, and `process` sections are static---they are set at sandbox creation time and cannot be changed on a running sandbox. If you need to modify these, you must delete and recreate the sandbox. The `network_policies` and `inference` sections are dynamic and can be hot-reloaded. ::: ## Step 6: Push the Policy @@ -214,7 +213,7 @@ The latest revision should show status `loaded`. ## Step 7: Set Up Inference Routing -So far, you have allowed the opencode *agent* to reach `integrate.api.nvidia.com` directly via network policy. But what about code that opencode writes and runs inside the sandbox? If that code calls an LLM API, it goes through the privacy router --- a separate mechanism. +So far, you have allowed the opencode *agent* to reach `integrate.api.nvidia.com` directly through network policy. But what about code that opencode writes and runs inside the sandbox? If that code calls an LLM API, it goes through the privacy router---a separate mechanism. Create an inference route so userland code can access NVIDIA models: @@ -233,7 +232,7 @@ $ nemoclaw sandbox policy set opencode-sandbox --policy opencode-policy.yaml --w ``` :::{note} -The distinction matters: **network policies** control which hosts the agent binary can reach directly. **Inference routes** control where LLM API calls from userland code (scripts, notebooks, applications the agent writes) get routed. They are two separate enforcement points. +The *network policies* control which hosts the agent binary can reach directly. The *inference routes* control where LLM API calls from userland code (scripts, notebooks, applications the agent writes) get routed. These are two separate enforcement points. ::: ## Step 8: Verify @@ -246,7 +245,7 @@ $ nemoclaw sandbox logs opencode-sandbox --tail You should no longer see `action=deny` lines for the endpoints you added. Connections to `opencode.ai`, `integrate.api.nvidia.com`, and GitHub should show `action=allow`. -If you still see denials, read the log line carefully --- it tells you the exact host, port, and binary that was blocked. Add the missing entry to your policy and push again. This observe-modify-push cycle is the policy iteration loop, and it is the normal workflow for getting a new tool running in NemoClaw. +If you still see denials, read the log line carefully. It tells you the exact host, port, and binary that was blocked. Add the missing entry to your policy and push again. This observe-modify-push cycle is the policy iteration loop, and it is the normal workflow for getting a new tool running in NemoClaw. ## Clean Up @@ -258,8 +257,8 @@ $ nemoclaw sandbox delete opencode-sandbox ## Next Steps -- [Policies](../../safety-and-privacy/policies.md) --- full reference on policy YAML structure, static vs dynamic fields, and enforcement modes -- [Network Access Control](../../safety-and-privacy/network-access-rules.md) --- how the proxy evaluates network rules, L4 vs L7 inspection, and TLS termination -- [Inference Routing](../../inference/index.md) --- inference route configuration, protocol detection, and transparent rerouting -- [Providers](../../sandboxes/providers.md) --- provider types, credential discovery, and manual vs automatic creation -- [Security Model](../../safety-and-privacy/security-model.md) --- the four protection layers and how they interact +- {doc}`../../safety-and-privacy/policies`: Full reference on policy YAML structure, static and dynamic fields, and enforcement modes +- {doc}`../../safety-and-privacy/network-access-rules`: How the proxy evaluates network rules, L4 and L7 inspection, and TLS termination +- {doc}`../../inference/index`: Inference route configuration, protocol detection, and transparent rerouting +- {doc}`../../sandboxes/providers`: Provider types, credential discovery, and manual and automatic creation +- {doc}`../../safety-and-privacy/security-model`: The four protection layers and how they interact diff --git a/docs/index.md b/docs/index.md index 3e0c0b18..5dc393d1 100644 --- a/docs/index.md +++ b/docs/index.md @@ -29,7 +29,7 @@ content: [![PyPI](https://img.shields.io/badge/PyPI-nemoclaw-orange?logo=pypi)](https://pypi.org/project/nemoclaw/) NemoClaw is the safe, private runtime for autonomous AI agents. It provides sandboxed execution environments -that protect your data, credentials, and infrastructure — agents run with exactly the permissions they need and +that protect your data, credentials, and infrastructure. Agents run with exactly the permissions they need and nothing more, governed by declarative policies that prevent unauthorized file access, data exfiltration, and uncontrolled network activity. @@ -76,14 +76,14 @@ Claude Code works out of the box with the default policy. $ nemoclaw sandbox create --from openclaw ``` -The `--from` flag pulls from the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) catalog --- a collection of domain-specific sandbox images bundled with their own containers, policies, and skills. +The `--from` flag pulls from the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) catalog---a collection of domain-specific sandbox images bundled with their own containers, policies, and skills. ::: :::: The agent runs with filesystem, network, process, and inference protection active. Credentials stay inside the sandbox, network access follows your policy, and inference traffic remains private. A single YAML policy controls all four protection layers and is hot-reloadable on a running sandbox. -For OpenCode or Codex, see the [](get-started/tutorials/run-opencode.md) tutorial for agent-specific setup. +For OpenCode or Codex, refer to the [](get-started/tutorials/run-opencode.md) tutorial for agent-specific setup. --- diff --git a/docs/inference/connect-sandboxes.md b/docs/inference/connect-sandboxes.md index 99db55d7..b46a0bf9 100644 --- a/docs/inference/connect-sandboxes.md +++ b/docs/inference/connect-sandboxes.md @@ -35,7 +35,7 @@ The `inference` section is a dynamic field, so you can add or remove routing hin ## How It Works -Once a sandbox has `allowed_routes` configured, the proxy intercepts outbound connections that do not match any explicit `network_policies` entry. If the request matches a known inference API pattern (e.g., `POST /v1/chat/completions`), the proxy: +After a sandbox has `allowed_routes` configured, the proxy intercepts outbound connections that do not match any explicit `network_policies` entry. If the request matches a known inference API pattern (for example, `POST /v1/chat/completions`), the proxy: 1. TLS-terminates the connection. 2. Strips the original authorization header. @@ -56,7 +56,7 @@ $ nemoclaw sandbox create --keep -- claude ## Next Steps -- {doc}`create-routes` --- register new inference backends. -- {doc}`manage-routes` --- list, update, and delete routes. -- [Policies](../safety-and-privacy/policies.md) --- the full policy iteration workflow. -- [Network Access Control](../safety-and-privacy/network-access-rules.md) --- how agent traffic differs from userland inference traffic. +- {doc}`create-routes`: Register new inference backends. +- {doc}`manage-routes`: List, update, and delete routes. +- [Policies](../safety-and-privacy/policies.md): The full policy iteration workflow. +- [Network Access Control](../safety-and-privacy/network-access-rules.md): How agent traffic differs from userland inference traffic. diff --git a/docs/inference/create-routes.md b/docs/inference/create-routes.md index 9a776950..71f9f765 100644 --- a/docs/inference/create-routes.md +++ b/docs/inference/create-routes.md @@ -8,7 +8,7 @@ Use `nemoclaw inference create` to register a new inference backend that sandboxes can route AI API calls to. :::{note} -Inference routes are for **userland code** --- scripts and programs that the agent writes and executes inside the sandbox. The agent's own API traffic flows directly through network policies, not through inference routing. See {doc}`../safety-and-privacy/network-access-rules` for the distinction between agent traffic and userland traffic. +Inference routes are for **userland code**: scripts and programs that the agent writes and executes inside the sandbox. The agent's own API traffic flows directly through network policies, not through inference routing. Refer to {doc}`../safety-and-privacy/network-access-rules` for the distinction between agent traffic and userland traffic. ::: ## Create a Route @@ -21,7 +21,7 @@ $ nemoclaw inference create \ --api-key sk-abc123 ``` -This creates a route named after the routing hint. Any sandbox whose policy includes `local` in its `inference.allowed_routes` list can use this route. If you omit `--protocol`, the CLI probes the endpoint and auto-detects the supported protocol (see [Supported API Patterns](index.md#supported-api-patterns)). +This creates a route named after the routing hint. Any sandbox whose policy includes `local` in its `inference.allowed_routes` list can use this route. If you omit `--protocol`, the CLI probes the endpoint and auto-detects the supported protocol (refer to [Supported API Patterns](index.md#supported-api-patterns)). ## Flags @@ -34,16 +34,16 @@ This creates a route named after the routing hint. Any sandbox whose policy incl | `--protocol` | Supported protocol(s): `openai_chat_completions`, `openai_completions`, `anthropic_messages` (repeatable, auto-detected if omitted). | | `--disabled` | Create the route in a disabled state. | -See the [CLI Reference](../reference/cli.md#inference-commands) for the full command specification. +Refer to the [CLI Reference](../reference/cli.md#inference-commands) for the full command specification. ## Good to Know -- **Cluster-level** --- routes are shared across all sandboxes in the cluster, not scoped to one sandbox. -- **Per-model** --- each route maps to one model. Create multiple routes with the same `--routing-hint` but different `--model-id` values to expose multiple models. -- **Hot-reloadable** --- routes can be created, updated, or deleted at any time without restarting sandboxes. +- **Cluster-level**: Routes are shared across all sandboxes in the cluster, not scoped to one sandbox. +- **Per-model**: Each route maps to one model. Create multiple routes with the same `--routing-hint` but different `--model-id` values to expose multiple models. +- **Hot-reloadable**: Routes can be created, updated, or deleted at any time without restarting sandboxes. ## Next Steps -- {doc}`manage-routes` --- list, update, and delete inference routes. -- {doc}`connect-sandboxes` --- connect a sandbox to inference routes via policy. -- {doc}`index` --- understand the inference routing architecture and interception sequence. +- {doc}`manage-routes`: List, update, and delete inference routes. +- {doc}`connect-sandboxes`: Connect a sandbox to inference routes via policy. +- {doc}`index`: Understand the inference routing architecture and interception sequence. diff --git a/docs/inference/index.md b/docs/inference/index.md index 2080d3fc..a50284e8 100644 --- a/docs/inference/index.md +++ b/docs/inference/index.md @@ -5,17 +5,17 @@ # About Inference Routing -The inference routing system keeps your AI inference traffic private by transparently intercepting API calls from sandboxed agents and rerouting them to policy-controlled backends. This enables organizations to keep sensitive prompts and model responses on private infrastructure — redirecting traffic to local or self-hosted models without modifying the agent's code. +The inference routing system keeps your AI inference traffic private by transparently intercepting API calls from sandboxed agents and rerouting them to policy-controlled backends. This enables organizations to keep sensitive prompts and model responses on private infrastructure. It redirects traffic to local or self-hosted models without modifying the agent's code. ## How It Works -When an agent inside a sandbox makes an API call (e.g., using the OpenAI or Anthropic SDK), the request flows through the sandbox proxy. If the destination does not match any explicit network policy but the sandbox has inference routes configured, the proxy: +When an agent inside a sandbox makes an API call (for example, using the OpenAI or Anthropic SDK), the request flows through the sandbox proxy. If the destination does not match any explicit network policy but the sandbox has inference routes configured, the proxy: 1. **TLS-terminates** the connection using the sandbox's ephemeral CA. -2. **Detects the inference API pattern** (e.g., `POST /v1/chat/completions` for OpenAI, `POST /v1/messages` for Anthropic). +2. **Detects the inference API pattern** (for example, `POST /v1/chat/completions` for OpenAI, `POST /v1/messages` for Anthropic). 3. **Strips authorization headers** and forwards the request to a matching backend. 4. **Rewrites the authorization** with the route's API key and injects the correct model ID. -5. **Returns the response** to the agent — the agent sees a normal HTTP response as if it came from the original API. +5. **Returns the response** to the agent. The agent sees a normal HTTP response as if it came from the original API. Agents need zero code changes. Standard OpenAI/Anthropic SDK calls work transparently. @@ -43,18 +43,18 @@ sequenceDiagram ## Working with Inference Routes -- {doc}`create-routes` --- register a new inference backend with `nemoclaw inference create`. -- {doc}`manage-routes` --- list, update, and delete inference routes. -- {doc}`connect-sandboxes` --- connect a sandbox to inference routes via policy. +- {doc}`create-routes`: Register a new inference backend with `nemoclaw inference create`. +- {doc}`manage-routes`: List, update, and delete inference routes. +- {doc}`connect-sandboxes`: Connect a sandbox to inference routes via policy. ## Key Design Properties -- **Zero agent code changes** — standard SDK calls work transparently. -- **Inference privacy** — prompts and responses stay on your infrastructure when routed to local backends. -- **Credential isolation** — the sandbox never sees the real API key for the backend, protecting your credentials. -- **Policy-controlled** — `inference.allowed_routes` determines which routes a sandbox can use. -- **Hot-reloadable** — the `inference` policy field is dynamic and can be updated on a running sandbox. -- **Automatic cache refresh** — in cluster mode, the sandbox refreshes its route cache from the gateway every 30 seconds. +- **Zero agent code changes**: Standard SDK calls work transparently. +- **Inference privacy**: Prompts and responses stay on your infrastructure when routed to local backends. +- **Credential isolation**: The sandbox never sees the real API key for the backend, protecting your credentials. +- **Policy-controlled**: `inference.allowed_routes` determines which routes a sandbox can use. +- **Hot-reloadable**: The `inference` policy field is dynamic and can be updated on a running sandbox. +- **Automatic cache refresh**: In cluster mode, the sandbox refreshes its route cache from the gateway every 30 seconds. ## Supported API Patterns diff --git a/docs/inference/manage-routes.md b/docs/inference/manage-routes.md index 992dabdd..4166cfc7 100644 --- a/docs/inference/manage-routes.md +++ b/docs/inference/manage-routes.md @@ -31,16 +31,16 @@ $ nemoclaw inference update --model-id updated-model-v2 --api-key sk-new- $ nemoclaw inference delete ``` -Deleting a route that is referenced by running sandboxes does not interrupt those sandboxes immediately. Future inference requests that would have matched the deleted route will be denied. +Deleting a route that is referenced by running sandboxes does not interrupt those sandboxes immediately. The proxy denies future inference requests that would have matched the deleted route. ## Behavior Notes -- Routes are **cluster-level** --- they are shared across all sandboxes in the cluster, not scoped to one sandbox. +- Routes are **cluster-level**: They are shared across all sandboxes in the cluster, not scoped to one sandbox. - Each route maps to **one model**. Create multiple routes with the same `--routing-hint` but different `--model-id` values to expose multiple models. -- Route changes are **hot-reloadable** --- sandboxes pick up new, updated, or deleted routes without restarting. +- Route changes are **hot-reloadable**: Sandboxes pick up new, updated, or deleted routes without restarting. ## Next Steps -- {doc}`create-routes` --- register a new inference backend. -- {doc}`connect-sandboxes` --- connect a sandbox to inference routes via policy. -- [CLI Reference](../reference/cli.md#inference-commands) --- full command specification for all inference commands. +- {doc}`create-routes`: Register a new inference backend. +- {doc}`connect-sandboxes`: Connect a sandbox to inference routes through policy. +- [CLI Reference](../reference/cli.md#inference-commands): Full command specification for all inference commands. diff --git a/docs/observability/health.md b/docs/observability/health.md index 11b68026..361cc8dc 100644 --- a/docs/observability/health.md +++ b/docs/observability/health.md @@ -38,7 +38,7 @@ $ nemoclaw term --cluster prod $ NEMOCLAW_CLUSTER=prod nemoclaw term ``` -The terminal inherits all CLI configuration --- cluster selection, TLS settings, and verbosity flags work the same way. No separate configuration is needed. +The terminal inherits all CLI configuration: cluster selection, TLS settings, and verbosity flags work the same way. No separate configuration is needed. ### Screen Layout @@ -56,25 +56,25 @@ The terminal inherits all CLI configuration --- cluster selection, TLS settings, └─────────────────────────────────────────────────────────────────┘ ``` -- **Title bar** --- NemoClaw logo, cluster name, current view, and live health status. -- **Main area** --- the active view. -- **Navigation bar** --- available views with shortcut keys. -- **Command bar** --- appears when you press `:` (vim-style). +- **Title bar**: NemoClaw logo, cluster name, current view, and live health status. +- **Main area**: The active view. +- **Navigation bar**: Available views with shortcut keys. +- **Command bar**: Appears when you press `:` (vim-style). ### Views -#### Dashboard (press `1`) +#### Dashboard Shows your cluster at a glance: - **Cluster name** and **gateway endpoint**. -- **Health status** --- polls every 2 seconds: - - `●` **Healthy** (green) --- everything is running normally. - - `◐` **Degraded** (yellow) --- the cluster is up but something needs attention. - - `○` **Unhealthy** (red) --- the cluster is not operating correctly. +- **Health status**: Polls every two seconds: + - `●` **Healthy** (green): Everything is running normally. + - `◐` **Degraded** (yellow): The cluster is up but something needs attention. + - `○` **Unhealthy** (red): The cluster is not operating correctly. - **Sandbox count**. -#### Sandboxes (press `2`) +#### Sandboxes A live table of all sandboxes: @@ -117,11 +117,11 @@ Press `Esc` to cancel. ### Port Forwarding -When creating a sandbox in the terminal, specify ports in the **Ports** field (comma-separated, e.g., `8080,3000`). After the sandbox reaches `Ready` state, the terminal automatically spawns background SSH tunnels. Forwarded ports appear in the **NOTES** column and in the sandbox detail view. +When creating a sandbox in the terminal, specify ports in the **Ports** field (comma-separated, for example, `8080,3000`). After the sandbox reaches `Ready` state, the terminal automatically spawns background SSH tunnels. Forwarded ports appear in the **NOTES** column and in the sandbox detail view. ### Data Refresh -The terminal polls the cluster every 2 seconds. Both cluster health and the sandbox list update automatically --- no manual refresh needed. +The terminal polls the cluster every two seconds. Both cluster health and the sandbox list update automatically. No manual refresh needed. ### Theme diff --git a/docs/observability/logs.md b/docs/observability/logs.md index be750e74..94963a20 100644 --- a/docs/observability/logs.md +++ b/docs/observability/logs.md @@ -34,7 +34,7 @@ $ nemoclaw sandbox logs my-sandbox --source gateway --level error | `--tail` | Stream live logs (does not exit). | | `--source` | Filter by source: `gateway`, `sandbox`, or `all` (repeatable). | | `--level` | Minimum log level: `error`, `warn`, `info`, `debug`, `trace`. | -| `--since` | Show logs from this duration ago (e.g., `5m`, `1h`, `30s`). | +| `--since` | Show logs from this duration ago (for example, `5m`, `1h`, `30s`). | | `-n ` | Number of log lines to fetch (default: 200). | ## Log Sources @@ -54,14 +54,14 @@ $ nemoclaw sandbox logs my-sandbox --tail --source sandbox Deny log entries include: -- **Destination host and port** --- what the agent tried to reach. -- **Binary path** --- which program attempted the connection. -- **Deny reason** --- why the connection was blocked (no matching policy, binary mismatch, etc.). +- **Destination host and port**: What the agent tried to reach. +- **Binary path**: Which program attempted the connection. +- **Deny reason**: Why the connection was blocked (no matching policy, binary mismatch, etc.). This information drives the [policy iteration loop](../safety-and-privacy/policies.md#the-policy-iteration-loop). ## Log Architecture -Sandbox logs are pushed from the sandbox process to the gateway using a background batching layer. The sandbox collects log entries from its tracing subscriber and streams them to the gateway via gRPC in batches. The gateway stores log entries and makes them available via the CLI's `logs` command. +Sandbox logs are pushed from the sandbox process to the gateway using a background batching layer. The sandbox collects log entries from its tracing subscriber and streams them to the gateway through gRPC in batches. The gateway stores log entries and makes them available via the CLI's `logs` command. -This push-based model means logs are available even if you are not actively streaming --- you can always retrieve recent logs after the fact. +This push-based model means logs are available even if you are not actively streaming. You can always retrieve recent logs after the fact. diff --git a/docs/reference/architecture.md b/docs/reference/architecture.md index 6d7a00b3..a9a8fcfb 100644 --- a/docs/reference/architecture.md +++ b/docs/reference/architecture.md @@ -68,11 +68,11 @@ The gateway is the central control-plane API. It coordinates sandbox lifecycle and state, acts as the auth boundary, and brokers all requests across the platform. It exposes a gRPC API consumed by the CLI and handles: -- Sandbox lifecycle --- creates, monitors, and deletes sandbox pods. -- Provider storage --- stores encrypted provider credentials. -- Policy distribution --- delivers policy YAML to sandboxes at startup and on +- Sandbox lifecycle---creates, monitors, and deletes sandbox pods. +- Provider storage---stores encrypted provider credentials. +- Policy distribution---delivers policy YAML to sandboxes at startup and on hot-reload. -- SSH termination --- terminates SSH tunnels from the CLI and routes them to +- SSH termination---terminates SSH tunnels from the CLI and routes them to the correct sandbox. The CLI never talks to sandbox pods directly. All commands go through the @@ -104,12 +104,12 @@ boundaries before starting the agent: Every outbound TCP connection from any process in the sandbox is routed through the proxy. For each connection, the proxy: -1. **Resolves the calling binary** via `/proc//exe`, ancestor process +1. **Resolves the calling binary** through `/proc//exe`, ancestor process walking, and `/proc//cmdline`. 2. **Queries the policy engine** with the destination host, port, and resolved binary path. -3. **Acts on the decision** --- allow the connection directly, hand it to the - privacy router for inference routing, or deny it. See +3. **Acts on the decision**---allow the connection directly, hand it to the + privacy router for inference routing, or deny it. Refer to [How the Proxy Evaluates Connections](../safety-and-privacy/network-access-rules.md#how-the-proxy-evaluates-connections) for the full decision model. @@ -125,7 +125,7 @@ application layer down to infrastructure and kernel layers. The engine evaluates policies compiled from the sandbox's policy YAML. It is queried synchronously by the proxy on every outbound connection. Policy updates -delivered via hot-reload are compiled and loaded without restarting the proxy. +delivered through hot-reload are compiled and loaded without restarting the proxy. ## Privacy Router diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 14f795f9..30671400 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -89,7 +89,7 @@ Create and manage isolated agent execution environments. | `nemoclaw sandbox policy get ` | Show the active policy for a sandbox. Add `--full` for the complete policy with metadata. | | `nemoclaw sandbox policy list ` | List all policy versions applied to a sandbox, with status. | -### `sandbox create` Flags +### Sandbox Create Flags | Flag | Description | |---|---| @@ -114,7 +114,7 @@ Manage credential providers that inject secrets into sandboxes. | `nemoclaw provider update ` | Update a provider's credentials or configuration. | | `nemoclaw provider delete ` | Delete a provider. | -### `provider create` Flags +### Provider Create Flags | Flag | Description | |---|---| @@ -135,13 +135,13 @@ Manage inference routes that intercept and reroute LLM API calls from userland c | `nemoclaw inference delete ` | Delete an inference route. | | `nemoclaw inference list` | List all inference routes in the active cluster. | -### `inference create` Flags +### Inference Create Flags | Flag | Description | |---|---| -| `--routing-hint` | Short label that identifies this route (e.g., `local`, `nvidia`, `staging`). Referenced by `allowed_routes` in sandbox policies. | -| `--base-url` | Base URL of the inference backend (e.g., `https://vllm.internal:8000`). | -| `--model-id` | Model identifier to send to the backend (e.g., `meta/llama-3.1-8b`). | +| `--routing-hint` | Short label that identifies this route (for example, `local`, `nvidia`, `staging`). Referenced by `allowed_routes` in sandbox policies. | +| `--base-url` | Base URL of the inference backend (for example, `https://vllm.internal:8000`). | +| `--model-id` | Model identifier to send to the backend (for example, `meta/llama-3.1-8b`). | | `--api-key` | API key for authenticating with the backend. | | `--protocol` | API protocol: `openai` or `anthropic`. Defaults to `openai`. | | `--disabled` | Create the route in a disabled state. | @@ -152,7 +152,7 @@ Manage inference routes that intercept and reroute LLM API calls from userland c status, live logs, and policy decisions in a single view. Navigate with `j`/`k`, press `f` to follow live output, `s` to filter by source, and `q` to quit. -See {doc}`/sandboxes/terminal` for the full guide — including how to read log +Refer to {doc}`/sandboxes/terminal` for the full guide, including how to read log entries, diagnose blocked connections, and interpret inference interception. ## Environment Variables diff --git a/docs/reference/environment-variables.md b/docs/reference/environment-variables.md index 97ace48b..7d824fc3 100644 --- a/docs/reference/environment-variables.md +++ b/docs/reference/environment-variables.md @@ -26,7 +26,7 @@ These variables are set inside sandbox processes automatically: | `NODE_EXTRA_CA_CERTS` | Same CA bundle path, for Node.js applications. | | `REQUESTS_CA_BUNDLE` | Same CA bundle path, for Python requests library. | -Provider credentials are also injected as environment variables. The specific variables depend on which providers are attached (e.g., `ANTHROPIC_API_KEY` for Claude, `GITHUB_TOKEN` for GitHub). +Provider credentials are also injected as environment variables. The specific variables depend on which providers are attached (for example, `ANTHROPIC_API_KEY` for Claude, `GITHUB_TOKEN` for GitHub). ## Sandbox Supervisor Variables diff --git a/docs/reference/policy-schema.md b/docs/reference/policy-schema.md index 4654662b..4a1c498d 100644 --- a/docs/reference/policy-schema.md +++ b/docs/reference/policy-schema.md @@ -29,13 +29,13 @@ inference: { ... } Static fields are set at sandbox creation time. Changing them requires destroying and recreating the sandbox. Dynamic fields can be updated on a running sandbox with `nemoclaw sandbox policy set` and take effect without restarting. -## `version` +## Version | Field | Type | Required | Description | |---|---|---|---| | `version` | integer | Yes | Schema version number. Currently must be `1`. | -## `filesystem_policy` +## Filesystem Policy **Category:** Static @@ -64,7 +64,7 @@ filesystem_policy: - /dev/null ``` -## `landlock` +## Landlock **Category:** Static @@ -81,7 +81,7 @@ landlock: compatibility: best_effort ``` -## `process` +## Process **Category:** Static @@ -100,11 +100,11 @@ process: run_as_group: sandbox ``` -## `network_policies` +## Network Policies **Category:** Dynamic -A map of named network policy entries. Each entry declares a set of endpoints and a set of binaries. Only the listed binaries are permitted to connect to the listed endpoints. The map key is a logical identifier; the `name` field inside the entry is the display name used in logs. +A map of named network policy entries. Each entry declares a set of endpoints and a set of binaries. Only the listed binaries are permitted to connect to the listed endpoints. The map key is a logical identifier. The `name` field inside the entry is the display name used in logs. ### Network Policy Entry @@ -125,7 +125,7 @@ Each endpoint defines a reachable destination and optional inspection rules. | `protocol` | string | No | Set to `rest` to enable L7 (HTTP) inspection. Omit for L4-only (TCP passthrough). | | `tls` | string | No | TLS handling mode. `terminate` decrypts TLS at the proxy for inspection. `passthrough` forwards encrypted traffic without inspection. Only relevant when `protocol` is `rest`. | | `enforcement` | string | No | `enforce` actively blocks disallowed requests. `audit` logs violations but allows traffic through. | -| `access` | string | No | HTTP access level. One of `read-only`, `read-write`, or `full`. See table below. Mutually exclusive with `rules`. | +| `access` | string | No | HTTP access level. One of `read-only`, `read-write`, or `full`. Refer to table below. Mutually exclusive with `rules`. | | `rules` | list of rule objects | No | Fine-grained per-method, per-path allow rules. Mutually exclusive with `access`. | #### Access Levels @@ -142,7 +142,7 @@ Used when `access` is not set. Each rule explicitly allows a method and path com | Field | Type | Required | Description | |---|---|---|---| -| `allow.method` | string | Yes | HTTP method to allow (e.g., `GET`, `POST`). | +| `allow.method` | string | Yes | HTTP method to allow (for example, `GET`, `POST`). | | `allow.path` | string | Yes | URL path pattern. Supports `*` and `**` glob syntax. | Example with rules: @@ -192,15 +192,15 @@ network_policies: - path: /usr/bin/node ``` -## `inference` +## Inference **Category:** Dynamic -Controls which inference routing backends userland code may access. The `allowed_routes` list names route types that the privacy router will accept. Traffic matching an inference API pattern that targets a route type not in this list is denied. +Controls which inference routing backends userland code can access. The `allowed_routes` list names route types that the privacy router will accept. Traffic matching an inference API pattern that targets a route type not in this list is denied. | Field | Type | Required | Description | |---|---|---|---| -| `allowed_routes` | list of strings | No | Routing hint labels (e.g., `local`, `nvidia`, `staging`) that this sandbox may use. Must match the `routing_hint` of inference routes created with `nemoclaw inference create`. | +| `allowed_routes` | list of strings | No | Routing hint labels (e.g., `local`, `nvidia`, `staging`) that this sandbox can use. Must match the `routing_hint` of inference routes created with `nemoclaw inference create`. | Example: diff --git a/docs/resources/index.md b/docs/resources/index.md index eaadbf89..bc4a3bf0 100644 --- a/docs/resources/index.md +++ b/docs/resources/index.md @@ -7,8 +7,8 @@ ## Links -- [NemoClaw on GitHub](https://github.com/NVIDIA/NemoClaw) — source code, issues, and pull requests. -- [Contributing Guide](https://github.com/NVIDIA/NemoClaw/blob/main/CONTRIBUTING.md) — how to build from source and contribute. +- [NemoClaw on GitHub](https://github.com/NVIDIA/NemoClaw): Source code, issues, and pull requests. +- [Contributing Guide](https://github.com/NVIDIA/NemoClaw/blob/main/CONTRIBUTING.md): How to build from source and contribute. ## Related Technologies @@ -32,8 +32,8 @@ | **Policy** | A YAML document defining what a sandbox can access (filesystem, network, inference). | | **Gateway** | The central control plane service that manages sandboxes, providers, and routes. | | **Inference Route** | A mapping from a routing hint to a backend AI model endpoint. | -| **BYOC** | Bring Your Own Container — running custom images as sandboxes. | +| **BYOC** | Bring Your Own Container: running custom images as sandboxes. | | **NemoClaw Terminal** | The NemoClaw terminal user interface (TUI), launched with `nemoclaw term`. | | **L7 Inspection** | HTTP-level traffic inspection inside TLS tunnels. | -| **TOFU** | Trust-On-First-Use — the binary integrity verification model used by the proxy. | -| **mTLS** | Mutual TLS — both client and server present certificates. Used for all gateway communication. | +| **TOFU** | Trust-On-First-Use: the binary integrity verification model used by the proxy. | +| **mTLS** | Mutual TLS: both client and server present certificates. Used for all gateway communication. | diff --git a/docs/safety-and-privacy/index.md b/docs/safety-and-privacy/index.md index 3c8ada70..3aaf8461 100644 --- a/docs/safety-and-privacy/index.md +++ b/docs/safety-and-privacy/index.md @@ -6,7 +6,7 @@ # About Safety and Privacy NemoClaw wraps every sandbox in four independent protection layers. No single -point of failure can compromise your environment --- each layer covers gaps the +point of failure can compromise your environment. Each layer covers gaps the others cannot. ```{mermaid} @@ -38,13 +38,13 @@ graph TB ``` You control all four layers through a single YAML policy. Network and inference -rules are hot-reloadable on a running sandbox; filesystem and process +rules are hot-reloadable on a running sandbox. Filesystem and process restrictions are locked at creation time. -- **{doc}`security-model`** --- threat scenarios (data exfiltration, credential +- **{doc}`security-model`**: Threat scenarios (data exfiltration, credential theft, unauthorized API calls, privilege escalation) and how NemoClaw addresses each one. -- **{doc}`policies`** --- author policies, monitor for blocked actions, and +- **{doc}`policies`**: Author policies, monitor for blocked actions, and iterate on rules without restarting sandboxes. -- **{doc}`network-access-rules`** --- configure endpoint rules, binary matching, +- **{doc}`network-access-rules`**: Configure endpoint rules, binary matching, L7 inspection, and access presets. diff --git a/docs/safety-and-privacy/network-access-rules.md b/docs/safety-and-privacy/network-access-rules.md index 5224db7b..615ba719 100644 --- a/docs/safety-and-privacy/network-access-rules.md +++ b/docs/safety-and-privacy/network-access-rules.md @@ -23,7 +23,7 @@ Each outbound connection resolves to one of three outcomes: :::{note} This is the most important distinction in NemoClaw's network model. -**Agent traffic** is the coding agent (Claude, opencode, Codex) calling its own API to get completions. This traffic matches a `network_policies` entry because the policy declares both the endpoint (for example, `api.anthropic.com:443`) and the binary (for example, `/usr/local/bin/claude`). The proxy allows it through directly. The agent's own API key --- injected by the provider --- is used as-is. +**Agent traffic** is the coding agent (Claude, opencode, Codex) calling its own API to get completions. This traffic matches a `network_policies` entry because the policy declares both the endpoint (for example, `api.anthropic.com:443`) and the binary (for example, `/usr/local/bin/claude`). The proxy allows it through directly. The agent's own API key (injected by the provider) is used as-is. **Userland traffic** is code that the agent *writes* making inference calls. A Python script calling the OpenAI-compatible API, a data pipeline hitting an LLM endpoint, a test harness querying a model. This traffic does *not* match any network policy because the calling binary (`/usr/bin/python3`) is not listed in the agent's policy entry. The proxy intercepts it, the privacy router reroutes it to a configured backend, and the route's API key is substituted in. The agent's code never touches your real API key. ::: @@ -64,7 +64,7 @@ The key (`my_rule`) is a logical name for reference. The `name` field is the hum ## Endpoints -Each endpoint entry controls access to a single host-port combination. See [Endpoint Object](../reference/policy-schema.md#endpoint-object) for the full field reference. +Each endpoint entry controls access to a single host-port combination. Refer to [Endpoint Object](../reference/policy-schema.md#endpoint-object) for the full field reference. The `access` field provides presets: `full` (all methods), `read-only` (`GET`, `HEAD`, `OPTIONS`), or `read-write` (`GET`, `HEAD`, `OPTIONS`, `POST`, `PUT`, `PATCH`). @@ -129,7 +129,7 @@ endpoints: With both fields set, the proxy terminates the TLS connection, decrypts the HTTP request, evaluates it against the `access` preset or custom `rules`, and re-encrypts before forwarding to the destination. :::{warning} -Without `tls: terminate` on port 443, the proxy cannot decrypt the traffic. L7 rules (`access`, `rules`) are not evaluated because the HTTP payload is encrypted. The connection is handled at L4 only --- allowed or denied based on host and port, with no HTTP-level access control. +Without `tls: terminate` on port 443, the proxy cannot decrypt the traffic. L7 rules (`access`, `rules`) are not evaluated because the HTTP payload is encrypted. The connection is handled at L4 only: allowed or denied based on host and port, with no HTTP-level access control. ::: ### Bare Endpoints (L4-Only) @@ -145,7 +145,7 @@ endpoints: The proxy allows the TCP connection through to the destination without decrypting or inspecting the payload. Use L4-only entries for non-HTTP traffic, package registries where you need connectivity but not method-level control, or endpoints where TLS termination is not desired. :::{warning} -With L4-only rules, you have no control over *what* is sent to the endpoint --- only *whether* the connection is allowed. Any binary listed in the entry can send any data to the host. If you need to restrict HTTP methods or paths, add `protocol: rest` and `tls: terminate`. +With L4-only rules, you have no control over *what* is sent to the endpoint: only *whether* the connection is allowed. Any binary listed in the entry can send any data to the host. If you need to restrict HTTP methods or paths, add `protocol: rest` and `tls: terminate`. ::: ## Enforcement Modes @@ -158,7 +158,7 @@ Each endpoint can operate in one of two enforcement modes: | `audit` | Logs the violation but forwards the traffic to the destination. The agent is not interrupted. | :::{tip} -Start with `enforcement: audit` when developing a new policy. Audit mode shows you what *would* be blocked without actually breaking the agent. Once the policy is correct and you have confirmed that no legitimate traffic is flagged, switch to `enforcement: enforce`. +Start with `enforcement: audit` when developing a new policy. Audit mode shows you what *would* be blocked without actually breaking the agent. After the policy is correct and you have confirmed that no legitimate traffic is flagged, switch to `enforcement: enforce`. ::: ## Putting It Together @@ -212,4 +212,4 @@ network_policies: ## Next Steps -- [Write Sandbox Policies](policies.md) --- the full iterative workflow for authoring, testing, and updating policies. +- [Write Sandbox Policies](policies.md): The full iterative workflow for authoring, testing, and updating policies. diff --git a/docs/safety-and-privacy/policies.md b/docs/safety-and-privacy/policies.md index 76a23fdd..c52a1d14 100644 --- a/docs/safety-and-privacy/policies.md +++ b/docs/safety-and-privacy/policies.md @@ -66,7 +66,7 @@ inference: - local ``` -See the [Policy Schema Reference](../reference/policy-schema.md) for every field, type, and default value. +Refer to the [Policy Schema Reference](../reference/policy-schema.md) for every field, type, and default value. ## Default Policy @@ -74,7 +74,7 @@ NemoClaw ships a built-in default policy designed for Claude Code. It covers Cla | Agent | Default policy coverage | What you need to do | |---|---|---| -| Claude Code | Full | Nothing --- works out of the box | +| Claude Code | Full | Nothing: works out of the box | | opencode | Partial | Add `opencode.ai` endpoint and opencode binary paths. | | Codex | None | Provide a complete custom policy with OpenAI endpoints and Codex binary paths. | @@ -92,7 +92,7 @@ $ nemoclaw sandbox create --policy ./my-policy.yaml --keep -- claude The `--keep` flag keeps the sandbox running after the initial command exits, which is useful when you plan to iterate on the policy. -To avoid passing `--policy` every time, set a default policy via environment variable: +To avoid passing `--policy` every time, set a default policy by using environment variable: ```console $ export NEMOCLAW_SANDBOX_POLICY=./my-policy.yaml @@ -115,13 +115,13 @@ flowchart TD F --> B ``` -### Step 1: Create the sandbox with your initial policy +### Step 1: Create the Sandbox with Your Initial Policy ```console $ nemoclaw sandbox create --policy ./my-policy.yaml --keep -- claude ``` -### Step 2: Monitor logs for denied actions +### Step 2: Monitor Logs for Denied Actions In a second terminal, tail the sandbox logs and look for `action: deny` entries: @@ -136,12 +136,12 @@ that shows status and logs in a single view. See {doc}`/sandboxes/terminal` for how to read log entries and diagnose what's being blocked. :::{tip} -The NemoClaw Terminal is especially useful during policy iteration — you can +The NemoClaw Terminal is especially useful during policy iteration. You can watch deny entries appear in real time as the agent hits blocked endpoints, then push an updated policy without leaving the terminal. ::: -### Step 3: Pull the current policy +### Step 3: Pull the Current Policy Export the running policy to a file: @@ -153,7 +153,7 @@ $ nemoclaw sandbox policy get --full > current-policy.yaml The `--full` output includes a metadata header with `Version`, `Hash`, and `Status` lines that are not valid YAML. Strip these lines before re-submitting the file as a policy update, or the push will fail. ::: -### Step 4: Modify the policy YAML +### Step 4: Modify the Policy YAML Edit `current-policy.yaml` to address the denied actions you observed. Common changes include: @@ -163,7 +163,7 @@ Edit `current-policy.yaml` to address the denied actions you observed. Common ch - Adjusting `access` levels or adding custom `rules` - Updating `inference.allowed_routes` -### Step 5: Push the updated policy +### Step 5: Push the Updated Policy ```console $ nemoclaw sandbox policy set --policy current-policy.yaml --wait @@ -177,7 +177,7 @@ The `--wait` flag blocks until the policy engine processes the update. Exit code | `1` | Policy failed validation | | `124` | Timed out waiting for the policy engine | -### Step 6: Verify the new revision loaded +### Step 6: Verify the New Revision Loaded ```console $ nemoclaw sandbox policy list @@ -215,12 +215,12 @@ $ nemoclaw sandbox policy get --rev 3 --full ## Safety Properties **Last-known-good.** -If a new policy revision fails validation, the previous successfully loaded policy stays active. A bad push does not break a running sandbox --- the agent continues operating under the last good policy. +If a new policy revision fails validation, the previous successfully loaded policy stays active. A bad push does not break a running sandbox. The agent continues operating under the last good policy. **Idempotent.** Submitting the same policy content again does not create a new revision. The CLI detects that the content has not changed and returns without modifying the revision history. ## Next Steps -- [Network Access Rules](network-access-rules.md) --- how the proxy evaluates connections, endpoint allowlists, binary matching, and enforcement modes. -- {doc}`../reference/policy-schema` --- complete field reference for the policy YAML. +- [Network Access Rules](network-access-rules.md): How the proxy evaluates connections, endpoint allowlists, binary matching, and enforcement modes. +- {doc}`../reference/policy-schema`: Complete field reference for the policy YAML. diff --git a/docs/safety-and-privacy/security-model.md b/docs/safety-and-privacy/security-model.md index d064d591..3fd68b74 100644 --- a/docs/safety-and-privacy/security-model.md +++ b/docs/safety-and-privacy/security-model.md @@ -10,8 +10,8 @@ file, reach any network host, call any API with your credentials, and install arbitrary software. NemoClaw's security model exists to prevent all of that. :::{note} -NemoClaw uses defense in depth. Four independent protection layers --- filesystem, -network, process, and inference --- work together so that no single point of +NemoClaw uses defense in depth. Four independent protection layers: filesystem, +network, process, and inference. They work together so that no single point of failure can compromise your environment. ::: @@ -41,7 +41,7 @@ from your home directory and exfiltrates them. **With NemoClaw:** Landlock filesystem restrictions limit the agent to declared paths. The agent -can access `/sandbox`, `/tmp`, and read-only system directories --- but not your +can access `/sandbox`, `/tmp`, and read-only system directories, but not your home directory, SSH keys, cloud credentials, or anything else outside the policy. @@ -55,7 +55,7 @@ data to a third-party inference provider you did not approve. **With NemoClaw:** The privacy router intercepts outbound API calls and reroutes them to a -backend you control --- a local model, an NVIDIA endpoint, or your own +backend you control: a local model, an NVIDIA endpoint, or your own deployment. The agent's code does not need to change; the rerouting is transparent. Your data never reaches an unauthorized provider. @@ -82,6 +82,6 @@ that the others cannot. ## Next Steps -- {doc}`policies` --- write and iterate on the policy YAML that configures all four layers -- {doc}`network-access-rules` --- configure network rules, binary matching, and TLS inspection -- {doc}`../inference/index` --- set up private inference backends +- {doc}`policies`: Write and iterate on the policy YAML that configures all four layers +- {doc}`network-access-rules`: Configure network rules, binary matching, and TLS inspection +- {doc}`../inference/index`: Set up private inference backends diff --git a/docs/sandboxes/community-sandboxes.md b/docs/sandboxes/community-sandboxes.md index 3fc3224a..d4779271 100644 --- a/docs/sandboxes/community-sandboxes.md +++ b/docs/sandboxes/community-sandboxes.md @@ -49,14 +49,14 @@ preconfigured by the community package. The `--from` flag also accepts: -- **Local directory paths** --- point to a directory on disk that contains a +- **Local directory paths**: Point to a directory on disk that contains a Dockerfile and optional policy/skills: ```console $ nemoclaw sandbox create --from ./my-sandbox-dir ``` -- **Container image references** --- use an existing container image directly: +- **Container image references**: Use an existing container image directly: ```console $ nemoclaw sandbox create --from my-registry.example.com/my-image:latest @@ -68,14 +68,14 @@ Each community sandbox is a directory under `sandboxes/` in the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) repository. At minimum, a sandbox directory must contain: -- `Dockerfile` --- defines the container image -- `README.md` --- describes the sandbox and how to use it +- `Dockerfile`: Defines the container image +- `README.md`: Describes the sandbox and how to use it Optional files: -- `policy.yaml` --- default policy applied when the sandbox launches -- `skills/` --- agent skill definitions bundled with the sandbox -- Startup scripts --- any scripts the Dockerfile or entrypoint invokes +- `policy.yaml`: Default policy applied when the sandbox launches +- `skills/`: Agent skill definitions bundled with the sandbox +- Startup scripts: Any scripts the Dockerfile or entrypoint invokes To contribute, fork the repository, add your sandbox directory, and open a pull request. See the repository's @@ -84,12 +84,12 @@ for submission guidelines. :::{note} The community catalog is designed to grow. If you have built a sandbox that -supports a particular workflow --- data processing, simulation, code review, -or anything else --- consider contributing it back so others can use it. +supports a particular workflow (data processing, simulation, code review, +or anything else), consider contributing it back so others can use it. ::: ## Next Steps -- {doc}`create-and-manage` --- full sandbox lifecycle management -- {doc}`custom-containers` --- build a fully custom container with BYOC -- {doc}`../safety-and-privacy/policies` --- customize the policy applied to any sandbox +- {doc}`create-and-manage`: Full sandbox lifecycle management +- {doc}`custom-containers`: Build a fully custom container with BYOC +- {doc}`../safety-and-privacy/policies`: Customize the policy applied to any sandbox diff --git a/docs/sandboxes/create-and-manage.md b/docs/sandboxes/create-and-manage.md index 900169f8..28a84f62 100644 --- a/docs/sandboxes/create-and-manage.md +++ b/docs/sandboxes/create-and-manage.md @@ -16,7 +16,7 @@ Every sandbox moves through a defined set of phases: | **Provisioning** | The runtime is setting up the sandbox environment, injecting credentials, and applying your policy. | | **Ready** | The sandbox is running. The agent process is active and all isolation layers are enforced. You can connect, sync files, and view logs. | | **Error** | Something went wrong during provisioning or execution. Check logs with `nemoclaw sandbox logs` for details. | -| **Deleting** | The sandbox is being torn down. Resources are released and credentials are purged. | +| **Deleting** | The sandbox is being torn down. The system releases resources and purges credentials. | ## The NemoClaw Runtime @@ -36,9 +36,9 @@ remote host instead of your local machine: $ nemoclaw cluster admin deploy --remote user@host ``` -See [Remote Deployment](../reference/architecture.md) for +Refer to [Remote Deployment](../reference/architecture.md) for details. If you have multiple clusters (local and remote), switch between them -with `nemoclaw cluster use `. See the +with `nemoclaw cluster use `. Refer to the [CLI Reference](../reference/cli.md#cluster-commands) for the full command set. ## Prerequisites @@ -147,7 +147,7 @@ $ nemoclaw sandbox logs my-sandbox --tail --source sandbox --level warn --since :::{tip} For a real-time dashboard that combines sandbox status and logs in one view, -run `nemoclaw term`. See {doc}`terminal` for details on reading log entries and +run `nemoclaw term`. Refer to {doc}`terminal` for details on reading log entries and diagnosing blocked connections. ::: @@ -223,7 +223,7 @@ $ nemoclaw sandbox delete sandbox-a sandbox-b sandbox-c ## Next Steps -- {doc}`community-sandboxes` --- use pre-built sandboxes from the community catalog -- {doc}`providers` --- create and attach credential providers -- {doc}`custom-containers` --- build and run your own container image -- {doc}`../safety-and-privacy/policies` --- control what the agent can access \ No newline at end of file +- {doc}`community-sandboxes`: Use pre-built sandboxes from the community catalog +- {doc}`providers`: Create and attach credential providers +- {doc}`custom-containers`: Build and run your own container image +- {doc}`../safety-and-privacy/policies`: Control what the agent can access \ No newline at end of file diff --git a/docs/sandboxes/custom-containers.md b/docs/sandboxes/custom-containers.md index df9f0658..14a28579 100644 --- a/docs/sandboxes/custom-containers.md +++ b/docs/sandboxes/custom-containers.md @@ -23,8 +23,8 @@ Point `--from` at the directory containing your Dockerfile: $ nemoclaw sandbox create --from ./my-app --keep --name my-app ``` -The CLI builds the image locally via Docker, pushes it into the cluster, and -creates the sandbox --- all in one step. No external container registry is +The CLI builds the image locally using Docker, pushes it into the cluster, and +creates the sandbox, all in one step. No external container registry is needed. You can also pass a full container image reference if the image is already @@ -66,7 +66,7 @@ This creates the sandbox, sets up port forwarding on port 8080, and runs `./start-server.sh` as the sandbox command. :::{warning} -Distroless and `FROM scratch` images are not supported. The NemoClaw +NemoClaw does not support distroless and `FROM scratch` images. The supervisor requires glibc, `/proc`, and a shell to operate. Images missing `iproute2` or required Linux capabilities will fail to start in proxy mode. Ensure your base image includes these dependencies. @@ -74,7 +74,7 @@ Ensure your base image includes these dependencies. ## Next Steps -- {doc}`create-and-manage` --- full sandbox lifecycle commands -- {doc}`providers` --- attach credentials to your custom container -- {doc}`/safety-and-privacy/policies` --- write a policy tailored to your workload -- {doc}`/safety-and-privacy/security-model` --- understand the isolation layers applied to custom images \ No newline at end of file +- {doc}`create-and-manage`: Full sandbox lifecycle commands +- {doc}`providers`: Attach credentials to your custom container +- {doc}`/safety-and-privacy/policies`: Write a policy tailored to your workload +- {doc}`/safety-and-privacy/security-model`: Understand the isolation layers applied to custom images \ No newline at end of file diff --git a/docs/sandboxes/index.md b/docs/sandboxes/index.md index 1c8f66fd..a04ce8a1 100644 --- a/docs/sandboxes/index.md +++ b/docs/sandboxes/index.md @@ -5,7 +5,7 @@ # About Sandboxes -A sandbox is a safe, private execution environment for an AI agent. Each sandbox runs inside a Kubernetes pod with multiple layers of protection that prevent unauthorized data access, credential exposure, and network exfiltration: filesystem restrictions (Landlock), system call filtering (seccomp), network namespace isolation, and a privacy-enforcing HTTP CONNECT proxy. +A sandbox is a safe, private execution environment for an AI agent. Each sandbox runs inside a Kubernetes pod with multiple layers of protection that prevent unauthorized data access, credential exposure, and network exfiltration. Protection layers include filesystem restrictions (Landlock), system call filtering (seccomp), network namespace isolation, and a privacy-enforcing HTTP CONNECT proxy. ## Concepts @@ -27,18 +27,18 @@ A sandbox goes through these phases: Each sandbox runs two processes: - The **supervisor** (`navigator-sandbox`) is a privileged process that sets up isolation, starts the proxy, runs the SSH server, and manages the child process. -- The **child process** is the agent (e.g., Claude, Codex) running with restricted privileges — reduced filesystem access, filtered system calls, and all network traffic routed through the proxy. +- The **child process** is the agent (for example, Claude, Codex) running with restricted privileges: reduced filesystem access, filtered system calls, and all network traffic routed through the proxy. ### Policy -Every sandbox is governed by a policy that defines what the agent can do, ensuring your data and credentials stay safe. Policies are written in YAML and control: +A policy governs every sandbox, defining what the agent can do and ensuring your data and credentials stay safe. Policies are written in YAML and control: -- **Filesystem access** — which directories are readable and writable, protecting sensitive data. -- **Network access** — which hosts each program can connect to, preventing data exfiltration. -- **Inference routing** — which AI model backends are available, keeping inference traffic private. -- **Process privileges** — the user and group the agent runs as, limiting blast radius. +- **Filesystem access**: Which directories are readable and writable, protecting sensitive data. +- **Network access**: Which hosts each program can connect to, preventing data exfiltration. +- **Inference routing**: Which AI model backends are available, keeping inference traffic private. +- **Process privileges**: The user and group the agent runs as, limiting blast radius. -See [Safety & Privacy](../safety-and-privacy/index.md) for details. +Refer to [Safety & Privacy](../safety-and-privacy/index.md) for details. ## Quick Reference diff --git a/docs/sandboxes/providers.md b/docs/sandboxes/providers.md index 07759d71..bb3a44fe 100644 --- a/docs/sandboxes/providers.md +++ b/docs/sandboxes/providers.md @@ -5,7 +5,7 @@ # Providers -AI agents typically need credentials to access external services — an API key for the AI model provider, a token for GitHub or GitLab, and so on. NemoClaw manages these credentials as first-class entities called *providers*. +AI agents typically need credentials to access external services: an API key for the AI model provider, a token for GitHub or GitLab, and so on. NemoClaw manages these credentials as first-class entities called *providers*. Create and manage providers that supply credentials to sandboxes. @@ -91,8 +91,7 @@ providers specified. ### Auto-Discovery Shortcut -When the trailing command in `nemoclaw sandbox create` is a recognized tool name ---- `claude`, `codex`, or `opencode` --- the CLI auto-creates the required +When the trailing command in `nemoclaw sandbox create` is a recognized tool name (`claude`, `codex`, or `opencode`), the CLI auto-creates the required provider from your local credentials if one does not already exist. You do not need to create the provider separately: @@ -121,15 +120,13 @@ flowchart LR `--provider` flag (one or more providers can be attached). 3. **The sandbox starts.** The supervisor process initializes. 4. **The supervisor fetches credentials** from the NemoClaw gateway at runtime. - Credentials are not stored in the sandbox specification --- they are - retrieved on demand. + The system does not store credentials in the sandbox specification. It retrieves them on demand. 5. **Credentials are injected** into the agent process as environment variables. They are also available in SSH sessions when you connect to the sandbox. :::{warning} -Credentials are never stored in the sandbox container specification. They are -fetched at runtime by the supervisor and held only in process memory. This -means credentials are not visible in container inspection, image layers, or +The system does not store credentials in the sandbox container specification. The supervisor fetches them at runtime and holds them only in process memory. This +means you cannot find credentials in container inspection, image layers, or environment dumps of the container spec. ::: @@ -139,6 +136,6 @@ For a list of supported provider types, refer to the [Support Matrix](../about/s ## Next Steps -- {doc}`create-and-manage` --- full sandbox lifecycle management -- {doc}`custom-containers` --- use providers with custom container images -- {doc}`../safety-and-privacy/security-model` --- why credential isolation matters \ No newline at end of file +- {doc}`create-and-manage`: Full sandbox lifecycle management +- {doc}`custom-containers`: Use providers with custom container images +- {doc}`../safety-and-privacy/security-model`: Why credential isolation matters \ No newline at end of file diff --git a/docs/sandboxes/terminal.md b/docs/sandboxes/terminal.md index 265f0988..997afe96 100644 --- a/docs/sandboxes/terminal.md +++ b/docs/sandboxes/terminal.md @@ -29,8 +29,8 @@ The logs pane streams activity in real time. Outbound connections, policy decisi Log entries originate from two sources: -- **sandbox** — the sandbox supervisor (proxy decisions, policy enforcement, SSH connections, process lifecycle). -- **gateway** — the control plane (sandbox creation, phase changes, policy distribution). +- **sandbox**: The sandbox supervisor (proxy decisions, policy enforcement, SSH connections, process lifecycle). +- **gateway**: The control plane (sandbox creation, phase changes, policy distribution). Press `f` to enable follow mode and auto-scroll to new entries. @@ -54,7 +54,7 @@ Each deny entry contains the following fields: To resolve a blocked connection: -1. Add the host to the network policy if the connection is legitimate. See {doc}`../safety-and-privacy/policies` for the iteration workflow. +1. Add the host to the network policy if the connection is legitimate. Refer to {doc}`../safety-and-privacy/policies` for the iteration workflow. 2. Leave it blocked if the connection is unauthorized. ## Diagnosing Inference Interception @@ -75,15 +75,15 @@ This sequence indicates: :::{note} If these calls should go directly to the destination rather than through inference routing, the most likely cause is a binary path mismatch. The process making the HTTP call does not match any binary listed in the network policy. -Check the log entry for the binary path, then update the `binaries` list in the policy. See {doc}`../safety-and-privacy/network-access-rules` for details on binary matching. +Check the log entry for the binary path, then update the `binaries` list in the policy. Refer to {doc}`../safety-and-privacy/network-access-rules` for details on binary matching. ::: ## Filtering and Navigation The dashboard provides filtering and navigation controls: -- Press **`s`** to filter logs by source — display only `sandbox` logs (policy decisions) or only `gateway` logs (lifecycle events). -- Press **`f`** to toggle follow mode — auto-scroll to the latest entries. +- Press **`s`** to filter logs by source. Display only `sandbox` logs (policy decisions) or only `gateway` logs (lifecycle events). +- Press **`f`** to toggle follow mode. Auto-scroll to the latest entries. - Press **`Enter`** on a log entry to open the detail view with the full message. - Use **`j`** / **`k`** to navigate up and down the log list. @@ -103,8 +103,8 @@ The following keyboard shortcuts are available in the terminal dashboard. ## Related Topics -For deeper dives into topics covered by the terminal dashboard, see the following guides. +For deeper dives into topics covered by the terminal dashboard, refer to the following guides. -- **Blocked connections** — Follow {doc}`../safety-and-privacy/policies` to pull the current policy, add the missing endpoint, and push an update without restarting the sandbox. -- **Inference interception** — See {doc}`../safety-and-privacy/network-access-rules` for the distinction between agent traffic (routed directly) and userland traffic (routed through inference routing). -- **General troubleshooting** — See {doc}`../troubleshooting/cluster-issues` for common issues and diagnostics. +- **Blocked connections**: Follow {doc}`../safety-and-privacy/policies` to pull the current policy, add the missing endpoint, and push an update without restarting the sandbox. +- **Inference interception**: Refer to {doc}`../safety-and-privacy/network-access-rules` for the distinction between agent traffic (routed directly) and userland traffic (routed through inference routing). +- **General troubleshooting**: Refer to {doc}`../troubleshooting/cluster-issues` for common issues and diagnostics. diff --git a/docs/troubleshooting/cluster-issues.md b/docs/troubleshooting/cluster-issues.md index c8860861..0f8da09b 100644 --- a/docs/troubleshooting/cluster-issues.md +++ b/docs/troubleshooting/cluster-issues.md @@ -31,5 +31,5 @@ Troubleshoot problems with deploying, connecting to, and running NemoClaw cluste **Check:** 1. View container logs: `docker logs nemoclaw-cluster`. -2. Check if k3s started: the bootstrap process waits up to 180 attempts (6 minutes) for cluster readiness. -3. Look for resource constraints — k3s needs sufficient memory and disk. +2. Check if k3s started: the bootstrap process waits up to 180 attempts (six minutes) for cluster readiness. +3. Look for resource constraints. k3s needs sufficient memory and disk. diff --git a/docs/troubleshooting/provider-issues.md b/docs/troubleshooting/provider-issues.md index ed7c473e..99c62dfc 100644 --- a/docs/troubleshooting/provider-issues.md +++ b/docs/troubleshooting/provider-issues.md @@ -12,8 +12,8 @@ Troubleshoot problems with provider credential discovery and injection into sand **Symptom:** `--from-existing` creates a provider with no credentials. **Check:** -1. Are the expected environment variables set? (e.g., `ANTHROPIC_API_KEY` for Claude). -2. Do the expected config files exist? (e.g., `~/.claude.json`). +1. Are the expected environment variables set? (for example, `ANTHROPIC_API_KEY` for Claude). +2. Do the expected config files exist? (for example, `~/.claude.json`). 3. Try explicit credentials: `--credential ANTHROPIC_API_KEY=sk-...`. ## Sandbox Missing Credentials @@ -21,6 +21,6 @@ Troubleshoot problems with provider credential discovery and injection into sand **Symptom:** Environment variables for a provider are not set inside the sandbox. **Check:** -1. Was the provider attached? `nemoclaw sandbox get ` — check the providers list. +1. Was the provider attached? `nemoclaw sandbox get `. Check the providers list. 2. Does the provider have credentials? `nemoclaw provider get `. 3. Are the credential keys valid env var names? Keys with dots, dashes, or spaces are silently skipped. diff --git a/docs/troubleshooting/sandbox-issues.md b/docs/troubleshooting/sandbox-issues.md index c9419f78..e079fc92 100644 --- a/docs/troubleshooting/sandbox-issues.md +++ b/docs/troubleshooting/sandbox-issues.md @@ -22,7 +22,7 @@ Troubleshoot problems with creating, connecting to, and configuring sandboxes. **Check:** 1. Is the sandbox in `Ready` state? `nemoclaw sandbox get `. -2. Is SSH accessible? The tunnel goes through the gateway — verify cluster connectivity first. +2. Is SSH accessible? The tunnel goes through the gateway. Verify cluster connectivity first. ## Network Requests Denied @@ -30,8 +30,8 @@ Troubleshoot problems with creating, connecting to, and configuring sandboxes. **Check:** 1. Stream sandbox logs: `nemoclaw sandbox logs --tail --source sandbox`. -2. Look for `deny` actions — they include the destination, binary, and reason. -3. Update the policy to allow the blocked endpoint. See [Policy Iteration Loop](../safety-and-privacy/policies.md#the-policy-iteration-loop). +2. Look for `deny` actions. They include the destination, binary, and reason. +3. Update the policy to allow the blocked endpoint. Refer to [Policy Iteration Loop](../safety-and-privacy/policies.md#the-policy-iteration-loop). ## Policy Update Fails @@ -39,5 +39,5 @@ Troubleshoot problems with creating, connecting to, and configuring sandboxes. **Check:** 1. Are you changing a static field? `filesystem_policy`, `landlock`, and `process` cannot change after creation. -2. Are you adding/removing `network_policies` to change the network mode? This is not allowed — the mode is fixed at creation. +2. Are you adding/removing `network_policies` to change the network mode? This is not allowed. The mode is fixed at creation. 3. Check the error message in `nemoclaw sandbox policy list `. From eb4c9cb39867d8d3c79be31638317ebf2690eea0 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 5 Mar 2026 18:09:59 -0800 Subject: [PATCH 16/39] clean up --- docs/about/how-it-works.md | 190 -------------------- docs/about/index.md | 108 ----------- docs/index.md | 12 +- docs/{about => reference}/support-matrix.md | 0 docs/{about => }/release-notes.md | 0 docs/sandboxes/providers.md | 2 +- 6 files changed, 3 insertions(+), 309 deletions(-) delete mode 100644 docs/about/how-it-works.md delete mode 100644 docs/about/index.md rename docs/{about => reference}/support-matrix.md (100%) rename docs/{about => }/release-notes.md (100%) diff --git a/docs/about/how-it-works.md b/docs/about/how-it-works.md deleted file mode 100644 index ef6d0615..00000000 --- a/docs/about/how-it-works.md +++ /dev/null @@ -1,190 +0,0 @@ - - -# How It Works - -This page covers the NemoClaw architecture, its major subsystems, and the end-to-end flow from bootstrapping a cluster to running a safety-enforced sandbox. - -## Architecture - -```{mermaid} -flowchart TB - subgraph USER["User's Machine"] - CLI["Command-Line Interface"] - end - - subgraph CLUSTER["Kubernetes Cluster (single Docker container)"] - SERVER["Gateway / Control Plane"] - DB["Database (SQLite or Postgres)"] - - subgraph SBX["Sandbox Pod"] - SUPERVISOR["Sandbox Supervisor"] - PROXY["Network Proxy"] - CHILD["Agent Process (restricted)"] - OPA["Policy Engine (OPA)"] - end - end - - subgraph EXT["External Services"] - HOSTS["Allowed Hosts (github.com, api.anthropic.com, ...)"] - CREDS["Provider APIs (Claude, GitHub, GitLab, ...)"] - BACKEND["Inference Backends (LM Studio, vLLM, ...)"] - end - - CLI -- "gRPC / HTTPS" --> SERVER - CLI -- "SSH over HTTP CONNECT" --> SERVER - SERVER -- "CRUD + Watch" --> DB - SERVER -- "Create / Delete Pods" --> SBX - SUPERVISOR -- "Fetch Policy + Credentials" --> SERVER - SUPERVISOR -- "Spawn + Restrict" --> CHILD - CHILD -- "All network traffic" --> PROXY - PROXY -- "Evaluate request" --> OPA - PROXY -- "Allowed traffic only" --> HOSTS - PROXY -- "Inference reroute" --> SERVER - SERVER -- "Proxied inference" --> BACKEND - SERVER -. "Store / retrieve credentials" .-> CREDS -``` - -Users interact through the CLI, which communicates with a central gateway. The gateway manages sandbox lifecycle in Kubernetes, and each sandbox enforces its own policy locally. - -## Major Subsystems - -### Sandbox Execution Environment - -Each sandbox runs inside a container as two processes: a privileged **supervisor** and a restricted **child process** (the agent). Safety and privacy are enforced through four independent layers: - -- **Filesystem restrictions**: The Linux Landlock LSM controls which directories the agent can read and write. Attempts to access files outside the allowed set are blocked by the kernel. -- **System call filtering**: Seccomp prevents the agent from creating raw network sockets, eliminating proxy bypass. -- **Network namespace isolation**: The agent is placed in a separate network where the only reachable destination is the proxy, preventing data exfiltration. -- **Process privilege separation**: The agent runs as an unprivileged user, protecting against privilege escalation. - -All restrictions are driven by a YAML **policy** evaluated by an embedded OPA/Rego engine. Refer to [Safety & Privacy](../safety-and-privacy/index.md). - -### Network Proxy - -Every sandbox forces all outbound traffic through an HTTP CONNECT proxy. No data leaves without inspection. The proxy: - -1. **Identifies the requesting program** via the process table. -2. **Verifies binary integrity** with trust-on-first-use SHA256 hashing. -3. **Evaluates requests against policy** with per-binary, per-host granularity. -4. **Protects private infrastructure** by blocking DNS results that resolve to internal IP ranges. -5. **Performs L7 inspection** for configured endpoints, examining HTTP requests within TLS tunnels. -6. **Keeps inference traffic private** by intercepting AI API calls and rerouting them to policy-controlled backends. - -### Gateway - -The gateway is the central orchestration service that provides gRPC and HTTP APIs, sandbox lifecycle management, data persistence, TLS termination, SSH tunnel gateway, and real-time status streaming. - -### Providers - -Credentials are managed with a privacy-first design. API keys and tokens are stored separately from sandbox definitions, never appear in pod specs, and are fetched only at runtime. Refer to [Providers](../sandboxes/providers.md). - -### Inference Routing - -AI inference API calls are transparently intercepted and rerouted to policy-controlled backends, keeping sensitive prompts and responses on private infrastructure. Refer to [Inference Routing](../inference/index.md). - -### Cluster Infrastructure - -The entire platform packages into a single Docker container running k3s. Docker is the only dependency. - -## End-to-End Flow - -```{mermaid} -sequenceDiagram - participant User as User - participant CLI as CLI - participant Docker as Docker - participant GW as Gateway - participant K8s as Kubernetes - participant SBX as Sandbox - - User->>CLI: nemoclaw sandbox create -- claude - CLI->>CLI: Check for running cluster - alt No cluster found - CLI->>Docker: Bootstrap k3s cluster - Docker-->>CLI: Cluster ready - end - CLI->>CLI: Discover local credentials (ANTHROPIC_API_KEY, ~/.claude.json) - CLI->>GW: Upload credentials as provider - CLI->>GW: CreateSandbox(policy, providers) - GW->>K8s: Create sandbox pod - K8s-->>GW: Pod scheduled - GW-->>CLI: Sandbox provisioning - loop Wait for Ready - CLI->>GW: GetSandbox(name) - GW-->>CLI: Status update - end - CLI->>GW: CreateSshSession(sandbox_id) - GW-->>CLI: Session token - CLI->>SBX: SSH tunnel through gateway - User->>SBX: Interactive shell session -``` - -## What Happens Inside a Sandbox - -When a sandbox starts, the supervisor executes this sequence: - -1. **Load policy**: Fetches the YAML policy from the gateway. The policy defines all filesystem, network, and process restrictions. -2. **Fetch credentials**: Retrieves provider credentials via gRPC for injection into child processes. -3. **Set up filesystem isolation**: Configures Landlock rules. Writable directories are created and ownership is set automatically. -4. **Generate ephemeral TLS certificates**: Creates a per-sandbox CA for transparent TLS inspection. -5. **Create network namespace**: Isolates the agent's network so the only reachable destination is the proxy. -6. **Start the proxy**: Launches the HTTP CONNECT proxy with OPA policy evaluation. -7. **Start the SSH server**: Launches the embedded SSH daemon for interactive access. -8. **Spawn the agent**: Launches the child process with reduced privileges: seccomp filters, network namespace, Landlock rules, and credentials injected as environment variables. -9. **Begin policy polling**: Checks for policy updates every 30 seconds, enabling live changes without restart. - -## How Network Safety Works - -```{mermaid} -flowchart TD - A[Agent makes HTTPS request] --> B[Request routed to proxy via network namespace] - B --> C{OPA policy evaluation} - C -->|Endpoint + binary match| D[Allow: forward to destination] - C -->|No match, inference routes exist| E[Inspect for inference patterns] - C -->|No match, no routes| F[Deny: connection rejected] - E --> G{Known inference API?} - G -->|Yes| H[Route to configured backend] - G -->|No| F - D --> I{DNS resolves to private IP?} - I -->|Yes| F - I -->|No| J[Connection established] -``` - -Every connection is evaluated with three pieces of context: -- **Which program** is making the request (identified via `/proc`). -- **Which host and port** the program is trying to reach. -- **Whether the binary has been tampered with** since its first request. - -## How Credential Privacy Works - -Credentials flow through a privacy-preserving pipeline: - -1. **Discovery**: The CLI scans local environment variables and config files for credentials. -2. **Upload**: Credentials are sent to the gateway over mTLS and stored separately from sandbox definitions. -3. **Injection**: The supervisor fetches credentials through gRPC and injects them as environment variables. They never appear in Kubernetes pod specs. -4. **Isolation**: The sandbox policy controls which endpoints the agent can reach, so credentials cannot be exfiltrated. - -## How Inference Privacy Works - -When inference routing is configured, the proxy intercepts AI API calls and keeps them private: - -1. The agent calls the OpenAI/Anthropic SDK as normal. -2. The proxy TLS-terminates the connection and detects the inference API pattern. -3. The proxy strips the original authorization header and routes the request to a configured backend. -4. The backend's API key is injected by the router. The sandbox never sees it. -5. The response flows back to the agent transparently. - -This keeps prompts and responses on your private infrastructure while the agent operates as if it were calling the original API. - -## How Live Policy Updates Work - -Policies can be updated on running sandboxes without restarts: - -1. Push the updated policy: `nemoclaw sandbox policy set --policy updated.yaml --wait`. -2. The gateway stores the new revision as `pending`. -3. The sandbox detects the new version within 30 seconds. -4. The OPA engine atomically reloads with the new rules. -5. If the reload fails, the previous policy stays active (last-known-good behavior). diff --git a/docs/about/index.md b/docs/about/index.md deleted file mode 100644 index 09f8765d..00000000 --- a/docs/about/index.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: - page: "NVIDIA NemoClaw Overview" - nav: "Overview" -description: "Learn about NemoClaw, the safe and private runtime for autonomous AI agents. Run agents in sandboxed environments that protect your data, credentials, and infrastructure." -keywords: ["nemoclaw", "ai agent sandbox", "agent safety", "agent privacy", "sandboxed execution"] -topics: ["generative_ai", "cybersecurity"] -tags: ["ai_agents", "sandboxing", "security", "privacy", "inference_routing"] -content: - type: concept - difficulty: technical_beginner - audience: [engineer, data_scientist, devops] ---- - - - -# NVIDIA NemoClaw Overview - -NVIDIA NemoClaw is a safe, private runtime for autonomous AI agents. It provides sandboxed execution environments that protect your data, credentials, and infrastructure while giving agents the system access they need to be useful. Each sandbox enforces declarative YAML policies through Linux kernel-level isolation, a policy-enforcing network proxy, and a credential management pipeline. Agents run with exactly the permissions you grant and nothing more. - -You do not modify agent code to use NemoClaw. Instead, the CLI bootstraps a local Kubernetes cluster packaged in a single Docker container, creates sandboxes with the safety policies you define, and connects you to the running agent through an SSH tunnel. - -## How NemoClaw Works - -```{mermaid} -flowchart LR - CLI["CLI"] -->|gRPC| GW["Gateway"] - GW --> SBX["Sandbox"] - - subgraph SBX["Sandbox"] - direction TB - AGENT["Agent Process"] -->|All traffic| PROXY["Network Proxy"] - PROXY -->|Evaluate| OPA["Policy Engine"] - end - - PROXY -->|Allowed traffic| EXT["External Services"] - - style CLI fill:#ffffff,stroke:#000000,color:#000000 - style GW fill:#76b900,stroke:#000000,color:#000000 - style SBX fill:#f5f5f5,stroke:#000000,color:#000000 - style AGENT fill:#ffffff,stroke:#000000,color:#000000 - style PROXY fill:#76b900,stroke:#000000,color:#000000 - style OPA fill:#76b900,stroke:#000000,color:#000000 - style EXT fill:#ffffff,stroke:#000000,color:#000000 - - linkStyle default stroke:#76b900,stroke-width:2px -``` - -The CLI bootstraps a cluster, creates sandboxes, and connects you through SSH. Inside each sandbox, an agent process runs with kernel-level filesystem restrictions while all network traffic passes through a policy-enforcing proxy. The proxy evaluates every request against an OPA policy engine before allowing or denying access. For the full architecture and end-to-end flow, refer to [How It Works](how-it-works.md). - -## Key Capabilities - -:::{dropdown} Data Safety - -Filesystem restrictions prevent agents from reading sensitive files or writing outside designated directories. The Linux Landlock LSM controls which paths the agent can access, and seccomp filters block raw network socket creation. Restrictions are enforced at the kernel level. They cannot be bypassed by the agent process. -::: - -:::{dropdown} Network Privacy - -All outbound traffic passes through an HTTP CONNECT proxy that inspects every connection. The proxy identifies which program is making the request, verifies binary integrity through SHA256 hashing, and evaluates requests against per-host, per-binary policies. DNS results that resolve to private IP ranges are blocked automatically to prevent SSRF attacks. -::: - -:::{dropdown} Credential Privacy - -API keys and tokens are stored separately from sandbox definitions, never appear in container or pod specifications, and are fetched only at runtime over mTLS. The CLI auto-discovers local credentials for supported providers (Anthropic, OpenAI, GitHub, GitLab, NVIDIA) and uploads them through a privacy-preserving pipeline. Refer to [Providers](../sandboxes/providers.md) for the full list. -::: - -:::{dropdown} Inference Privacy - -AI API calls (OpenAI, Anthropic) are transparently intercepted by the proxy and rerouted to local or self-hosted backends such as LM Studio or vLLM. The agent calls its SDK as normal. NemoClaw swaps the destination and injects the backend's API key without the sandbox ever seeing it. Prompts and responses stay on your infrastructure. Refer to [Inference Routing](../inference/index.md) for configuration details. -::: - -:::{dropdown} Declarative Policies - -YAML policies define what each sandbox can access: filesystems, network endpoints, inference routes, and credential bindings. Policies can be updated on running sandboxes without restart: push a new policy revision and the OPA engine reloads atomically within 30 seconds. Refer to [Policies](../safety-and-privacy/policies.md) for the schema and examples. -::: - -:::{dropdown} Zero-Config Deployment - -The entire platform packages into a single Docker container running k3s. Docker is the only dependency. Two commands go from zero to a running sandbox: - -```bash -nemoclaw cluster admin deploy -nemoclaw sandbox create -- claude -``` - -No Kubernetes expertise is required. -::: - -## Use Cases - -| Use Case | Description | -| --- | --- | -| Autonomous coding agents | Run Claude, Codex, or OpenCode with full shell access while preventing unauthorized file reads, credential leaks, and network exfiltration. | -| Secure CI/CD agent execution | Execute AI-assisted build, test, and deploy workflows in sandboxes that restrict what the agent can reach on your network. | -| Private inference | Route all LLM API calls to self-hosted backends, keeping prompts, code, and responses off third-party servers. | -| Multi-tenant agent hosting | Run sandboxes for multiple users or teams on a shared cluster with isolated policies, credentials, and network access. | -| Compliance-sensitive environments | Enforce auditable, declarative policies that prove agents operate within defined boundaries for regulatory or security review. | -| Custom toolchain sandboxing | Bring your own container image with custom tools and dependencies while NemoClaw enforces the same safety guarantees. Refer to [Custom Containers](../sandboxes/custom-containers.md). | - -## Next Steps - -- [How It Works](how-it-works.md): Explore the architecture, major subsystems, and the end-to-end flow from cluster bootstrap to running sandbox. -- [Support Matrix](support-matrix.md): Find platform requirements, supported providers, agent tools, and compatibility details. -- [Release Notes](release-notes.md): Track what changed in each version. diff --git a/docs/index.md b/docs/index.md index 5dc393d1..47405fa8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -159,15 +159,7 @@ CLI commands, policy schema, environment variables, and system architecture. Get Started get-started/tutorials/index -``` - -```{toctree} -:caption: Concepts -:hidden: - -Overview -about/how-it-works -about/release-notes +release-notes ``` ```{toctree} @@ -214,7 +206,7 @@ observability/health :caption: Reference :hidden: -about/support-matrix +reference/support-matrix reference/cli reference/policy-schema reference/environment-variables diff --git a/docs/about/support-matrix.md b/docs/reference/support-matrix.md similarity index 100% rename from docs/about/support-matrix.md rename to docs/reference/support-matrix.md diff --git a/docs/about/release-notes.md b/docs/release-notes.md similarity index 100% rename from docs/about/release-notes.md rename to docs/release-notes.md diff --git a/docs/sandboxes/providers.md b/docs/sandboxes/providers.md index bb3a44fe..383d664c 100644 --- a/docs/sandboxes/providers.md +++ b/docs/sandboxes/providers.md @@ -132,7 +132,7 @@ environment dumps of the container spec. ## Supported Provider Types -For a list of supported provider types, refer to the [Support Matrix](../about/support-matrix.md#supported-provider-types). +For a list of supported provider types, refer to the [Support Matrix](../reference/support-matrix.md#supported-provider-types). ## Next Steps From 64065be29cecec64ba8724ae98e493822be0678f Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 5 Mar 2026 18:18:46 -0800 Subject: [PATCH 17/39] updates impacting docs --- docs/get-started/tutorials/run-claude.md | 2 +- docs/get-started/tutorials/run-opencode.md | 2 +- docs/reference/cli.md | 22 ++++++++++++++-------- docs/reference/policy-schema.md | 12 ++++++++++++ docs/safety-and-privacy/policies.md | 17 +++++++++++++++++ 5 files changed, 45 insertions(+), 10 deletions(-) diff --git a/docs/get-started/tutorials/run-claude.md b/docs/get-started/tutorials/run-claude.md index bd63b67a..97a9938b 100644 --- a/docs/get-started/tutorials/run-claude.md +++ b/docs/get-started/tutorials/run-claude.md @@ -63,7 +63,7 @@ $ nemoclaw sandbox list For a live dashboard view, launch the NemoClaw Terminal: ```console -$ nemoclaw gator +$ nemoclaw term ``` The terminal dashboard shows sandbox status, active network connections, and policy decisions in real time. diff --git a/docs/get-started/tutorials/run-opencode.md b/docs/get-started/tutorials/run-opencode.md index 841320d8..fdaaf42d 100644 --- a/docs/get-started/tutorials/run-opencode.md +++ b/docs/get-started/tutorials/run-opencode.md @@ -61,7 +61,7 @@ $ nemoclaw sandbox logs opencode-sandbox --tail Or launch the NemoClaw Terminal for a live view: ```console -$ nemoclaw gator +$ nemoclaw term ``` Look for lines like these in the output: diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 30671400..3b2aa222 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -23,12 +23,12 @@ nemoclaw │ └── tunnel ├── sandbox │ ├── create -│ ├── get +│ ├── get [name] │ ├── list │ ├── delete -│ ├── connect -│ ├── sync -│ ├── logs +│ ├── connect [name] +│ ├── sync [name] +│ ├── logs [name] │ ├── ssh-config │ ├── forward │ │ ├── start @@ -75,12 +75,12 @@ Create and manage isolated agent execution environments. | Command | Description | |---|---| | `nemoclaw sandbox create` | Create a new sandbox. See flag reference below. | -| `nemoclaw sandbox get ` | Show detailed information about a sandbox. | +| `nemoclaw sandbox get [name]` | Show detailed information about a sandbox. When name is omitted, uses the last-used sandbox. | | `nemoclaw sandbox list` | List all sandboxes in the active cluster. | | `nemoclaw sandbox delete ` | Delete one or more sandboxes by name. | -| `nemoclaw sandbox connect ` | Open an interactive SSH session into a running sandbox. | -| `nemoclaw sandbox sync ` | Sync files between host and sandbox. Use `--up` or `--down`. | -| `nemoclaw sandbox logs ` | View sandbox logs. Use `--tail` for streaming, `--source` and `--level` to filter. | +| `nemoclaw sandbox connect [name]` | Open an interactive SSH session into a running sandbox. When name is omitted, reconnects to the last-used sandbox. | +| `nemoclaw sandbox sync [name]` | Sync files between host and sandbox. Use `--up` or `--down`. When name is omitted, uses the last-used sandbox. | +| `nemoclaw sandbox logs [name]` | View sandbox logs. Use `--tail` for streaming, `--source` and `--level` to filter. When name is omitted, uses the last-used sandbox. | | `nemoclaw sandbox ssh-config ` | Print SSH config for a sandbox. Append to `~/.ssh/config` for VS Code Remote-SSH. | | `nemoclaw sandbox forward start ` | Forward a sandbox port to the host. Add `-d` for background mode. | | `nemoclaw sandbox forward stop ` | Stop an active port forward. | @@ -155,6 +155,12 @@ press `f` to follow live output, `s` to filter by source, and `q` to quit. Refer to {doc}`/sandboxes/terminal` for the full guide, including how to read log entries, diagnose blocked connections, and interpret inference interception. +## Sandbox Name Fallback + +Commands that accept an optional `[name]` argument---`get`, `connect`, `sync`, and `logs`---fall back to the last-used sandbox when the name is omitted. The CLI records the sandbox name each time you create or connect to a sandbox. When falling back, the CLI prints a hint showing which sandbox was selected. + +If no sandbox has been used yet and no name is provided, the command exits with an error prompting you to specify a name. + ## Environment Variables | Variable | Description | diff --git a/docs/reference/policy-schema.md b/docs/reference/policy-schema.md index 4a1c498d..3bacad0e 100644 --- a/docs/reference/policy-schema.md +++ b/docs/reference/policy-schema.md @@ -47,6 +47,16 @@ Controls filesystem access inside the sandbox. Paths not listed in either `read_ | `read_only` | list of strings | No | Paths the agent can read but not modify. Typically system directories like `/usr`, `/lib`, `/etc`. | | `read_write` | list of strings | No | Paths the agent can read and write. Typically `/sandbox` (working directory) and `/tmp`. | +**Validation constraints:** + +- Every path must be absolute (start with `/`). +- Paths must not contain `..` traversal components. The server normalizes paths before storage, but rejects policies where traversal would escape the intended scope. +- Read-write paths must not be overly broad (for example, `/` alone is rejected). +- Each individual path must not exceed 4096 characters. +- The combined total of `read_only` and `read_write` paths must not exceed 256. + +Policies that violate these constraints are rejected with `INVALID_ARGUMENT` at creation or update time. Disk-loaded YAML policies that fail validation fall back to a restrictive default. + Example: ```yaml @@ -92,6 +102,8 @@ Sets the OS-level identity for the agent process inside the sandbox. | `run_as_user` | string | No | The user name or UID the agent process runs as. Default: `sandbox`. | | `run_as_group` | string | No | The group name or GID the agent process runs as. Default: `sandbox`. | +**Validation constraint:** Neither `run_as_user` nor `run_as_group` may be set to `root` or `0`. Policies that request root process identity are rejected at creation or update time. + Example: ```yaml diff --git a/docs/safety-and-privacy/policies.md b/docs/safety-and-privacy/policies.md index c52a1d14..b79e6d72 100644 --- a/docs/safety-and-privacy/policies.md +++ b/docs/safety-and-privacy/policies.md @@ -212,6 +212,23 @@ $ nemoclaw sandbox policy get --rev 3 --full | `failed` | The revision failed validation. The previous good revision remains active. | | `superseded` | A newer revision has been loaded, replacing this one. | +## Policy Validation + +The server validates every policy at creation and update time. Policies that violate any of the following rules are rejected with exit code `1` (`INVALID_ARGUMENT`): + +| Rule | Description | +|---|---| +| No root identity | `run_as_user` and `run_as_group` cannot be `root` or `0`. | +| Absolute paths only | All filesystem paths must start with `/`. | +| No path traversal | Filesystem paths must not contain `..` components. | +| No overly broad writes | Read-write paths like `/` alone are rejected. | +| Path length limit | Each path must not exceed 4096 characters. | +| Path count limit | The combined total of `read_only` and `read_write` paths must not exceed 256. | + +When a disk-loaded YAML policy (via `--policy` or `NEMOCLAW_SANDBOX_POLICY`) fails validation, the sandbox falls back to a restrictive default policy rather than starting with an unsafe configuration. + +Refer to the [Policy Schema Reference](../reference/policy-schema.md) for the constraints documented alongside each field. + ## Safety Properties **Last-known-good.** From 91b122ee4f9ab07a7ba00da5026cbd225920f24e Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Fri, 6 Mar 2026 10:43:25 -0800 Subject: [PATCH 18/39] incorporate feedback --- docs/get-started/tutorials/index.md | 46 ------ docs/index.md | 42 +++--- docs/inference/configure-routes.md | 92 ++++++++++++ docs/inference/connect-sandboxes.md | 62 -------- docs/inference/create-routes.md | 49 ------- docs/inference/index.md | 96 +++++++------ docs/inference/manage-routes.md | 46 ------ docs/observability/health.md | 134 ----------------- docs/observability/logs.md | 67 --------- docs/reference/architecture.md | 36 ++--- docs/reference/cli.md | 2 +- docs/reference/environment-variables.md | 43 ------ docs/reference/support-matrix.md | 110 -------------- docs/resources/eula.md | 6 + docs/resources/index.md | 39 ----- docs/safety-and-privacy/index.md | 8 +- .../network-access-rules.md | 10 +- docs/safety-and-privacy/policies.md | 6 +- docs/sandboxes/community-sandboxes.md | 4 +- docs/sandboxes/create-and-manage.md | 14 +- docs/sandboxes/index.md | 67 --------- docs/sandboxes/providers.md | 28 +++- docs/sandboxes/terminal.md | 28 ++-- docs/troubleshooting.md | 135 ++++++++++++++++++ docs/troubleshooting/cluster-issues.md | 35 ----- .../custom-container-issues.md | 17 --- .../getting-more-information.md | 12 -- .../troubleshooting/port-forwarding-issues.md | 18 --- docs/troubleshooting/provider-issues.md | 26 ---- docs/troubleshooting/sandbox-issues.md | 43 ------ .../{get-started => }/tutorials/run-claude.md | 14 +- .../tutorials/run-openclaw.md | 24 ++-- .../tutorials/run-opencode.md | 24 ++-- 33 files changed, 412 insertions(+), 971 deletions(-) delete mode 100644 docs/get-started/tutorials/index.md create mode 100644 docs/inference/configure-routes.md delete mode 100644 docs/inference/connect-sandboxes.md delete mode 100644 docs/inference/create-routes.md delete mode 100644 docs/inference/manage-routes.md delete mode 100644 docs/observability/health.md delete mode 100644 docs/observability/logs.md delete mode 100644 docs/reference/environment-variables.md delete mode 100644 docs/reference/support-matrix.md create mode 100644 docs/resources/eula.md delete mode 100644 docs/resources/index.md delete mode 100644 docs/sandboxes/index.md create mode 100644 docs/troubleshooting.md delete mode 100644 docs/troubleshooting/cluster-issues.md delete mode 100644 docs/troubleshooting/custom-container-issues.md delete mode 100644 docs/troubleshooting/getting-more-information.md delete mode 100644 docs/troubleshooting/port-forwarding-issues.md delete mode 100644 docs/troubleshooting/provider-issues.md delete mode 100644 docs/troubleshooting/sandbox-issues.md rename docs/{get-started => }/tutorials/run-claude.md (73%) rename docs/{get-started => }/tutorials/run-openclaw.md (71%) rename docs/{get-started => }/tutorials/run-opencode.md (82%) diff --git a/docs/get-started/tutorials/index.md b/docs/get-started/tutorials/index.md deleted file mode 100644 index f14eeccb..00000000 --- a/docs/get-started/tutorials/index.md +++ /dev/null @@ -1,46 +0,0 @@ -# Tutorials - -Each tutorial walks through an end-to-end workflow from bootstrapping a cluster to running an agent inside a policy-enforced sandbox. Pick the tutorial that matches your agent and follow along. - -All tutorials assume you have [installed the CLI](../../index.md#install-the-nemoclaw-cli) and have Docker running. - -::::{grid} 1 1 2 2 -:gutter: 3 - -:::{grid-item-card} Run OpenClaw Safely -:link: run-openclaw -:link-type: doc - -Launch OpenClaw inside a NemoClaw sandbox with inference routing and policy enforcement. -+++ -{bdg-secondary}`Tutorial` -::: - -:::{grid-item-card} Run Claude Safely -:link: run-claude -:link-type: doc - -Run Anthropic Claude as a coding agent with credential management, inference routing, and policy enforcement. -+++ -{bdg-secondary}`Tutorial` -::: - -:::{grid-item-card} Run OpenCode with NVIDIA Inference -:link: run-opencode -:link-type: doc - -Set up opencode with NVIDIA inference routing, custom policies, and the full policy iteration loop. -+++ -{bdg-secondary}`Tutorial` -::: - -:::: - -```{toctree} -:hidden: -:maxdepth: 2 - -Run OpenClaw Safely -Run Claude Safely -Run OpenCode with NVIDIA Inference -``` diff --git a/docs/index.md b/docs/index.md index 47405fa8..0ec2850a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -76,14 +76,14 @@ Claude Code works out of the box with the default policy. $ nemoclaw sandbox create --from openclaw ``` -The `--from` flag pulls from the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) catalog---a collection of domain-specific sandbox images bundled with their own containers, policies, and skills. +The `--from` flag pulls from the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) catalog, which contains a collection of domain-specific sandbox images bundled with their own containers, policies, and skills. ::: :::: The agent runs with filesystem, network, process, and inference protection active. Credentials stay inside the sandbox, network access follows your policy, and inference traffic remains private. A single YAML policy controls all four protection layers and is hot-reloadable on a running sandbox. -For OpenCode or Codex, refer to the [](get-started/tutorials/run-opencode.md) tutorial for agent-specific setup. +For OpenCode or Codex, refer to the [](tutorials/run-opencode.md) tutorial for agent-specific setup. --- @@ -93,7 +93,7 @@ For OpenCode or Codex, refer to the [](get-started/tutorials/run-opencode.md) tu :gutter: 3 :::{grid-item-card} Tutorials -:link: get-started/tutorials/index +:link: tutorials/run-claude :link-type: doc Step-by-step walkthroughs for Claude Code, OpenClaw, and OpenCode with NVIDIA inference. @@ -158,15 +158,21 @@ CLI commands, policy schema, environment variables, and system architecture. :hidden: Get Started -get-started/tutorials/index -release-notes +``` + +```{toctree} +:caption: Tutorials +:hidden: + +Run Claude Safely +Run OpenClaw Safely +Run OpenCode with NVIDIA Inference ``` ```{toctree} :caption: Sandboxes :hidden: -sandboxes/index sandboxes/create-and-manage sandboxes/providers sandboxes/custom-containers @@ -189,27 +195,16 @@ safety-and-privacy/network-access-rules :hidden: inference/index -inference/create-routes -inference/manage-routes -inference/connect-sandboxes -``` - -```{toctree} -:caption: Observability -:hidden: - -observability/logs -observability/health +inference/configure-routes ``` ```{toctree} :caption: Reference :hidden: -reference/support-matrix +release-notes reference/cli reference/policy-schema -reference/environment-variables reference/architecture ``` @@ -217,17 +212,12 @@ reference/architecture :caption: Troubleshooting :hidden: -troubleshooting/cluster-issues -troubleshooting/sandbox-issues -troubleshooting/provider-issues -troubleshooting/custom-container-issues -troubleshooting/port-forwarding-issues -troubleshooting/getting-more-information +troubleshooting ``` ```{toctree} :caption: Resources :hidden: -resources/index +resources/eula ``` diff --git a/docs/inference/configure-routes.md b/docs/inference/configure-routes.md new file mode 100644 index 00000000..24f5c656 --- /dev/null +++ b/docs/inference/configure-routes.md @@ -0,0 +1,92 @@ + + +# Configure Inference Routes + +This guide covers how to create and manage inference routes so that sandboxes can route AI API calls from userland code to policy-controlled backends. You will learn to create routes, connect them to sandboxes via policy, and manage routes across a cluster. + +:::{note} +Inference routes are for *userland code*, which are scripts and programs that the agent writes and executes inside the sandbox. The agent's own API traffic flows directly through network policies, not through inference routing. See {doc}`../safety-and-privacy/network-access-rules` for the distinction between agent traffic and userland traffic. +::: + +## Create a Route + +Use `nemoclaw inference create` to register a new inference backend: + +```console +$ nemoclaw inference create \ + --routing-hint local \ + --base-url https://my-llm.example.com \ + --model-id my-model-v1 \ + --api-key sk-abc123 +``` + +This creates a route named after the routing hint. Any sandbox whose policy includes `local` in its `inference.allowed_routes` list can use this route. If you omit `--protocol`, the CLI probes the endpoint and auto-detects the supported protocol (see [Supported API Patterns](index.md#supported-api-patterns)). See the [CLI Reference](../reference/cli.md#inference-create-flags) for all flags. + +## Manage Routes + +### List all routes + +```console +$ nemoclaw inference list +``` + +### Update a route + +Change any field on an existing route: + +```console +$ nemoclaw inference update --base-url https://new-backend.example.com +``` + +```console +$ nemoclaw inference update --model-id updated-model-v2 --api-key sk-new-key +``` + +### Delete a route + +```console +$ nemoclaw inference delete +``` + +Deleting a route that is referenced by running sandboxes does not interrupt those sandboxes immediately. Future inference requests that would have matched the deleted route will be denied. + +## Connect a Sandbox to Routes + +Inference routes take effect only when a sandbox policy references the route's `routing_hint` in its `inference.allowed_routes` list. + +### Step 1: Add the routing hint to your policy + +```yaml +inference: + allowed_routes: + - local +``` + +### Step 2: Create or update the sandbox with that policy + +```console +$ nemoclaw sandbox create --policy ./my-policy.yaml --keep -- claude +``` + +Or, if the sandbox is already running, push an updated policy: + +```console +$ nemoclaw sandbox policy set --policy ./my-policy.yaml --wait +``` + +The `inference` section is a dynamic field, so you can add or remove routing hints on a running sandbox without recreating it. + +## Good to Know + +- Cluster-level: routes are shared across all sandboxes in the cluster, not scoped to one sandbox. +- Per-model: each route maps to one model. Create multiple routes with the same `--routing-hint` but different `--model-id` values to expose multiple models. +- Hot-reloadable: routes can be created, updated, or deleted at any time without restarting sandboxes. + +## Next Steps + +- {doc}`index`: understand the inference routing architecture, interception sequence, and routing hints. +- {doc}`../safety-and-privacy/network-access-rules`: configure the network policies that control agent traffic (as opposed to userland inference traffic). +- {doc}`../safety-and-privacy/policies`: the full policy iteration workflow. diff --git a/docs/inference/connect-sandboxes.md b/docs/inference/connect-sandboxes.md deleted file mode 100644 index b46a0bf9..00000000 --- a/docs/inference/connect-sandboxes.md +++ /dev/null @@ -1,62 +0,0 @@ - - -# Connect Sandboxes to Inference Routes - -Inference routes take effect only when a sandbox policy references the route's `routing_hint` in its `inference.allowed_routes` list. This page shows how to wire them together. - -## Step 1: Add the Routing Hint to Your Policy - -In your policy YAML, include the routing hint that matches the route you created: - -```yaml -inference: - allowed_routes: - - local -``` - -## Step 2: Create or Update the Sandbox with That Policy - -When creating a new sandbox: - -```console -$ nemoclaw sandbox create --policy ./my-policy.yaml --keep -- claude -``` - -Or, if the sandbox is already running, push an updated policy: - -```console -$ nemoclaw sandbox policy set --policy ./my-policy.yaml --wait -``` - -The `inference` section is a dynamic field, so you can add or remove routing hints on a running sandbox without recreating it. - -## How It Works - -After a sandbox has `allowed_routes` configured, the proxy intercepts outbound connections that do not match any explicit `network_policies` entry. If the request matches a known inference API pattern (for example, `POST /v1/chat/completions`), the proxy: - -1. TLS-terminates the connection. -2. Strips the original authorization header. -3. Selects a route whose `routing_hint` appears in the sandbox's `allowed_routes`. -4. Injects the route's API key and model ID. -5. Forwards the request to the route's backend. - -The agent's code sees a normal HTTP response as if it came from the original API. - -:::{tip} -To avoid passing `--policy` every time, set a default policy via environment variable: - -```console -$ export NEMOCLAW_SANDBOX_POLICY=./my-policy.yaml -$ nemoclaw sandbox create --keep -- claude -``` -::: - -## Next Steps - -- {doc}`create-routes`: Register new inference backends. -- {doc}`manage-routes`: List, update, and delete routes. -- [Policies](../safety-and-privacy/policies.md): The full policy iteration workflow. -- [Network Access Control](../safety-and-privacy/network-access-rules.md): How agent traffic differs from userland inference traffic. diff --git a/docs/inference/create-routes.md b/docs/inference/create-routes.md deleted file mode 100644 index 71f9f765..00000000 --- a/docs/inference/create-routes.md +++ /dev/null @@ -1,49 +0,0 @@ - - -# Create Inference Routes - -Use `nemoclaw inference create` to register a new inference backend that sandboxes can route AI API calls to. - -:::{note} -Inference routes are for **userland code**: scripts and programs that the agent writes and executes inside the sandbox. The agent's own API traffic flows directly through network policies, not through inference routing. Refer to {doc}`../safety-and-privacy/network-access-rules` for the distinction between agent traffic and userland traffic. -::: - -## Create a Route - -```console -$ nemoclaw inference create \ - --routing-hint local \ - --base-url https://my-llm.example.com \ - --model-id my-model-v1 \ - --api-key sk-abc123 -``` - -This creates a route named after the routing hint. Any sandbox whose policy includes `local` in its `inference.allowed_routes` list can use this route. If you omit `--protocol`, the CLI probes the endpoint and auto-detects the supported protocol (refer to [Supported API Patterns](index.md#supported-api-patterns)). - -## Flags - -| Flag | Description | -|------|-------------| -| `--routing-hint` (required) | Name used in sandbox policy to reference this route. | -| `--base-url` (required) | Backend inference endpoint URL. | -| `--model-id` (required) | Model identifier sent to the backend. | -| `--api-key` | API key for the backend endpoint. | -| `--protocol` | Supported protocol(s): `openai_chat_completions`, `openai_completions`, `anthropic_messages` (repeatable, auto-detected if omitted). | -| `--disabled` | Create the route in a disabled state. | - -Refer to the [CLI Reference](../reference/cli.md#inference-commands) for the full command specification. - -## Good to Know - -- **Cluster-level**: Routes are shared across all sandboxes in the cluster, not scoped to one sandbox. -- **Per-model**: Each route maps to one model. Create multiple routes with the same `--routing-hint` but different `--model-id` values to expose multiple models. -- **Hot-reloadable**: Routes can be created, updated, or deleted at any time without restarting sandboxes. - -## Next Steps - -- {doc}`manage-routes`: List, update, and delete inference routes. -- {doc}`connect-sandboxes`: Connect a sandbox to inference routes via policy. -- {doc}`index`: Understand the inference routing architecture and interception sequence. diff --git a/docs/inference/index.md b/docs/inference/index.md index a50284e8..3a973835 100644 --- a/docs/inference/index.md +++ b/docs/inference/index.md @@ -3,67 +3,81 @@ SPDX-License-Identifier: Apache-2.0 --> -# About Inference Routing +# Inference Routing -The inference routing system keeps your AI inference traffic private by transparently intercepting API calls from sandboxed agents and rerouting them to policy-controlled backends. This enables organizations to keep sensitive prompts and model responses on private infrastructure. It redirects traffic to local or self-hosted models without modifying the agent's code. +The inference routing system keeps your AI inference traffic private by +transparently intercepting API calls from sandboxed agents and rerouting them +to backends you control. + +:::{note} +Inference routing applies to userland traffic: code that the agent writes +or runs, not the agent itself. The agent's own API calls (e.g., Claude calling +`api.anthropic.com`) go direct via network policy. See +{doc}`/safety-and-privacy/network-access-rules` for the distinction. +::: ## How It Works -When an agent inside a sandbox makes an API call (for example, using the OpenAI or Anthropic SDK), the request flows through the sandbox proxy. If the destination does not match any explicit network policy but the sandbox has inference routes configured, the proxy: +When userland code inside a sandbox makes an API call (e.g., using the OpenAI +or Anthropic SDK), the request flows through the sandbox proxy. If the +destination does not match any explicit network policy but the sandbox has +inference routes configured, the proxy: -1. **TLS-terminates** the connection using the sandbox's ephemeral CA. -2. **Detects the inference API pattern** (for example, `POST /v1/chat/completions` for OpenAI, `POST /v1/messages` for Anthropic). -3. **Strips authorization headers** and forwards the request to a matching backend. -4. **Rewrites the authorization** with the route's API key and injects the correct model ID. -5. **Returns the response** to the agent. The agent sees a normal HTTP response as if it came from the original API. +1. TLS-terminates the connection using the sandbox's ephemeral CA. +2. Detects the inference API pattern (e.g., `POST /v1/chat/completions`). +3. Strips authorization headers and forwards to a matching backend. +4. Rewrites the authorization with the route's API key and model ID. +5. Returns the response to the agent's code. The agent sees a normal HTTP + response as if it came from the original API. -Agents need zero code changes. Standard OpenAI/Anthropic SDK calls work transparently. +The agent's code needs zero changes. Standard OpenAI/Anthropic SDK calls work +transparently. ```{mermaid} sequenceDiagram - participant Agent as Sandboxed Agent + participant Code as Userland Code participant Proxy as Sandbox Proxy - participant OPA as OPA Engine - participant Router as Local Router - participant Backend as Backend (e.g., LM Studio) + participant OPA as Policy Engine + participant Router as Privacy Router + participant Backend as Your Backend - Agent->>Proxy: CONNECT api.openai.com:443 - Proxy->>OPA: evaluate_network_action(input) + Code->>Proxy: CONNECT api.openai.com:443 + Proxy->>OPA: evaluate policy OPA-->>Proxy: InspectForInference - Proxy-->>Agent: 200 Connection Established - Proxy->>Proxy: TLS terminate (ephemeral CA) - Agent->>Proxy: POST /v1/chat/completions - Proxy->>Proxy: detect_inference_pattern() + Proxy-->>Code: 200 Connection Established + Proxy->>Proxy: TLS terminate + Code->>Proxy: POST /v1/chat/completions Proxy->>Router: route to matching backend - Router->>Backend: POST /v1/chat/completions - Backend-->>Router: 200 OK + Router->>Backend: forwarded request + Backend-->>Router: response Router-->>Proxy: response - Proxy-->>Agent: HTTP 200 OK (re-encrypted) + Proxy-->>Code: HTTP 200 OK ``` -## Working with Inference Routes +## Supported API Patterns -- {doc}`create-routes`: Register a new inference backend with `nemoclaw inference create`. -- {doc}`manage-routes`: List, update, and delete inference routes. -- {doc}`connect-sandboxes`: Connect a sandbox to inference routes via policy. +The proxy detects these inference patterns: -## Key Design Properties +| Pattern | Method | Path | +|---|---|---| +| OpenAI Chat Completions | POST | `/v1/chat/completions` | +| OpenAI Completions | POST | `/v1/completions` | +| Anthropic Messages | POST | `/v1/messages` | -- **Zero agent code changes**: Standard SDK calls work transparently. -- **Inference privacy**: Prompts and responses stay on your infrastructure when routed to local backends. -- **Credential isolation**: The sandbox never sees the real API key for the backend, protecting your credentials. -- **Policy-controlled**: `inference.allowed_routes` determines which routes a sandbox can use. -- **Hot-reloadable**: The `inference` policy field is dynamic and can be updated on a running sandbox. -- **Automatic cache refresh**: In cluster mode, the sandbox refreshes its route cache from the gateway every 30 seconds. +If an intercepted request does not match any known pattern, it is denied. -## Supported API Patterns +## Key Properties -The proxy detects these inference API patterns: +- Zero code changes: standard SDK calls work transparently. +- Inference privacy: prompts and responses stay on your infrastructure. +- Credential isolation: the agent's code never sees your backend API key. +- Policy-controlled: `inference.allowed_routes` determines which routes a + sandbox can use. +- Hot-reloadable: update `allowed_routes` on a running sandbox without + restarting. -| Pattern | Method | Path | -|---------|--------|------| -| `openai_chat_completions` | POST | `/v1/chat/completions` | -| `openai_completions` | POST | `/v1/completions` | -| `anthropic_messages` | POST | `/v1/messages` | +## Next Steps -If an intercepted request does not match any known pattern, it is denied with a descriptive error. +- {doc}`configure-routes`: create and manage inference routes. +- {doc}`/safety-and-privacy/network-access-rules`: understand agent traffic vs. + userland traffic. diff --git a/docs/inference/manage-routes.md b/docs/inference/manage-routes.md deleted file mode 100644 index 4166cfc7..00000000 --- a/docs/inference/manage-routes.md +++ /dev/null @@ -1,46 +0,0 @@ - - -# Manage Inference Routes - -List, update, and delete inference routes across your cluster. - -## List All Routes - -```console -$ nemoclaw inference list -``` - -## Update a Route - -Change any field on an existing route: - -```console -$ nemoclaw inference update --base-url https://new-backend.example.com -``` - -```console -$ nemoclaw inference update --model-id updated-model-v2 --api-key sk-new-key -``` - -## Delete a Route - -```console -$ nemoclaw inference delete -``` - -Deleting a route that is referenced by running sandboxes does not interrupt those sandboxes immediately. The proxy denies future inference requests that would have matched the deleted route. - -## Behavior Notes - -- Routes are **cluster-level**: They are shared across all sandboxes in the cluster, not scoped to one sandbox. -- Each route maps to **one model**. Create multiple routes with the same `--routing-hint` but different `--model-id` values to expose multiple models. -- Route changes are **hot-reloadable**: Sandboxes pick up new, updated, or deleted routes without restarting. - -## Next Steps - -- {doc}`create-routes`: Register a new inference backend. -- {doc}`connect-sandboxes`: Connect a sandbox to inference routes through policy. -- [CLI Reference](../reference/cli.md#inference-commands): Full command specification for all inference commands. diff --git a/docs/observability/health.md b/docs/observability/health.md deleted file mode 100644 index 361cc8dc..00000000 --- a/docs/observability/health.md +++ /dev/null @@ -1,134 +0,0 @@ - - -# Cluster and Sandbox Health - -NemoClaw provides two ways to monitor health: the CLI for quick checks and the NemoClaw Terminal for a live dashboard. - -## CLI - -Check cluster health: - -```console -$ nemoclaw cluster status -``` - -Shows gateway connectivity and version. - -Check sandbox status: - -```console -$ nemoclaw sandbox list -$ nemoclaw sandbox get -``` - -`sandbox list` shows all sandboxes with their current phase. `sandbox get` returns detailed information for a single sandbox, including status, image, attached providers, and policy revision. - -## NemoClaw Terminal - -The NemoClaw Terminal is a terminal user interface inspired by [k9s](https://k9scli.io/). Instead of typing individual CLI commands to check cluster health, list sandboxes, and manage resources, it gives you a real-time, keyboard-driven dashboard. - -### Launching the Terminal - -```console -$ nemoclaw term -$ nemoclaw term --cluster prod -$ NEMOCLAW_CLUSTER=prod nemoclaw term -``` - -The terminal inherits all CLI configuration: cluster selection, TLS settings, and verbosity flags work the same way. No separate configuration is needed. - -### Screen Layout - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ NemoClaw ─ my-cluster ─ Dashboard ● Healthy │ ← title bar -├─────────────────────────────────────────────────────────────────┤ -│ │ -│ (view content — Dashboard or Sandboxes) │ ← main area -│ │ -├─────────────────────────────────────────────────────────────────┤ -│ [1] Dashboard [2] Sandboxes │ [?] Help [q] Quit │ ← nav bar -├─────────────────────────────────────────────────────────────────┤ -│ : │ ← command bar -└─────────────────────────────────────────────────────────────────┘ -``` - -- **Title bar**: NemoClaw logo, cluster name, current view, and live health status. -- **Main area**: The active view. -- **Navigation bar**: Available views with shortcut keys. -- **Command bar**: Appears when you press `:` (vim-style). - -### Views - -#### Dashboard - -Shows your cluster at a glance: - -- **Cluster name** and **gateway endpoint**. -- **Health status**: Polls every two seconds: - - `●` **Healthy** (green): Everything is running normally. - - `◐` **Degraded** (yellow): The cluster is up but something needs attention. - - `○` **Unhealthy** (red): The cluster is not operating correctly. -- **Sandbox count**. - -#### Sandboxes - -A live table of all sandboxes: - -| Column | Description | -|--------|-------------| -| NAME | Sandbox name. | -| STATUS | Current phase, color-coded (green = Ready, yellow = Provisioning, red = Error). | -| AGE | Time since creation. | -| IMAGE | Container image. | -| PROVIDERS | Attached provider names. | -| NOTES | Metadata like forwarded ports (`fwd:8080,3000`). | - -Navigate with `j`/`k` or arrow keys. - -### Keyboard Controls - -#### Normal Mode - -| Key | Action | -|-----|--------| -| `1` | Switch to Dashboard. | -| `2` | Switch to Sandboxes. | -| `j` / `↓` | Move selection down. | -| `k` / `↑` | Move selection up. | -| `:` | Enter command mode. | -| `q` | Quit the terminal. | -| `Ctrl+C` | Force quit. | - -#### Command Mode - -Press `:` to open the command bar. Type a command and press `Enter`. - -| Command | Action | -|---------|--------| -| `quit` / `q` | Quit the terminal. | -| `dashboard` / `1` | Switch to Dashboard. | -| `sandboxes` / `2` | Switch to Sandboxes. | - -Press `Esc` to cancel. - -### Port Forwarding - -When creating a sandbox in the terminal, specify ports in the **Ports** field (comma-separated, for example, `8080,3000`). After the sandbox reaches `Ready` state, the terminal automatically spawns background SSH tunnels. Forwarded ports appear in the **NOTES** column and in the sandbox detail view. - -### Data Refresh - -The terminal polls the cluster every two seconds. Both cluster health and the sandbox list update automatically. No manual refresh needed. - -### Theme - -The NemoClaw Terminal uses a dark terminal theme based on the NVIDIA brand palette: - -- **Background**: Terminal black. -- **Text**: White for primary, dimmed for secondary. -- **Accent**: NVIDIA Green (`#76b900`) for selected rows, active tabs, and healthy status. -- **Borders**: Everglade (`#123123`) for structural separators. -- **Status**: Green = Ready/Healthy, Yellow = Provisioning/Degraded, Red = Error/Unhealthy. diff --git a/docs/observability/logs.md b/docs/observability/logs.md deleted file mode 100644 index 94963a20..00000000 --- a/docs/observability/logs.md +++ /dev/null @@ -1,67 +0,0 @@ - - -# Sandbox Logs - -View recent logs from a sandbox: - -```console -$ nemoclaw sandbox logs my-sandbox -``` - -## Live Streaming - -Stream logs in real time: - -```console -$ nemoclaw sandbox logs my-sandbox --tail -``` - -## Filtering - -Filter by source, level, and time range: - -```console -$ nemoclaw sandbox logs my-sandbox --tail --source sandbox --level warn -$ nemoclaw sandbox logs my-sandbox --since 5m -$ nemoclaw sandbox logs my-sandbox --source gateway --level error -``` - -| Flag | Description | -|------|-------------| -| `--tail` | Stream live logs (does not exit). | -| `--source` | Filter by source: `gateway`, `sandbox`, or `all` (repeatable). | -| `--level` | Minimum log level: `error`, `warn`, `info`, `debug`, `trace`. | -| `--since` | Show logs from this duration ago (for example, `5m`, `1h`, `30s`). | -| `-n ` | Number of log lines to fetch (default: 200). | - -## Log Sources - -| Source | Content | -|--------|---------| -| `gateway` | Gateway-side events: sandbox lifecycle, gRPC calls, pod management. | -| `sandbox` | Sandbox-side events: proxy decisions, policy evaluation, connection allows/denies. | - -## Monitoring Denied Actions - -When iterating on sandbox policies, the most useful view is sandbox-level deny events: - -```console -$ nemoclaw sandbox logs my-sandbox --tail --source sandbox -``` - -Deny log entries include: - -- **Destination host and port**: What the agent tried to reach. -- **Binary path**: Which program attempted the connection. -- **Deny reason**: Why the connection was blocked (no matching policy, binary mismatch, etc.). - -This information drives the [policy iteration loop](../safety-and-privacy/policies.md#the-policy-iteration-loop). - -## Log Architecture - -Sandbox logs are pushed from the sandbox process to the gateway using a background batching layer. The sandbox collects log entries from its tracing subscriber and streams them to the gateway through gRPC in batches. The gateway stores log entries and makes them available via the CLI's `logs` command. - -This push-based model means logs are available even if you are not actively streaming. You can always retrieve recent logs after the fact. diff --git a/docs/reference/architecture.md b/docs/reference/architecture.md index a9a8fcfb..7c6d5841 100644 --- a/docs/reference/architecture.md +++ b/docs/reference/architecture.md @@ -11,10 +11,10 @@ The system has four core components. | Component | Role | |---|---| -| **Gateway** | Control-plane API that coordinates sandbox lifecycle and state, acts as the auth boundary, and brokers requests across the platform. | -| **Sandbox** | Isolated runtime that includes container supervision and general L7 egress routing. | -| **Policy Engine** | Policy definition and enforcement layer for filesystem, network, and process constraints. Defense in depth enforces policies from the application layer down to infrastructure and kernel layers. | -| **Privacy Router** | Privacy-aware LLM routing layer that keeps sensitive context on sandbox compute and routes based on cost/privacy policy. | +| Gateway | Control-plane API that coordinates sandbox lifecycle and state, acts as the auth boundary, and brokers requests across the platform. | +| Sandbox | Isolated runtime that includes container supervision and general L7 egress routing. | +| Policy Engine | Policy definition and enforcement layer for filesystem, network, and process constraints. Defense in depth enforces policies from the application layer down to infrastructure and kernel layers. | +| Privacy Router | Privacy-aware LLM routing layer that keeps sensitive context on sandbox compute and routes based on cost/privacy policy. | ## Component Diagram @@ -68,11 +68,11 @@ The gateway is the central control-plane API. It coordinates sandbox lifecycle and state, acts as the auth boundary, and brokers all requests across the platform. It exposes a gRPC API consumed by the CLI and handles: -- Sandbox lifecycle---creates, monitors, and deletes sandbox pods. -- Provider storage---stores encrypted provider credentials. -- Policy distribution---delivers policy YAML to sandboxes at startup and on +- Sandbox lifecycle: creates, monitors, and deletes sandbox pods. +- Provider storage: stores encrypted provider credentials. +- Policy distribution: delivers policy YAML to sandboxes at startup and on hot-reload. -- SSH termination---terminates SSH tunnels from the CLI and routes them to +- SSH termination: terminates SSH tunnels from the CLI and routes them to the correct sandbox. The CLI never talks to sandbox pods directly. All commands go through the @@ -89,14 +89,14 @@ process, an L7 proxy, and the agent. The supervisor is the sandbox's init process. It establishes all isolation boundaries before starting the agent: -1. **Fetch credentials** from the gateway for all attached providers. -2. **Set up the network namespace.** The sandbox gets its own network stack +1. Fetch credentials from the gateway for all attached providers. +2. Set up the network namespace. The sandbox gets its own network stack with no default route. All outbound traffic is redirected through the proxy. -3. **Apply Landlock** filesystem restrictions based on the policy. -4. **Apply seccomp** filters to restrict available system calls. -5. **Start the L7 proxy** in the sandbox's network namespace. -6. **Start the SSH server** for interactive access. -7. **Start the agent** as a child process with credentials injected as +3. Apply Landlock filesystem restrictions based on the policy. +4. Apply seccomp filters to restrict available system calls. +5. Start the L7 proxy in the sandbox's network namespace. +6. Start the SSH server for interactive access. +7. Start the agent as a child process with credentials injected as environment variables. ### L7 Proxy @@ -104,11 +104,11 @@ boundaries before starting the agent: Every outbound TCP connection from any process in the sandbox is routed through the proxy. For each connection, the proxy: -1. **Resolves the calling binary** through `/proc//exe`, ancestor process +1. Resolves the calling binary through `/proc//exe`, ancestor process walking, and `/proc//cmdline`. -2. **Queries the policy engine** with the destination host, port, and resolved +2. Queries the policy engine with the destination host, port, and resolved binary path. -3. **Acts on the decision**---allow the connection directly, hand it to the +3. Acts on the decision: allow the connection directly, hand it to the privacy router for inference routing, or deny it. Refer to [How the Proxy Evaluates Connections](../safety-and-privacy/network-access-rules.md#how-the-proxy-evaluates-connections) for the full decision model. diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 3b2aa222..6406d923 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -157,7 +157,7 @@ entries, diagnose blocked connections, and interpret inference interception. ## Sandbox Name Fallback -Commands that accept an optional `[name]` argument---`get`, `connect`, `sync`, and `logs`---fall back to the last-used sandbox when the name is omitted. The CLI records the sandbox name each time you create or connect to a sandbox. When falling back, the CLI prints a hint showing which sandbox was selected. +Commands that accept an optional `[name]` argument, such as `get`, `connect`, `sync`, and `logs`, fall back to the last-used sandbox when the name is omitted. The CLI records the sandbox name each time you create or connect to a sandbox. When falling back, the CLI prints a hint showing which sandbox was selected. If no sandbox has been used yet and no name is provided, the command exits with an error prompting you to specify a name. diff --git a/docs/reference/environment-variables.md b/docs/reference/environment-variables.md deleted file mode 100644 index 7d824fc3..00000000 --- a/docs/reference/environment-variables.md +++ /dev/null @@ -1,43 +0,0 @@ - - -# Environment Variables - -## CLI Variables - -| Variable | Description | -|----------|-------------| -| `NEMOCLAW_CLUSTER` | Override the active cluster name (same as `--cluster` flag). | -| `NEMOCLAW_SANDBOX_POLICY` | Path to default sandbox policy YAML (fallback when `--policy` is not provided). | - -## Sandbox Variables - -These variables are set inside sandbox processes automatically: - -| Variable | Description | -|----------|-------------| -| `NEMOCLAW_SANDBOX` | Set to `1` inside all sandbox processes. | -| `HTTP_PROXY` | Proxy URL for HTTP traffic (set in proxy mode). | -| `HTTPS_PROXY` | Proxy URL for HTTPS traffic (set in proxy mode). | -| `ALL_PROXY` | Proxy URL for all traffic (set in proxy mode). | -| `SSL_CERT_FILE` | Path to the combined CA bundle (system CAs + sandbox ephemeral CA). | -| `NODE_EXTRA_CA_CERTS` | Same CA bundle path, for Node.js applications. | -| `REQUESTS_CA_BUNDLE` | Same CA bundle path, for Python requests library. | - -Provider credentials are also injected as environment variables. The specific variables depend on which providers are attached (for example, `ANTHROPIC_API_KEY` for Claude, `GITHUB_TOKEN` for GitHub). - -## Sandbox Supervisor Variables - -These are used by the sandbox supervisor process and are not typically set by users: - -| Variable | Description | -|----------|-------------| -| `NEMOCLAW_SANDBOX_ID` | Sandbox ID (set by gateway in pod spec). | -| `NEMOCLAW_ENDPOINT` | Gateway gRPC endpoint (set by gateway in pod spec). | -| `NEMOCLAW_POLICY_RULES` | Path to `.rego` file (file mode only). | -| `NEMOCLAW_POLICY_DATA` | Path to YAML policy data file (file mode only). | -| `NEMOCLAW_INFERENCE_ROUTES` | Path to YAML inference routes file (standalone mode). | -| `NEMOCLAW_POLICY_POLL_INTERVAL_SECS` | Override policy poll interval (default: 30 seconds). | -| `NEMOCLAW_SANDBOX_COMMAND` | Default command when none specified (set to `sleep infinity` by server). | diff --git a/docs/reference/support-matrix.md b/docs/reference/support-matrix.md deleted file mode 100644 index e2c23ebe..00000000 --- a/docs/reference/support-matrix.md +++ /dev/null @@ -1,110 +0,0 @@ - - -# Support Matrix - -This page lists the platforms, kernel features, providers, protocols, and tools that NVIDIA NemoClaw supports. - -## Platform Requirements - -The following software and runtime dependencies are required to install and run NemoClaw. - -| Requirement | Supported | -|-------------|-----------| -| **Operating System** | Linux (sandbox runtime). macOS and Linux (CLI). | -| **Docker** | Required for cluster bootstrap. | -| **Python** | 3.12+ (for CLI installation with `pip`). | -| **Rust** | 1.88+ (for building from source). | -| **Kubernetes** | k3s (bundled, no external cluster needed). | - -## Linux Kernel Features - -The sandbox isolation mechanisms require the following Linux kernel features: - -| Feature | Minimum Kernel | Purpose | -|---------|---------------|---------| -| **Landlock** | 5.13+ (ABI V1) | Filesystem access restriction. | -| **seccomp-BPF** | 3.5+ | System call filtering. | -| **Network namespaces** | 2.6.29+ | Network isolation for sandbox processes. | -| **`/proc` filesystem** | — | Process identity resolution for proxy. | - -:::{note} -When `landlock.compatibility` is set to `best_effort` (the default), the sandbox runs with the best available Landlock ABI. Set to `hard_requirement` to fail startup if the required ABI is not available. -::: - -## Supported Provider Types - -Providers supply credentials to sandboxes. NemoClaw can auto-discover credentials from environment variables and config files on your local machine. - -| Type | Environment Variables Injected | Typical Use | -|---|---|---| -| `claude` | `ANTHROPIC_API_KEY`, `CLAUDE_API_KEY` | Claude Code, Anthropic API | -| `codex` | `OPENAI_API_KEY` | OpenAI Codex | -| `opencode` | `OPENCODE_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY` | opencode tool | -| `github` | `GITHUB_TOKEN`, `GH_TOKEN` | GitHub API, `gh` CLI | -| `gitlab` | `GITLAB_TOKEN`, `GLAB_TOKEN`, `CI_JOB_TOKEN` | GitLab API, `glab` CLI | -| `nvidia` | `NVIDIA_API_KEY` | NVIDIA API Catalog | -| `generic` | User-defined | Any service with custom credentials | -| `outlook` | *(none, no auto-discovery)* | Microsoft Outlook integration | - -:::{tip} -Use the `generic` type for any service not listed above. You define the -environment variable names and values yourself with `--credential`. -::: - -## Supported Inference Protocols - -Inference routing intercepts AI API calls and reroutes them to policy-controlled backends. The following protocols are recognized for interception. - -| Protocol | API Pattern | Method | Path | -|----------|-------------|--------|------| -| `openai_chat_completions` | OpenAI Chat | POST | `/v1/chat/completions` | -| `openai_completions` | OpenAI Completions | POST | `/v1/completions` | -| `anthropic_messages` | Anthropic Messages | POST | `/v1/messages` | - -## Supported Agent Tools - -The following tools are recognized by `nemoclaw sandbox create -- ` for auto-provider discovery: - -| Tool | Provider Type | Notes | -|------|--------------|-------| -| `claude` | `claude` | Auto-discovers Anthropic credentials. | -| `codex` | `codex` | Auto-discovers OpenAI credentials. | -| `opencode` | `opencode` | Auto-discovers OpenCode/OpenRouter credentials. | - -## Network Policy Features - -The network proxy enforces policies at layers 4 and 7. The following table summarizes the available policy capabilities. - -| Feature | Support | -|---------|---------| -| L4 allow/deny (host + port) | Supported | -| Per-binary access control | Supported (glob patterns) | -| Binary integrity (TOFU) | Supported (SHA256) | -| SSRF protection (private IP blocking) | Supported | -| L7 HTTP inspection | Supported (TLS termination) | -| L7 enforcement modes | `enforce`, `audit` | -| L7 access presets | `read-only`, `read-write`, `full` | -| Inference interception | Supported | - -## Container Image Compatibility (BYOC) - -Bring Your Own Container lets you run custom images as sandboxes. Image compatibility depends on the libraries and tools available in the image. - -| Image Type | Supported | Notes | -|------------|-----------|-------| -| Standard Linux images | Yes | Must have glibc and `/proc`. | -| Alpine / musl-based | Yes | Requires `iproute2` for proxy mode. | -| Distroless / `FROM scratch` | No | Supervisor needs glibc, `/proc`, and a shell. | -| Images without `iproute2` | Partial | Works in Block mode; fails in Proxy mode. | - -## Database Backends - -The gateway server stores cluster state in a database. SQLite is the default and requires no configuration. - -| Backend | Support | -|---------|---------| -| SQLite | Default. No configuration needed. | -| PostgreSQL | Supported as an alternative. | diff --git a/docs/resources/eula.md b/docs/resources/eula.md new file mode 100644 index 00000000..a1d6f1b9 --- /dev/null +++ b/docs/resources/eula.md @@ -0,0 +1,6 @@ + + +# License diff --git a/docs/resources/index.md b/docs/resources/index.md deleted file mode 100644 index bc4a3bf0..00000000 --- a/docs/resources/index.md +++ /dev/null @@ -1,39 +0,0 @@ - - -# About Resources - -## Links - -- [NemoClaw on GitHub](https://github.com/NVIDIA/NemoClaw): Source code, issues, and pull requests. -- [Contributing Guide](https://github.com/NVIDIA/NemoClaw/blob/main/CONTRIBUTING.md): How to build from source and contribute. - -## Related Technologies - -| Technology | How NemoClaw Uses It | -|------------|---------------------| -| [k3s](https://k3s.io/) | Lightweight Kubernetes distribution used for the cluster runtime. | -| [OPA / Rego](https://www.openpolicyagent.org/) | Policy language for sandbox network access control. NemoClaw uses the `regorus` pure-Rust evaluator. | -| [Landlock](https://landlock.io/) | Linux security module for filesystem access control. | -| [seccomp](https://www.kernel.org/doc/html/latest/userspace-api/seccomp_filter.html) | Linux kernel system call filtering. | -| [ratatui](https://ratatui.rs/) | Rust TUI framework powering the NemoClaw Terminal dashboard. | -| [russh](https://github.com/warp-tech/russh) | Rust SSH library used for the sandbox embedded SSH server. | -| [Helm](https://helm.sh/) | Kubernetes package manager used for deploying NemoClaw components. | - -## Glossary - -| Term | Definition | -|------|-----------| -| **Sandbox** | An isolated execution environment for an AI agent, enforcing filesystem, network, and syscall restrictions. | -| **Supervisor** | The privileged process inside a sandbox that manages isolation and spawns the agent. | -| **Provider** | A credential store for external services (API keys, tokens). Injected as environment variables at runtime. | -| **Policy** | A YAML document defining what a sandbox can access (filesystem, network, inference). | -| **Gateway** | The central control plane service that manages sandboxes, providers, and routes. | -| **Inference Route** | A mapping from a routing hint to a backend AI model endpoint. | -| **BYOC** | Bring Your Own Container: running custom images as sandboxes. | -| **NemoClaw Terminal** | The NemoClaw terminal user interface (TUI), launched with `nemoclaw term`. | -| **L7 Inspection** | HTTP-level traffic inspection inside TLS tunnels. | -| **TOFU** | Trust-On-First-Use: the binary integrity verification model used by the proxy. | -| **mTLS** | Mutual TLS: both client and server present certificates. Used for all gateway communication. | diff --git a/docs/safety-and-privacy/index.md b/docs/safety-and-privacy/index.md index 3aaf8461..c3ad0991 100644 --- a/docs/safety-and-privacy/index.md +++ b/docs/safety-and-privacy/index.md @@ -3,7 +3,7 @@ SPDX-License-Identifier: Apache-2.0 --> -# About Safety and Privacy +# Safety and Privacy NemoClaw wraps every sandbox in four independent protection layers. No single point of failure can compromise your environment. Each layer covers gaps the @@ -41,10 +41,10 @@ You control all four layers through a single YAML policy. Network and inference rules are hot-reloadable on a running sandbox. Filesystem and process restrictions are locked at creation time. -- **{doc}`security-model`**: Threat scenarios (data exfiltration, credential +- {doc}`security-model`: Threat scenarios (data exfiltration, credential theft, unauthorized API calls, privilege escalation) and how NemoClaw addresses each one. -- **{doc}`policies`**: Author policies, monitor for blocked actions, and +- {doc}`policies`: Author policies, monitor for blocked actions, and iterate on rules without restarting sandboxes. -- **{doc}`network-access-rules`**: Configure endpoint rules, binary matching, +- {doc}`network-access-rules`: Configure endpoint rules, binary matching, L7 inspection, and access presets. diff --git a/docs/safety-and-privacy/network-access-rules.md b/docs/safety-and-privacy/network-access-rules.md index 615ba719..0987988a 100644 --- a/docs/safety-and-privacy/network-access-rules.md +++ b/docs/safety-and-privacy/network-access-rules.md @@ -16,16 +16,16 @@ Each outbound connection resolves to one of three outcomes: | Outcome | When it applies | What happens | |------------------------|-----------------------------------------------------------------------------|-----------------------------------------------------------------------------| -| **Allow** | A `network_policies` entry matches the destination host *and* the calling binary. | Traffic flows directly to the destination. The agent's own API key is used. | -| **InspectForInference**| No network policy matches, but `inference.allowed_routes` is configured. | The proxy intercepts the connection and hands it to the privacy router, which reroutes it to a configured backend. The route's API key is used. | -| **Deny** | No network policy matches and no inference route applies. | The connection is blocked. The calling process receives a 403 or connection reset. | +| Allow | A `network_policies` entry matches the destination host *and* the calling binary. | Traffic flows directly to the destination. The agent's own API key is used. | +| InspectForInference| No network policy matches, but `inference.allowed_routes` is configured. | The proxy intercepts the connection and hands it to the privacy router, which reroutes it to a configured backend. The route's API key is used. | +| Deny | No network policy matches and no inference route applies. | The connection is blocked. The calling process receives a 403 or connection reset. | :::{note} This is the most important distinction in NemoClaw's network model. -**Agent traffic** is the coding agent (Claude, opencode, Codex) calling its own API to get completions. This traffic matches a `network_policies` entry because the policy declares both the endpoint (for example, `api.anthropic.com:443`) and the binary (for example, `/usr/local/bin/claude`). The proxy allows it through directly. The agent's own API key (injected by the provider) is used as-is. +Agent traffic is the coding agent (Claude, opencode, Codex) calling its own API to get completions. This traffic matches a `network_policies` entry because the policy declares both the endpoint (for example, `api.anthropic.com:443`) and the binary (for example, `/usr/local/bin/claude`). The proxy allows it through directly. The agent's own API key (injected by the provider) is used as-is. -**Userland traffic** is code that the agent *writes* making inference calls. A Python script calling the OpenAI-compatible API, a data pipeline hitting an LLM endpoint, a test harness querying a model. This traffic does *not* match any network policy because the calling binary (`/usr/bin/python3`) is not listed in the agent's policy entry. The proxy intercepts it, the privacy router reroutes it to a configured backend, and the route's API key is substituted in. The agent's code never touches your real API key. +Userland traffic is code that the agent *writes* making inference calls. A Python script calling the OpenAI-compatible API, a data pipeline hitting an LLM endpoint, a test harness querying a model. This traffic does *not* match any network policy because the calling binary (`/usr/bin/python3`) is not listed in the agent's policy entry. The proxy intercepts it, the privacy router reroutes it to a configured backend, and the route's API key is substituted in. The agent's code never touches your real API key. ::: ```{mermaid} diff --git a/docs/safety-and-privacy/policies.md b/docs/safety-and-privacy/policies.md index b79e6d72..3b94dd0f 100644 --- a/docs/safety-and-privacy/policies.md +++ b/docs/safety-and-privacy/policies.md @@ -92,7 +92,7 @@ $ nemoclaw sandbox create --policy ./my-policy.yaml --keep -- claude The `--keep` flag keeps the sandbox running after the initial command exits, which is useful when you plan to iterate on the policy. -To avoid passing `--policy` every time, set a default policy by using environment variable: +To avoid passing `--policy` every time, set a default policy with an environment variable: ```console $ export NEMOCLAW_SANDBOX_POLICY=./my-policy.yaml @@ -231,10 +231,10 @@ Refer to the [Policy Schema Reference](../reference/policy-schema.md) for the co ## Safety Properties -**Last-known-good.** +Last-known-good. If a new policy revision fails validation, the previous successfully loaded policy stays active. A bad push does not break a running sandbox. The agent continues operating under the last good policy. -**Idempotent.** +Idempotent. Submitting the same policy content again does not create a new revision. The CLI detects that the content has not changed and returns without modifying the revision history. ## Next Steps diff --git a/docs/sandboxes/community-sandboxes.md b/docs/sandboxes/community-sandboxes.md index d4779271..a907ea87 100644 --- a/docs/sandboxes/community-sandboxes.md +++ b/docs/sandboxes/community-sandboxes.md @@ -49,14 +49,14 @@ preconfigured by the community package. The `--from` flag also accepts: -- **Local directory paths**: Point to a directory on disk that contains a +- Local directory paths: Point to a directory on disk that contains a Dockerfile and optional policy/skills: ```console $ nemoclaw sandbox create --from ./my-sandbox-dir ``` -- **Container image references**: Use an existing container image directly: +- Container image references: Use an existing container image directly: ```console $ nemoclaw sandbox create --from my-registry.example.com/my-image:latest diff --git a/docs/sandboxes/create-and-manage.md b/docs/sandboxes/create-and-manage.md index 28a84f62..1e88feb2 100644 --- a/docs/sandboxes/create-and-manage.md +++ b/docs/sandboxes/create-and-manage.md @@ -5,6 +5,8 @@ # Create and Manage Sandboxes +A NemoClaw sandbox is a safe, private execution environment for an AI agent. Each sandbox runs inside a Kubernetes pod with multiple layers of protection that prevent unauthorized data access, credential exposure, and network exfiltration. Protection layers include filesystem restrictions (Landlock), system call filtering (seccomp), network namespace isolation, and a privacy-enforcing HTTP CONNECT proxy. + This page walks you through the full sandbox lifecycle: creating, inspecting, connecting to, monitoring, and deleting sandboxes. ## Sandbox Lifecycle @@ -13,10 +15,10 @@ Every sandbox moves through a defined set of phases: | Phase | Description | |---|---| -| **Provisioning** | The runtime is setting up the sandbox environment, injecting credentials, and applying your policy. | -| **Ready** | The sandbox is running. The agent process is active and all isolation layers are enforced. You can connect, sync files, and view logs. | -| **Error** | Something went wrong during provisioning or execution. Check logs with `nemoclaw sandbox logs` for details. | -| **Deleting** | The sandbox is being torn down. The system releases resources and purges credentials. | +| Provisioning | The runtime is setting up the sandbox environment, injecting credentials, and applying your policy. | +| Ready | The sandbox is running. The agent process is active and all isolation layers are enforced. You can connect, sync files, and view logs. | +| Error | Something went wrong during provisioning or execution. Check logs with `nemoclaw sandbox logs` for details. | +| Deleting | The sandbox is being torn down. The system releases resources and purges credentials. | ## The NemoClaw Runtime @@ -24,7 +26,7 @@ Sandboxes run inside a lightweight runtime cluster that NemoClaw manages for you. The cluster runs as a [k3s](https://k3s.io/) Kubernetes distribution inside a Docker container on your machine. -**You do not need to set this up manually.** The first time you run a command +You do not need to set this up manually. The first time you run a command that needs a cluster (such as `nemoclaw sandbox create`), the CLI provisions one automatically. This is the "Runtime ready" line you see in the output. Subsequent commands reuse the existing cluster. @@ -117,7 +119,7 @@ Export the sandbox SSH configuration and append it to your SSH config: $ nemoclaw sandbox ssh-config my-sandbox >> ~/.ssh/config ``` -Then open VS Code, install the **Remote - SSH** extension if you have not +Then open VS Code, install the Remote - SSH extension if you have not already, and connect to the host named `my-sandbox`. ## View Logs diff --git a/docs/sandboxes/index.md b/docs/sandboxes/index.md deleted file mode 100644 index a04ce8a1..00000000 --- a/docs/sandboxes/index.md +++ /dev/null @@ -1,67 +0,0 @@ - - -# About Sandboxes - -A sandbox is a safe, private execution environment for an AI agent. Each sandbox runs inside a Kubernetes pod with multiple layers of protection that prevent unauthorized data access, credential exposure, and network exfiltration. Protection layers include filesystem restrictions (Landlock), system call filtering (seccomp), network namespace isolation, and a privacy-enforcing HTTP CONNECT proxy. - -## Concepts - -The following concepts are fundamental to how sandboxes operate. - -### Lifecycle - -A sandbox goes through these phases: - -| Phase | Description | -|-------|-------------| -| **Provisioning** | The pod is being created and the supervisor is starting up. | -| **Ready** | The sandbox is running and accessible via SSH. | -| **Error** | Something went wrong during startup or execution. | -| **Deleting** | The sandbox is being torn down. | - -### Supervisor and Child Process - -Each sandbox runs two processes: - -- The **supervisor** (`navigator-sandbox`) is a privileged process that sets up isolation, starts the proxy, runs the SSH server, and manages the child process. -- The **child process** is the agent (for example, Claude, Codex) running with restricted privileges: reduced filesystem access, filtered system calls, and all network traffic routed through the proxy. - -### Policy - -A policy governs every sandbox, defining what the agent can do and ensuring your data and credentials stay safe. Policies are written in YAML and control: - -- **Filesystem access**: Which directories are readable and writable, protecting sensitive data. -- **Network access**: Which hosts each program can connect to, preventing data exfiltration. -- **Inference routing**: Which AI model backends are available, keeping inference traffic private. -- **Process privileges**: The user and group the agent runs as, limiting blast radius. - -Refer to [Safety & Privacy](../safety-and-privacy/index.md) for details. - -## Quick Reference - -Common sandbox operations and their CLI commands. - -| Task | Command | -|------|---------| -| Create sandbox (interactive) | `nemoclaw sandbox create` | -| Create sandbox with tool | `nemoclaw sandbox create -- claude` | -| Create with custom policy | `nemoclaw sandbox create --policy ./p.yaml --keep` | -| List sandboxes | `nemoclaw sandbox list` | -| Connect to sandbox | `nemoclaw sandbox connect ` | -| Stream live logs | `nemoclaw sandbox logs --tail` | -| Sync files to sandbox | `nemoclaw sandbox sync --up ./src /sandbox/src` | -| Forward a port | `nemoclaw sandbox forward start -d` | -| Delete sandbox | `nemoclaw sandbox delete ` | - -## In This Section - -Guides for each aspect of sandbox management. - -- [Create and Manage](create-and-manage.md): About creating, listing, inspecting, and connecting to sandboxes. -- [Providers](providers.md): About managing external credentials privately. -- [Custom Containers](custom-containers.md): About bringing your own container images. -- [Community Sandboxes](community-sandboxes.md): About using pre-built sandboxes from the NemoClaw Community catalog. -- [Terminal](terminal.md): About using NemoClaw Terminal to monitor sandbox activity and diagnose blocked connections. diff --git a/docs/sandboxes/providers.md b/docs/sandboxes/providers.md index 383d664c..7461447d 100644 --- a/docs/sandboxes/providers.md +++ b/docs/sandboxes/providers.md @@ -114,14 +114,14 @@ flowchart LR D --> E["Credentials injected into\nagent process + SSH sessions"] ``` -1. **You create a provider** with credentials from your environment or +1. You create a provider with credentials from your environment or specified explicitly. -2. **You attach the provider to a sandbox** at creation time using the +2. You attach the provider to a sandbox at creation time using the `--provider` flag (one or more providers can be attached). -3. **The sandbox starts.** The supervisor process initializes. -4. **The supervisor fetches credentials** from the NemoClaw gateway at runtime. +3. The sandbox starts. The supervisor process initializes. +4. The supervisor fetches credentials from the NemoClaw gateway at runtime. The system does not store credentials in the sandbox specification. It retrieves them on demand. -5. **Credentials are injected** into the agent process as environment variables. +5. Credentials are injected into the agent process as environment variables. They are also available in SSH sessions when you connect to the sandbox. :::{warning} @@ -132,7 +132,23 @@ environment dumps of the container spec. ## Supported Provider Types -For a list of supported provider types, refer to the [Support Matrix](../reference/support-matrix.md#supported-provider-types). +The following provider types are supported. + +| Type | Environment Variables Injected | Typical Use | +|---|---|---| +| `claude` | `ANTHROPIC_API_KEY`, `CLAUDE_API_KEY` | Claude Code, Anthropic API | +| `codex` | `OPENAI_API_KEY` | OpenAI Codex | +| `opencode` | `OPENCODE_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY` | opencode tool | +| `github` | `GITHUB_TOKEN`, `GH_TOKEN` | GitHub API, `gh` CLI | +| `gitlab` | `GITLAB_TOKEN`, `GLAB_TOKEN`, `CI_JOB_TOKEN` | GitLab API, `glab` CLI | +| `nvidia` | `NVIDIA_API_KEY` | NVIDIA API Catalog | +| `generic` | User-defined | Any service with custom credentials | +| `outlook` | *(none: no auto-discovery)* | Microsoft Outlook integration | + +:::{tip} +Use the `generic` type for any service not listed above. You define the +environment variable names and values yourself with `--credential`. +::: ## Next Steps diff --git a/docs/sandboxes/terminal.md b/docs/sandboxes/terminal.md index 997afe96..43888e76 100644 --- a/docs/sandboxes/terminal.md +++ b/docs/sandboxes/terminal.md @@ -15,11 +15,11 @@ $ nemoclaw term The status pane at the top of the dashboard displays the following sandbox metadata: -- **Name** and **phase** (`Provisioning`, `Ready`, `Error`) -- **Image** running in the sandbox -- **Providers** attached and their available credentials -- **Age** since creation -- **Port forwards** currently active +- Name and phase (`Provisioning`, `Ready`, `Error`) +- Image running in the sandbox +- Providers attached and their available credentials +- Age since creation +- Port forwards currently active A phase other than `Ready` indicates the sandbox is still initializing or has encountered an error. Inspect the logs pane for details. @@ -29,8 +29,8 @@ The logs pane streams activity in real time. Outbound connections, policy decisi Log entries originate from two sources: -- **sandbox**: The sandbox supervisor (proxy decisions, policy enforcement, SSH connections, process lifecycle). -- **gateway**: The control plane (sandbox creation, phase changes, policy distribution). +- sandbox: The sandbox supervisor (proxy decisions, policy enforcement, SSH connections, process lifecycle). +- gateway: The control plane (sandbox creation, phase changes, policy distribution). Press `f` to enable follow mode and auto-scroll to new entries. @@ -82,10 +82,10 @@ Check the log entry for the binary path, then update the `binaries` list in the The dashboard provides filtering and navigation controls: -- Press **`s`** to filter logs by source. Display only `sandbox` logs (policy decisions) or only `gateway` logs (lifecycle events). -- Press **`f`** to toggle follow mode. Auto-scroll to the latest entries. -- Press **`Enter`** on a log entry to open the detail view with the full message. -- Use **`j`** / **`k`** to navigate up and down the log list. +- Press `s` to filter logs by source. Display only `sandbox` logs (policy decisions) or only `gateway` logs (lifecycle events). +- Press `f` to toggle follow mode. Auto-scroll to the latest entries. +- Press `Enter` on a log entry to open the detail view with the full message. +- Use `j` / `k` to navigate up and down the log list. ## Keyboard Shortcuts @@ -105,6 +105,6 @@ The following keyboard shortcuts are available in the terminal dashboard. For deeper dives into topics covered by the terminal dashboard, refer to the following guides. -- **Blocked connections**: Follow {doc}`../safety-and-privacy/policies` to pull the current policy, add the missing endpoint, and push an update without restarting the sandbox. -- **Inference interception**: Refer to {doc}`../safety-and-privacy/network-access-rules` for the distinction between agent traffic (routed directly) and userland traffic (routed through inference routing). -- **General troubleshooting**: Refer to {doc}`../troubleshooting/cluster-issues` for common issues and diagnostics. +- Blocked connections: Follow {doc}`../safety-and-privacy/policies` to pull the current policy, add the missing endpoint, and push an update without restarting the sandbox. +- Inference interception: Refer to {doc}`../safety-and-privacy/network-access-rules` for the distinction between agent traffic (routed directly) and userland traffic (routed through inference routing). +- Troubleshooting: Refer to {doc}`../troubleshooting` for troubleshooting tips and diagnostics. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md new file mode 100644 index 00000000..ed1b0783 --- /dev/null +++ b/docs/troubleshooting.md @@ -0,0 +1,135 @@ + + +# Troubleshooting + +Use this guide to troubleshoot problems with NemoClaw. + +## Cluster Issues + +Troubleshoot problems with deploying, connecting to, and running NemoClaw clusters. + +### Cluster Deploy Fails + +**Symptom:** `nemoclaw cluster admin deploy` exits with an error. + +**Check:** +1. Is Docker running? The cluster requires Docker to be active. +2. Is the port already in use? Try a different port: `--port 8081`. +3. Does a stale container exist? Destroy and redeploy: `nemoclaw cluster admin destroy && nemoclaw cluster admin deploy`. + +### Cluster Not Reachable + +**Symptom:** `nemoclaw cluster status` fails to connect. + +**Check:** +1. Is the cluster container running? `docker ps | grep nemoclaw`. +2. Was the cluster stopped? Redeploy: `nemoclaw cluster admin deploy`. +3. For remote clusters, is the SSH connection working? + +### Health Check Fails During Deploy + +**Symptom:** Deploy hangs or times out waiting for health checks. + +**Check:** +1. View container logs: `docker logs nemoclaw-cluster`. +2. Check if k3s started: the bootstrap process waits up to 180 attempts (six minutes) for cluster readiness. +3. Look for resource constraints. k3s needs sufficient memory and disk. + +## Sandbox Issues + +Troubleshoot problems with creating, connecting to, and configuring sandboxes. + +### Sandbox Stuck in Provisioning + +**Symptom:** Sandbox shows `Provisioning` status and does not become `Ready`. + +**Check:** +1. View sandbox logs: `nemoclaw sandbox logs --source gateway`. +2. Check if the container image can be pulled. +3. For custom images, verify the image was pushed: `nemoclaw sandbox image push`. + +### Cannot Connect to Sandbox + +**Symptom:** `nemoclaw sandbox connect ` fails. + +**Check:** +1. Is the sandbox in `Ready` state? `nemoclaw sandbox get `. +2. Is SSH accessible? The tunnel goes through the gateway. Verify cluster connectivity first. + +### Network Requests Denied + +**Symptom:** The agent cannot reach a remote host. + +**Check:** +1. Stream sandbox logs: `nemoclaw sandbox logs --tail --source sandbox`. +2. Look for `deny` actions. They include the destination, binary, and reason. +3. Update the policy to allow the blocked endpoint. Refer to [Policy Iteration Loop](safety-and-privacy/policies.md#the-policy-iteration-loop). + +### Policy Update Fails + +**Symptom:** `nemoclaw sandbox policy set` returns an error or the status shows `failed`. + +**Check:** +1. Are you changing a static field? `filesystem_policy`, `landlock`, and `process` cannot change after creation. +2. Are you adding/removing `network_policies` to change the network mode? This is not allowed. The mode is fixed at creation. +3. Check the error message in `nemoclaw sandbox policy list `. + +## Provider Issues + +Troubleshoot problems with provider credential discovery and injection into sandboxes. + +### Provider Discovery Finds No Credentials + +**Symptom:** `--from-existing` creates a provider with no credentials. + +**Check:** +1. Are the expected environment variables set? (for example, `ANTHROPIC_API_KEY` for Claude). +2. Do the expected config files exist? (for example, `~/.claude.json`). +3. Try explicit credentials: `--credential ANTHROPIC_API_KEY=sk-...`. + +### Sandbox Missing Credentials + +**Symptom:** Environment variables for a provider are not set inside the sandbox. + +**Check:** +1. Was the provider attached? `nemoclaw sandbox get `. Check the providers list. +2. Does the provider have credentials? `nemoclaw provider get `. +3. Are the credential keys valid env var names? Keys with dots, dashes, or spaces are silently skipped. + +## Custom Container Issues + +Troubleshoot problems with building and running custom container images in sandboxes. + +### Custom Image Fails to Start + +**Symptom:** Sandbox with `--from ` goes to `Error` state. + +**Check:** +1. Is the image pushed to the cluster? `nemoclaw sandbox image push --dockerfile ./Dockerfile --tag my-image`. +2. Does the image have glibc and `/proc`? Distroless / `FROM scratch` images are not supported. +3. For proxy mode, does the image have `iproute2`? Network namespace setup requires it. + +## Port Forwarding Issues + +Troubleshoot problems with forwarding local ports into sandbox services. + +### Port Forward Not Working + +**Symptom:** `localhost:` does not connect to the sandbox service. + +**Check:** +1. Is the forward running? `nemoclaw sandbox forward list`. +2. Is the service listening on that port inside the sandbox? +3. Is the sandbox still in `Ready` state? +4. Try stopping and restarting: `nemoclaw sandbox forward stop && nemoclaw sandbox forward start -d`. + +## Getting More Information + +Use these techniques to gather additional diagnostic detail when troubleshooting. + +- Increase CLI verbosity: `nemoclaw -vvv ` for trace-level output. +- View gateway-side logs: `nemoclaw sandbox logs --source gateway`. +- View sandbox-side logs: `nemoclaw sandbox logs --source sandbox --level debug`. diff --git a/docs/troubleshooting/cluster-issues.md b/docs/troubleshooting/cluster-issues.md deleted file mode 100644 index 0f8da09b..00000000 --- a/docs/troubleshooting/cluster-issues.md +++ /dev/null @@ -1,35 +0,0 @@ - - -# Cluster Issues - -Troubleshoot problems with deploying, connecting to, and running NemoClaw clusters. - -## Cluster Deploy Fails - -**Symptom:** `nemoclaw cluster admin deploy` exits with an error. - -**Check:** -1. Is Docker running? The cluster requires Docker to be active. -2. Is the port already in use? Try a different port: `--port 8081`. -3. Does a stale container exist? Destroy and redeploy: `nemoclaw cluster admin destroy && nemoclaw cluster admin deploy`. - -## Cluster Not Reachable - -**Symptom:** `nemoclaw cluster status` fails to connect. - -**Check:** -1. Is the cluster container running? `docker ps | grep nemoclaw`. -2. Was the cluster stopped? Redeploy: `nemoclaw cluster admin deploy`. -3. For remote clusters, is the SSH connection working? - -## Health Check Fails During Deploy - -**Symptom:** Deploy hangs or times out waiting for health checks. - -**Check:** -1. View container logs: `docker logs nemoclaw-cluster`. -2. Check if k3s started: the bootstrap process waits up to 180 attempts (six minutes) for cluster readiness. -3. Look for resource constraints. k3s needs sufficient memory and disk. diff --git a/docs/troubleshooting/custom-container-issues.md b/docs/troubleshooting/custom-container-issues.md deleted file mode 100644 index 3dd42b25..00000000 --- a/docs/troubleshooting/custom-container-issues.md +++ /dev/null @@ -1,17 +0,0 @@ - - -# Custom Container Issues - -Troubleshoot problems with building and running custom container images in sandboxes. - -## Custom Image Fails to Start - -**Symptom:** Sandbox with `--from ` goes to `Error` state. - -**Check:** -1. Is the image pushed to the cluster? `nemoclaw sandbox image push --dockerfile ./Dockerfile --tag my-image`. -2. Does the image have glibc and `/proc`? Distroless / `FROM scratch` images are not supported. -3. For proxy mode, does the image have `iproute2`? Network namespace setup requires it. diff --git a/docs/troubleshooting/getting-more-information.md b/docs/troubleshooting/getting-more-information.md deleted file mode 100644 index 6075390e..00000000 --- a/docs/troubleshooting/getting-more-information.md +++ /dev/null @@ -1,12 +0,0 @@ - - -# Getting More Information - -Use these techniques to gather additional diagnostic detail when troubleshooting. - -- Increase CLI verbosity: `nemoclaw -vvv ` for trace-level output. -- View gateway-side logs: `nemoclaw sandbox logs --source gateway`. -- View sandbox-side logs: `nemoclaw sandbox logs --source sandbox --level debug`. diff --git a/docs/troubleshooting/port-forwarding-issues.md b/docs/troubleshooting/port-forwarding-issues.md deleted file mode 100644 index 96efc8d2..00000000 --- a/docs/troubleshooting/port-forwarding-issues.md +++ /dev/null @@ -1,18 +0,0 @@ - - -# Port Forwarding Issues - -Troubleshoot problems with forwarding local ports into sandbox services. - -## Port Forward Not Working - -**Symptom:** `localhost:` does not connect to the sandbox service. - -**Check:** -1. Is the forward running? `nemoclaw sandbox forward list`. -2. Is the service listening on that port inside the sandbox? -3. Is the sandbox still in `Ready` state? -4. Try stopping and restarting: `nemoclaw sandbox forward stop && nemoclaw sandbox forward start -d`. diff --git a/docs/troubleshooting/provider-issues.md b/docs/troubleshooting/provider-issues.md deleted file mode 100644 index 99c62dfc..00000000 --- a/docs/troubleshooting/provider-issues.md +++ /dev/null @@ -1,26 +0,0 @@ - - -# Provider Issues - -Troubleshoot problems with provider credential discovery and injection into sandboxes. - -## Provider Discovery Finds No Credentials - -**Symptom:** `--from-existing` creates a provider with no credentials. - -**Check:** -1. Are the expected environment variables set? (for example, `ANTHROPIC_API_KEY` for Claude). -2. Do the expected config files exist? (for example, `~/.claude.json`). -3. Try explicit credentials: `--credential ANTHROPIC_API_KEY=sk-...`. - -## Sandbox Missing Credentials - -**Symptom:** Environment variables for a provider are not set inside the sandbox. - -**Check:** -1. Was the provider attached? `nemoclaw sandbox get `. Check the providers list. -2. Does the provider have credentials? `nemoclaw provider get `. -3. Are the credential keys valid env var names? Keys with dots, dashes, or spaces are silently skipped. diff --git a/docs/troubleshooting/sandbox-issues.md b/docs/troubleshooting/sandbox-issues.md deleted file mode 100644 index e079fc92..00000000 --- a/docs/troubleshooting/sandbox-issues.md +++ /dev/null @@ -1,43 +0,0 @@ - - -# Sandbox Issues - -Troubleshoot problems with creating, connecting to, and configuring sandboxes. - -## Sandbox Stuck in Provisioning - -**Symptom:** Sandbox shows `Provisioning` status and does not become `Ready`. - -**Check:** -1. View sandbox logs: `nemoclaw sandbox logs --source gateway`. -2. Check if the container image can be pulled. -3. For custom images, verify the image was pushed: `nemoclaw sandbox image push`. - -## Cannot Connect to Sandbox - -**Symptom:** `nemoclaw sandbox connect ` fails. - -**Check:** -1. Is the sandbox in `Ready` state? `nemoclaw sandbox get `. -2. Is SSH accessible? The tunnel goes through the gateway. Verify cluster connectivity first. - -## Network Requests Denied - -**Symptom:** The agent cannot reach a remote host. - -**Check:** -1. Stream sandbox logs: `nemoclaw sandbox logs --tail --source sandbox`. -2. Look for `deny` actions. They include the destination, binary, and reason. -3. Update the policy to allow the blocked endpoint. Refer to [Policy Iteration Loop](../safety-and-privacy/policies.md#the-policy-iteration-loop). - -## Policy Update Fails - -**Symptom:** `nemoclaw sandbox policy set` returns an error or the status shows `failed`. - -**Check:** -1. Are you changing a static field? `filesystem_policy`, `landlock`, and `process` cannot change after creation. -2. Are you adding/removing `network_policies` to change the network mode? This is not allowed. The mode is fixed at creation. -3. Check the error message in `nemoclaw sandbox policy list `. diff --git a/docs/get-started/tutorials/run-claude.md b/docs/tutorials/run-claude.md similarity index 73% rename from docs/get-started/tutorials/run-claude.md rename to docs/tutorials/run-claude.md index 97a9938b..9b0a1d8c 100644 --- a/docs/get-started/tutorials/run-claude.md +++ b/docs/tutorials/run-claude.md @@ -7,7 +7,7 @@ This tutorial walks you through the simplest path to running Claude Code inside a NemoClaw sandbox. By the end, you will have an isolated environment with Claude Code running, your credentials securely injected, and a default policy controlling what the agent can access. -**What you will learn:** +What you will learn: - Creating a sandbox with a single command - How NemoClaw auto-discovers provider credentials @@ -24,10 +24,10 @@ $ nemoclaw sandbox create -- claude This single command does several things: -1. **Bootstraps the runtime.** If this is your first time using NemoClaw, the CLI provisions a local k3s cluster inside Docker and deploys the NemoClaw control plane. This happens once---subsequent commands reuse the existing cluster. -2. **Auto-discovers credentials.** The CLI detects that `claude` is a recognized tool and looks for your Anthropic credentials. It reads the `ANTHROPIC_API_KEY` environment variable and creates a provider automatically. -3. **Creates the sandbox.** The CLI provisions an isolated environment and applies the default policy. The policy allows Claude Code to reach `api.anthropic.com` and a small set of supporting endpoints while blocking everything else. -4. **Drops you into the sandbox.** You land in an interactive SSH session inside the sandbox, ready to work. +1. Bootstraps the runtime. If this is your first time using NemoClaw, the CLI provisions a local k3s cluster inside Docker and deploys the NemoClaw control plane. This happens once. Subsequent commands reuse the existing cluster. +2. Auto-discovers credentials. The CLI detects that `claude` is a recognized tool and looks for your Anthropic credentials. It reads the `ANTHROPIC_API_KEY` environment variable and creates a provider automatically. +3. Creates the sandbox. The CLI provisions an isolated environment and applies the default policy. The policy allows Claude Code to reach `api.anthropic.com` and a small set of supporting endpoints while blocking everything else. +4. Drops you into the sandbox. You land in an interactive SSH session inside the sandbox, ready to work. :::{note} The first bootstrap takes a few minutes depending on your network speed. The CLI prints progress as each component starts. Subsequent sandbox creations are much faster. @@ -48,7 +48,7 @@ $ echo $ANTHROPIC_API_KEY sk-ant-... ``` -The sandbox has a working directory at `/sandbox` where you can create and edit files. Claude Code has access to standard development tools---git, common language runtimes, and package managers---within the boundaries set by the policy. +The sandbox has a working directory at `/sandbox` where you can create and edit files. Claude Code has access to standard development tools (git, common language runtimes, and package managers) within the boundaries set by the policy. ## Step 3: Check Sandbox Status @@ -78,7 +78,7 @@ First, export the sandbox's SSH configuration: $ nemoclaw sandbox ssh-config my-sandbox >> ~/.ssh/config ``` -Then open VS Code, install the **Remote - SSH** extension if you have not already, and connect to the host named `my-sandbox`. VS Code opens a full editor session inside the sandbox. +Then open VS Code, install the Remote - SSH extension if you have not already, and connect to the host named `my-sandbox`. VS Code opens a full editor session inside the sandbox. :::{tip} Replace `my-sandbox` with the actual name of your sandbox. Run `nemoclaw sandbox list` to find it if you did not specify a name at creation time. diff --git a/docs/get-started/tutorials/run-openclaw.md b/docs/tutorials/run-openclaw.md similarity index 71% rename from docs/get-started/tutorials/run-openclaw.md rename to docs/tutorials/run-openclaw.md index d9a7d240..4a06f05d 100644 --- a/docs/get-started/tutorials/run-openclaw.md +++ b/docs/tutorials/run-openclaw.md @@ -7,7 +7,7 @@ This tutorial shows you how to launch a community sandbox using the `--from` flag. Community sandboxes are pre-built configurations published to the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) repository. They bundle a container image, a tailored policy, and optional skills into a single package you can run with one command. -**What you will learn:** +What you will learn: - What community sandboxes are and how they differ from default sandboxes - How the `--from` flag pulls and builds a complete sandbox configuration @@ -17,9 +17,9 @@ This tutorial shows you how to launch a community sandbox using the `--from` fla Before you begin, make sure you have: -- **Docker** running on your machine. -- **NVIDIA GPU with drivers** installed. Required for GPU-accelerated workloads in the OpenClaw sandbox. -- [**NemoClaw CLI** installed](../../index.md#install-the-nemoclaw-cli) +- Docker running on your machine. +- NVIDIA GPU with drivers installed. Required for GPU-accelerated workloads in the OpenClaw sandbox. +- [NemoClaw CLI installed](../index.md#install-the-nemoclaw-cli) ## Step 1: Create a Sandbox from the Community Image @@ -31,10 +31,10 @@ $ nemoclaw sandbox create --from openclaw --keep The `--from` flag tells the CLI to pull a sandbox definition from the NemoClaw Community catalog. Here is what happens: -1. **Fetches the definition.** The CLI downloads the OpenClaw sandbox definition from the NemoClaw-Community repository. This includes a Dockerfile, a policy YAML, and any bundled skills. -2. **Builds the image.** The CLI builds the Dockerfile locally using Docker. The image includes all tools and dependencies that OpenClaw needs. -3. **Applies the bundled policy.** Instead of the generic default policy, the sandbox starts with a policy specifically written for the OpenClaw workload---it allows the endpoints and binaries that OpenClaw requires. -4. **Creates and keeps the sandbox.** The `--keep` flag ensures the sandbox stays running after creation so you can connect and disconnect freely. +1. Fetches the definition. The CLI downloads the OpenClaw sandbox definition from the NemoClaw-Community repository. This includes a Dockerfile, a policy YAML, and any bundled skills. +2. Builds the image. The CLI builds the Dockerfile locally using Docker. The image includes all tools and dependencies that OpenClaw needs. +3. Applies the bundled policy. Instead of the generic default policy, the sandbox starts with a policy specifically written for the OpenClaw workload. It allows the endpoints and binaries that OpenClaw requires. +4. Creates and keeps the sandbox. The `--keep` flag ensures the sandbox stays running after creation so you can connect and disconnect freely. :::{note} The first build takes longer because Docker needs to pull base layers and install dependencies. Subsequent creates reuse the cached image. @@ -64,10 +64,10 @@ $ nemoclaw sandbox policy get --full This outputs the complete policy YAML, including: -- **Network policies**---which hosts and ports the sandbox can reach, and which binaries are allowed to initiate those connections -- **Filesystem policy**---which paths are read-only and which are read-write -- **Process restrictions**---the user and group the sandbox runs as -- **Inference rules**---which inference routing hints are allowed +- Network policies: which hosts and ports the sandbox can reach, and which binaries are allowed to initiate those connections +- Filesystem policy: which paths are read-only and which are read-write +- Process restrictions: the user and group the sandbox runs as +- Inference rules: which inference routing hints are allowed Reviewing the bundled policy is a good way to understand what a community sandbox has access to before you start using it for sensitive work. diff --git a/docs/get-started/tutorials/run-opencode.md b/docs/tutorials/run-opencode.md similarity index 82% rename from docs/get-started/tutorials/run-opencode.md rename to docs/tutorials/run-opencode.md index fdaaf42d..2331b1bc 100644 --- a/docs/get-started/tutorials/run-opencode.md +++ b/docs/tutorials/run-opencode.md @@ -19,8 +19,8 @@ This tutorial walks through a realistic setup where you run [opencode](https://o Before you begin: -- **`NVIDIA_API_KEY` environment variable** set on your host machine with a valid NVIDIA API key -- **NemoClaw CLI** installed (`pip install nemoclaw`) +- `NVIDIA_API_KEY` environment variable set on your host machine with a valid NVIDIA API key +- NemoClaw CLI installed (`pip install nemoclaw`) ## Step 1: Create the Provider @@ -76,14 +76,14 @@ These log entries tell you exactly what the policy blocks and why. ## Step 4: Understand Why -The default policy has a `nvidia_inference` network policy entry, but it is configured for a narrow set of binaries---typically `/usr/local/bin/claude` and `/usr/bin/node`. If opencode makes HTTP calls through a different binary (its own binary, `curl`, or a shell subprocess), those connections do not match any policy rule and get denied. +The default policy has a `nvidia_inference` network policy entry, but it is configured for a narrow set of binaries, typically `/usr/local/bin/claude` and `/usr/bin/node`. If opencode makes HTTP calls through a different binary (its own binary, `curl`, or a shell subprocess), those connections do not match any policy rule and get denied. There are two separate problems: -1. **opencode's own traffic.** opencode contacts `opencode.ai` for its API and `integrate.api.nvidia.com` for inference. Neither of these endpoints has a matching policy entry for the binaries opencode uses. -2. **No opencode.ai endpoint.** The default policy has no entry for `opencode.ai` at all. Even if the binary matched, the destination is not listed. +1. OpenCode's own traffic. opencode contacts `opencode.ai` for its API and `integrate.api.nvidia.com` for inference. Neither of these endpoints has a matching policy entry for the binaries opencode uses. +2. No opencode.ai endpoint. The default policy has no entry for `opencode.ai` at all. Even if the binary matched, the destination is not listed. -This is the expected behavior---NemoClaw denies by default. You need to write a policy that explicitly allows what opencode needs. +This is the expected behavior. NemoClaw denies by default. You need to write a policy that explicitly allows what opencode needs. ## Step 5: Write a Custom Policy @@ -184,13 +184,13 @@ network_policies: Compared to the default policy, this adds: -- **`opencode_api`**---allows opencode and Node.js to reach `opencode.ai:443` -- **Broader `nvidia_inference` binaries**---adds `/usr/local/bin/opencode`, `/usr/bin/curl`, and `/bin/bash` so opencode's subprocesses can reach the NVIDIA endpoint -- **`inference.allowed_routes`**---includes `nvidia` so inference routing works for userland code -- **GitHub access** scoped for opencode's git operations +- `opencode_api`: allows opencode and Node.js to reach `opencode.ai:443` +- Broader `nvidia_inference` binaries: adds `/usr/local/bin/opencode`, `/usr/bin/curl`, and `/bin/bash` so opencode's subprocesses can reach the NVIDIA endpoint +- `inference.allowed_routes`: includes `nvidia` so inference routing works for userland code +- GitHub access scoped for opencode's git operations :::{warning} -The `filesystem_policy`, `landlock`, and `process` sections are static---they are set at sandbox creation time and cannot be changed on a running sandbox. If you need to modify these, you must delete and recreate the sandbox. The `network_policies` and `inference` sections are dynamic and can be hot-reloaded. +The `filesystem_policy`, `landlock`, and `process` sections are static. They are set at sandbox creation time and cannot be changed on a running sandbox. If you need to modify these, you must delete and recreate the sandbox. The `network_policies` and `inference` sections are dynamic and can be hot-reloaded. ::: ## Step 6: Push the Policy @@ -213,7 +213,7 @@ The latest revision should show status `loaded`. ## Step 7: Set Up Inference Routing -So far, you have allowed the opencode *agent* to reach `integrate.api.nvidia.com` directly through network policy. But what about code that opencode writes and runs inside the sandbox? If that code calls an LLM API, it goes through the privacy router---a separate mechanism. +So far, you have allowed the opencode *agent* to reach `integrate.api.nvidia.com` directly through network policy. But what about code that opencode writes and runs inside the sandbox? If that code calls an LLM API, it goes through the privacy router: a separate mechanism. Create an inference route so userland code can access NVIDIA models: From 6456efa7ed151e37b818a6f18299c653c71eb010 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Fri, 6 Mar 2026 10:47:25 -0800 Subject: [PATCH 19/39] minor fix --- docs/safety-and-privacy/network-access-rules.md | 4 ++-- docs/safety-and-privacy/policies.md | 6 +++--- docs/sandboxes/providers.md | 2 +- docs/tutorials/run-opencode.md | 14 +++++++------- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/safety-and-privacy/network-access-rules.md b/docs/safety-and-privacy/network-access-rules.md index 0987988a..b31eed93 100644 --- a/docs/safety-and-privacy/network-access-rules.md +++ b/docs/safety-and-privacy/network-access-rules.md @@ -23,9 +23,9 @@ Each outbound connection resolves to one of three outcomes: :::{note} This is the most important distinction in NemoClaw's network model. -Agent traffic is the coding agent (Claude, opencode, Codex) calling its own API to get completions. This traffic matches a `network_policies` entry because the policy declares both the endpoint (for example, `api.anthropic.com:443`) and the binary (for example, `/usr/local/bin/claude`). The proxy allows it through directly. The agent's own API key (injected by the provider) is used as-is. +*Agent traffic* is the coding agent (Claude, OpenCode, Codex) calling its own API to get completions. This traffic matches a `network_policies` entry because the policy declares both the endpoint (for example, `api.anthropic.com:443`) and the binary (for example, `/usr/local/bin/claude`). The proxy allows it through directly. The agent's own API key (injected by the provider) is used as-is. -Userland traffic is code that the agent *writes* making inference calls. A Python script calling the OpenAI-compatible API, a data pipeline hitting an LLM endpoint, a test harness querying a model. This traffic does *not* match any network policy because the calling binary (`/usr/bin/python3`) is not listed in the agent's policy entry. The proxy intercepts it, the privacy router reroutes it to a configured backend, and the route's API key is substituted in. The agent's code never touches your real API key. +*Userland traffic* is code that the agent *writes* making inference calls. A Python script calling the OpenAI-compatible API, a data pipeline hitting an LLM endpoint, a test harness querying a model. This traffic does *not* match any network policy because the calling binary (`/usr/bin/python3`) is not listed in the agent's policy entry. The proxy intercepts it, the privacy router reroutes it to a configured backend, and the route's API key is substituted in. The agent's code never touches your real API key. ::: ```{mermaid} diff --git a/docs/safety-and-privacy/policies.md b/docs/safety-and-privacy/policies.md index 3b94dd0f..cb6307c4 100644 --- a/docs/safety-and-privacy/policies.md +++ b/docs/safety-and-privacy/policies.md @@ -75,7 +75,7 @@ NemoClaw ships a built-in default policy designed for Claude Code. It covers Cla | Agent | Default policy coverage | What you need to do | |---|---|---| | Claude Code | Full | Nothing: works out of the box | -| opencode | Partial | Add `opencode.ai` endpoint and opencode binary paths. | +| OpenCode | Partial | Add `opencode.ai` endpoint and OpenCode binary paths. | | Codex | None | Provide a complete custom policy with OpenAI endpoints and Codex binary paths. | :::{important} @@ -231,10 +231,10 @@ Refer to the [Policy Schema Reference](../reference/policy-schema.md) for the co ## Safety Properties -Last-known-good. +**Last-known-good.** If a new policy revision fails validation, the previous successfully loaded policy stays active. A bad push does not break a running sandbox. The agent continues operating under the last good policy. -Idempotent. +**Idempotent.** Submitting the same policy content again does not create a new revision. The CLI detects that the content has not changed and returns without modifying the revision history. ## Next Steps diff --git a/docs/sandboxes/providers.md b/docs/sandboxes/providers.md index 7461447d..70907b82 100644 --- a/docs/sandboxes/providers.md +++ b/docs/sandboxes/providers.md @@ -138,7 +138,7 @@ The following provider types are supported. |---|---|---| | `claude` | `ANTHROPIC_API_KEY`, `CLAUDE_API_KEY` | Claude Code, Anthropic API | | `codex` | `OPENAI_API_KEY` | OpenAI Codex | -| `opencode` | `OPENCODE_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY` | opencode tool | +| `OpenCode` | `OPENCODE_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY` | opencode tool | | `github` | `GITHUB_TOKEN`, `GH_TOKEN` | GitHub API, `gh` CLI | | `gitlab` | `GITLAB_TOKEN`, `GLAB_TOKEN`, `CI_JOB_TOKEN` | GitLab API, `glab` CLI | | `nvidia` | `NVIDIA_API_KEY` | NVIDIA API Catalog | diff --git a/docs/tutorials/run-opencode.md b/docs/tutorials/run-opencode.md index 2331b1bc..4032c655 100644 --- a/docs/tutorials/run-opencode.md +++ b/docs/tutorials/run-opencode.md @@ -5,7 +5,7 @@ # Run OpenCode with NVIDIA Inference -This tutorial walks through a realistic setup where you run [opencode](https://opencode.ai) inside a NemoClaw sandbox with inference routed to NVIDIA API endpoints. Along the way, you will hit policy problems, diagnose them from logs, write a custom policy, and configure inference routing. This is the full policy iteration loop. +This tutorial walks through a realistic setup where you run [OpenCode](https://opencode.ai) inside a NemoClaw sandbox with inference routed to NVIDIA API endpoints. Along the way, you will hit policy problems, diagnose them from logs, write a custom policy, and configure inference routing. This is the full policy iteration loop. **What you will learn:** @@ -40,17 +40,17 @@ $ nemoclaw provider list ## Step 2: Create the Sandbox -Create a sandbox with the NVIDIA provider attached and opencode as the startup command: +Create a sandbox with the NVIDIA provider attached and OpenCode as the startup command: ```console $ nemoclaw sandbox create --name opencode-sandbox --provider nvidia --keep -- opencode ``` -The `--keep` flag keeps the sandbox alive after you exit, which you will need for the iteration steps ahead. The CLI creates the sandbox with the default policy, injects the NVIDIA credentials, and starts opencode. +The `--keep` flag keeps the sandbox alive after you exit, which you will need for the iteration steps ahead. The CLI creates the sandbox with the default policy, injects the NVIDIA credentials, and starts OpenCode. ## Step 3: Hit a Problem -Try using opencode inside the sandbox. You will likely find that calls to NVIDIA inference endpoints fail or behave unexpectedly. The default policy is designed around Claude Code, not opencode. +Try using OpenCode inside the sandbox. You will likely find that calls to NVIDIA inference endpoints fail or behave unexpectedly. The default policy is designed around Claude Code, not OpenCode. Open a second terminal and check the logs: @@ -76,14 +76,14 @@ These log entries tell you exactly what the policy blocks and why. ## Step 4: Understand Why -The default policy has a `nvidia_inference` network policy entry, but it is configured for a narrow set of binaries, typically `/usr/local/bin/claude` and `/usr/bin/node`. If opencode makes HTTP calls through a different binary (its own binary, `curl`, or a shell subprocess), those connections do not match any policy rule and get denied. +The default policy has a `nvidia_inference` network policy entry, but it is configured for a narrow set of binaries, typically `/usr/local/bin/claude` and `/usr/bin/node`. If OpenCode makes HTTP calls through a different binary (its own binary, `curl`, or a shell subprocess), those connections do not match any policy rule and get denied. There are two separate problems: -1. OpenCode's own traffic. opencode contacts `opencode.ai` for its API and `integrate.api.nvidia.com` for inference. Neither of these endpoints has a matching policy entry for the binaries opencode uses. +1. OpenCode's own traffic. OpenCode contacts `opencode.ai` for its API and `integrate.api.nvidia.com` for inference. Neither of these endpoints has a matching policy entry for the binaries OpenCode uses. 2. No opencode.ai endpoint. The default policy has no entry for `opencode.ai` at all. Even if the binary matched, the destination is not listed. -This is the expected behavior. NemoClaw denies by default. You need to write a policy that explicitly allows what opencode needs. +This is the expected behavior. NemoClaw denies by default. You need to write a policy that explicitly allows what OpenCode needs. ## Step 5: Write a Custom Policy From a0cfa0cb74f2cd93d636fdcd8fb82ad4e787b5d9 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Fri, 6 Mar 2026 10:50:47 -0800 Subject: [PATCH 20/39] some edits --- docs/tutorials/run-claude.md | 8 +++++--- docs/tutorials/run-openclaw.md | 6 ++++-- docs/tutorials/run-opencode.md | 12 +++++++----- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/docs/tutorials/run-claude.md b/docs/tutorials/run-claude.md index 9b0a1d8c..8422b468 100644 --- a/docs/tutorials/run-claude.md +++ b/docs/tutorials/run-claude.md @@ -7,12 +7,14 @@ This tutorial walks you through the simplest path to running Claude Code inside a NemoClaw sandbox. By the end, you will have an isolated environment with Claude Code running, your credentials securely injected, and a default policy controlling what the agent can access. -What you will learn: +## What you will learn -- Creating a sandbox with a single command +You will learn the following from this tutorial: + +- How to create a sandbox with a single command - How NemoClaw auto-discovers provider credentials - What the default policy allows and denies -- Connecting to a sandbox and working inside it +- How to connect to a sandbox and work inside it ## Step 1: Create a Sandbox diff --git a/docs/tutorials/run-openclaw.md b/docs/tutorials/run-openclaw.md index 4a06f05d..b6d4d01d 100644 --- a/docs/tutorials/run-openclaw.md +++ b/docs/tutorials/run-openclaw.md @@ -7,10 +7,12 @@ This tutorial shows you how to launch a community sandbox using the `--from` flag. Community sandboxes are pre-built configurations published to the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) repository. They bundle a container image, a tailored policy, and optional skills into a single package you can run with one command. -What you will learn: +## What you will learn + +You will learn the following from this tutorial: - What community sandboxes are and how they differ from default sandboxes -- How the `--from` flag pulls and builds a complete sandbox configuration +- How to use the `--from` flag to pull and build a complete sandbox configuration - How to inspect the bundled policy that ships with a community sandbox ## Prerequisites diff --git a/docs/tutorials/run-opencode.md b/docs/tutorials/run-opencode.md index 4032c655..e6ba9b0c 100644 --- a/docs/tutorials/run-opencode.md +++ b/docs/tutorials/run-opencode.md @@ -7,13 +7,15 @@ This tutorial walks through a realistic setup where you run [OpenCode](https://opencode.ai) inside a NemoClaw sandbox with inference routed to NVIDIA API endpoints. Along the way, you will hit policy problems, diagnose them from logs, write a custom policy, and configure inference routing. This is the full policy iteration loop. -**What you will learn:** +## What you will learn -- Creating a provider manually with `--from-existing` -- Writing a custom policy to replace the defaults -- Reading sandbox logs to diagnose denied actions +You will learn the following from this tutorial: + +- How to create a provider manually using the `--from-existing` flag +- How to write a custom policy to replace the default policy +- How to read sandbox logs to diagnose denied actions - The difference between agent traffic and userland inference -- Setting up inference routes for code running inside the sandbox +- How to set up inference routes for code running inside the sandbox ## Prerequisites From 946f047ec6dbaf4aedc48cae36ffd21882991dc6 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Fri, 6 Mar 2026 13:47:03 -0800 Subject: [PATCH 21/39] enterprise structure --- docs/{reference => about}/architecture.md | 16 +++- docs/about/overview.md | 90 +++++++++++++++++++ docs/{ => about}/release-notes.md | 0 docs/get-started/quickstart.md | 76 ++++++++++++++++ docs/{tutorials => get-started}/run-claude.md | 8 +- .../run-openclaw.md | 8 +- .../run-opencode.md | 10 +-- docs/get-started/tutorials.md | 66 ++++++++++++++ docs/index.md | 84 ++++------------- docs/inference/index.md | 2 +- docs/safety-and-privacy/index.md | 2 +- docs/sandboxes/create-and-manage.md | 38 +------- docs/sandboxes/index.md | 49 ++++++++++ 13 files changed, 328 insertions(+), 121 deletions(-) rename docs/{reference => about}/architecture.md (93%) create mode 100644 docs/about/overview.md rename docs/{ => about}/release-notes.md (100%) create mode 100644 docs/get-started/quickstart.md rename docs/{tutorials => get-started}/run-claude.md (90%) rename docs/{tutorials => get-started}/run-openclaw.md (90%) rename docs/{tutorials => get-started}/run-opencode.md (93%) create mode 100644 docs/get-started/tutorials.md create mode 100644 docs/sandboxes/index.md diff --git a/docs/reference/architecture.md b/docs/about/architecture.md similarity index 93% rename from docs/reference/architecture.md rename to docs/about/architecture.md index 7c6d5841..a38835ef 100644 --- a/docs/reference/architecture.md +++ b/docs/about/architecture.md @@ -1,9 +1,23 @@ +--- +title: + page: "Architecture Overview" + nav: "Architecture" +description: "Understand the architecture of NVIDIA NemoClaw: the gateway, sandbox pods, policy engine, and privacy router." +keywords: ["nemoclaw architecture", "sandbox architecture", "agent isolation", "k3s", "policy engine"] +topics: ["generative_ai", "cybersecurity"] +tags: ["ai_agents", "sandboxing", "security", "architecture"] +content: + type: concept + difficulty: technical_advanced + audience: [engineer, data_scientist] +--- + -# Architecture +# Architecture Overview NemoClaw runs as a [k3s](https://k3s.io/) Kubernetes cluster inside a Docker container. Sandboxes are Kubernetes pods managed by the NemoClaw control plane. diff --git a/docs/about/overview.md b/docs/about/overview.md new file mode 100644 index 00000000..eaa1b822 --- /dev/null +++ b/docs/about/overview.md @@ -0,0 +1,90 @@ +--- +title: + page: "Overview of NVIDIA NemoClaw" + nav: "Overview" +description: "NemoClaw is the safe, private runtime for autonomous AI agents. Run agents in sandboxed environments that protect your data, credentials, and infrastructure." +keywords: ["nemoclaw", "ai agent sandbox", "agent security", "agent isolation", "inference routing"] +topics: ["generative_ai", "cybersecurity"] +tags: ["ai_agents", "sandboxing", "security", "privacy", "inference_routing"] +content: + type: concept + difficulty: technical_beginner + audience: [engineer, data_scientist] +--- + + + +# Overview of NVIDIA NemoClaw + +NVIDIA NemoClaw is an open-source runtime that executes autonomous AI agents inside sandboxed environments with kernel-level isolation. It prevents agents from accessing unauthorized files, exfiltrating data, leaking credentials, or making uncontrolled network requests. A single declarative YAML policy governs filesystem, network, process, and inference protections across all sandboxes and is hot-reloadable without restarting running agents. + +## Challenge + +Autonomous AI agents need broad system access to be effective. They read and write files, install packages, make network requests, and invoke LLM APIs with credentials. This creates a set of risks that traditional application sandboxing does not address. + +- **Data exfiltration.** An agent with network access can send sensitive files, environment variables, or API keys to external endpoints. +- **Credential theft.** API keys, SSH keys, and cloud tokens stored in the environment are visible to any process the agent spawns. +- **Uncontrolled network activity.** Agents can reach arbitrary hosts, call unauthorized APIs, or route inference through unintended backends. +- **Privilege escalation.** Without process-level restrictions, agents can install software, modify system files, or spawn background processes that outlive the session. +- **Inference privacy leaks.** Prompts, completions, and tool calls routed through third-party APIs expose proprietary context to external providers. + +Running agents on bare metal or in conventional containers leaves these attack surfaces open. Organizations need a runtime that gives agents the access they require while enforcing strict boundaries on everything else. + +## Benefits + +NemoClaw addresses these risks through defense-in-depth enforcement across four protection layers. + +:::{dropdown} Kernel-Level Isolation +NemoClaw enforces isolation at the Linux kernel level using Landlock for filesystem restrictions, seccomp for system call filtering, and network namespaces for traffic control. These mechanisms operate below the application layer, so agents cannot bypass them regardless of the tools or languages they use. +::: + +:::{dropdown} Declarative Policy Enforcement +A single YAML policy file defines all security boundaries for a sandbox: allowed filesystem paths, permitted network destinations, restricted processes, and inference routing rules. Policies are hot-reloadable, so you can tighten or relax rules on a running sandbox without restarting the agent. +::: + +:::{dropdown} Credential Containment +Credentials are injected into sandboxes as environment variables at startup and are scoped to the sandbox's isolated namespace. They cannot be read by processes outside the sandbox, and network policies prevent agents from transmitting them to unauthorized endpoints. +::: + +:::{dropdown} Private Inference Routing +The built-in privacy router intercepts LLM API calls and redirects them to local or self-hosted backends based on your routing policy. Sensitive prompts and completions stay on infrastructure you control. Routes are configurable per sandbox and can be updated without restarting agents. +::: + +:::{dropdown} Full L7 Traffic Inspection +Every outbound TCP connection from a sandbox passes through an L7 proxy that resolves the calling process, evaluates the destination against the active policy, and either allows, denies, or reroutes the request. For REST endpoints, the proxy decrypts TLS, inspects HTTP method and path, and applies fine-grained access rules. +::: + +## Use Cases + +The following are common use cases for NemoClaw. + +:::{dropdown} Secure Coding Agents +Run AI coding assistants such as Claude Code, OpenCode, or OpenClaw inside a sandbox where they can read and modify project files but cannot access SSH keys, cloud credentials, or files outside the project directory. Network policies restrict which package registries and APIs the agent can reach. +::: + +:::{dropdown} Private Enterprise Development +Route all LLM inference through self-hosted NVIDIA NIM endpoints or private API backends. Proprietary source code and internal documentation stay on your infrastructure and are never sent to third-party LLM providers. +::: + +:::{dropdown} Multi-Agent Orchestration +Run multiple agents in separate sandboxes, each with its own policy. One agent can access a database while another can reach an external API, with no cross-sandbox communication unless explicitly permitted. The gateway manages lifecycle and credential distribution across all sandboxes. +::: + +:::{dropdown} Compliance and Audit +Declarative policies serve as auditable security controls. Each sandbox runs under a well-defined policy that specifies exactly what the agent can access. Policy files can be version-controlled and reviewed as part of your security and compliance processes. +::: + +:::{dropdown} Community and Custom Sandbox Images +Use pre-built sandbox images from the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) catalog or bring your own container. Community sandboxes bundle domain-specific tools, policies, and skills, while custom containers let you package any environment your agents need. +::: + +--- + +## Next Steps + +- [Architecture Overview](architecture.md): Understand the components that make up the NemoClaw runtime. +- [Get Started](../index.md): Install the CLI and create your first sandbox. +- [Security Model](../safety-and-privacy/security-model.md): Learn how NemoClaw enforces isolation across all protection layers. diff --git a/docs/release-notes.md b/docs/about/release-notes.md similarity index 100% rename from docs/release-notes.md rename to docs/about/release-notes.md diff --git a/docs/get-started/quickstart.md b/docs/get-started/quickstart.md new file mode 100644 index 00000000..f2b6ec05 --- /dev/null +++ b/docs/get-started/quickstart.md @@ -0,0 +1,76 @@ +--- +title: + page: "Quickstart" + nav: "Quickstart" +description: "Install the NemoClaw CLI and create your first sandboxed AI agent in two commands." +keywords: ["nemoclaw install", "quickstart", "sandbox create", "getting started"] +topics: ["generative_ai", "cybersecurity"] +tags: ["ai_agents", "sandboxing", "installation", "quickstart"] +content: + type: get_started + difficulty: technical_beginner + audience: [engineer, data_scientist] +--- + + + +# Quickstart + +NemoClaw is designed for minimal setup with safety and privacy built in from the start. Two commands take you from zero to a running, policy-enforced sandbox. + +## Prerequisites + +The following are the prerequisites for the NemoClaw CLI. + +- Docker must be running. +- Python 3.12+ is required. + +## Install the NemoClaw CLI + +```console +$ pip install nemoclaw +``` + +## Create Your First NemoClaw Sandbox + +::::{tab-set} + +:::{tab-item} Claude Code +```console +$ nemoclaw sandbox create -- claude +``` + +```text +✓ Runtime ready +✓ Discovered Claude credentials (ANTHROPIC_API_KEY) +✓ Created sandbox: keen-fox +✓ Policy loaded (4 protection layers active) + +Connecting to keen-fox... +``` + +Claude Code works out of the box with the default policy. +::: + +:::{tab-item} Community Sandbox +```console +$ nemoclaw sandbox create --from openclaw +``` + +The `--from` flag pulls from the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) catalog, which contains a collection of domain-specific sandbox images bundled with their own containers, policies, and skills. +::: + +:::: + +The agent runs with filesystem, network, process, and inference protection active. Credentials stay inside the sandbox, network access follows your policy, and inference traffic remains private. A single YAML policy controls all four protection layers and is hot-reloadable on a running sandbox. + +For OpenCode or Codex, refer to the [Run OpenCode with NVIDIA Inference](run-opencode.md) tutorial for agent-specific setup. + +## Next Steps + +- [Tutorials](tutorials.md): Step-by-step walkthroughs for Claude Code, OpenClaw, and OpenCode. +- [Sandboxes](../sandboxes/create-and-manage.md): Understand the isolation model and sandbox lifecycle. +- [Safety and Privacy](../safety-and-privacy/index.md): Write policies that control what agents can access. diff --git a/docs/tutorials/run-claude.md b/docs/get-started/run-claude.md similarity index 90% rename from docs/tutorials/run-claude.md rename to docs/get-started/run-claude.md index 8422b468..51050700 100644 --- a/docs/tutorials/run-claude.md +++ b/docs/get-started/run-claude.md @@ -110,7 +110,7 @@ $ nemoclaw sandbox create --keep -- claude ## Next Steps -- {doc}`../../sandboxes/create-and-manage`: Understand the isolation model and sandbox lifecycle -- {doc}`../../sandboxes/providers`: How credentials are injected without exposing them to agent code -- {doc}`../../safety-and-privacy/policies`: Learn how the default policy works and how to customize it -- {doc}`../../safety-and-privacy/network-access-rules`: Dig into the network proxy and per-endpoint rules +- {doc}`../sandboxes/create-and-manage`: Understand the isolation model and sandbox lifecycle +- {doc}`../sandboxes/providers`: How credentials are injected without exposing them to agent code +- {doc}`../safety-and-privacy/policies`: Learn how the default policy works and how to customize it +- {doc}`../safety-and-privacy/network-access-rules`: Dig into the network proxy and per-endpoint rules diff --git a/docs/tutorials/run-openclaw.md b/docs/get-started/run-openclaw.md similarity index 90% rename from docs/tutorials/run-openclaw.md rename to docs/get-started/run-openclaw.md index b6d4d01d..501bd31b 100644 --- a/docs/tutorials/run-openclaw.md +++ b/docs/get-started/run-openclaw.md @@ -21,7 +21,7 @@ Before you begin, make sure you have: - Docker running on your machine. - NVIDIA GPU with drivers installed. Required for GPU-accelerated workloads in the OpenClaw sandbox. -- [NemoClaw CLI installed](../index.md#install-the-nemoclaw-cli) +- [NemoClaw CLI installed](quickstart.md#install-the-nemoclaw-cli) ## Step 1: Create a Sandbox from the Community Image @@ -101,6 +101,6 @@ The NemoClaw Community repository accepts contributions. If you build a sandbox ## Next Steps -- {doc}`../../sandboxes/community-sandboxes`: Full reference on community sandbox definitions, available images, and how to contribute your own -- {doc}`../../safety-and-privacy/policies`: Understand the policy format and how to customize what a sandbox can do -- {doc}`../../sandboxes/create-and-manage`: The isolation model and lifecycle behind every sandbox \ No newline at end of file +- {doc}`../sandboxes/community-sandboxes`: Full reference on community sandbox definitions, available images, and how to contribute your own +- {doc}`../safety-and-privacy/policies`: Understand the policy format and how to customize what a sandbox can do +- {doc}`../sandboxes/create-and-manage`: The isolation model and lifecycle behind every sandbox \ No newline at end of file diff --git a/docs/tutorials/run-opencode.md b/docs/get-started/run-opencode.md similarity index 93% rename from docs/tutorials/run-opencode.md rename to docs/get-started/run-opencode.md index e6ba9b0c..ee21ac3b 100644 --- a/docs/tutorials/run-opencode.md +++ b/docs/get-started/run-opencode.md @@ -259,8 +259,8 @@ $ nemoclaw sandbox delete opencode-sandbox ## Next Steps -- {doc}`../../safety-and-privacy/policies`: Full reference on policy YAML structure, static and dynamic fields, and enforcement modes -- {doc}`../../safety-and-privacy/network-access-rules`: How the proxy evaluates network rules, L4 and L7 inspection, and TLS termination -- {doc}`../../inference/index`: Inference route configuration, protocol detection, and transparent rerouting -- {doc}`../../sandboxes/providers`: Provider types, credential discovery, and manual and automatic creation -- {doc}`../../safety-and-privacy/security-model`: The four protection layers and how they interact +- {doc}`../safety-and-privacy/policies`: Full reference on policy YAML structure, static and dynamic fields, and enforcement modes +- {doc}`../safety-and-privacy/network-access-rules`: How the proxy evaluates network rules, L4 and L7 inspection, and TLS termination +- {doc}`../inference/index`: Inference route configuration, protocol detection, and transparent rerouting +- {doc}`../sandboxes/providers`: Provider types, credential discovery, and manual and automatic creation +- {doc}`../safety-and-privacy/security-model`: The four protection layers and how they interact diff --git a/docs/get-started/tutorials.md b/docs/get-started/tutorials.md new file mode 100644 index 00000000..808e28ad --- /dev/null +++ b/docs/get-started/tutorials.md @@ -0,0 +1,66 @@ +--- +title: + page: "NemoClaw Tutorials" + nav: "Tutorials" +description: "Step-by-step tutorials for running AI agents inside NemoClaw sandboxes." +keywords: ["nemoclaw tutorials", "claude code sandbox", "opencode sandbox", "openclaw sandbox"] +topics: ["generative_ai", "cybersecurity"] +tags: ["ai_agents", "sandboxing", "tutorial"] +content: + type: tutorial + difficulty: technical_beginner + audience: [engineer, data_scientist] +--- + + + +# Tutorials + +This section contains tutorials that help you run AI agents inside NemoClaw sandboxes. Each tutorial covers a different agent and setup, from a single-command quickstart to full policy iteration with inference routing. + +::::{grid} 1 1 2 2 +:gutter: 3 + +:::{grid-item-card} Run Claude Code Safely +:link: run-claude +:link-type: doc + +Create a sandbox with a single command, auto-discover credentials, and work inside an isolated environment with the default policy. + ++++ +{bdg-secondary}`Tutorial` +::: + +:::{grid-item-card} Run OpenClaw Safely +:link: run-openclaw +:link-type: doc + +Launch a community sandbox using the `--from` flag. Explore pre-built configurations bundled with tailored policies and container images. + ++++ +{bdg-secondary}`Tutorial` +::: + +:::{grid-item-card} Run OpenCode with NVIDIA Inference +:link: run-opencode +:link-type: doc + +Write a custom policy, diagnose denied actions from logs, and configure inference routing to NVIDIA API endpoints. + ++++ +{bdg-secondary}`Tutorial` +::: + +:::: + +```{toctree} +:hidden: +:maxdepth: 2 + +Run Claude Code Safely +Run OpenClaw Safely +Run OpenCode with NVIDIA Inference +``` diff --git a/docs/index.md b/docs/index.md index 0ec2850a..33f9001f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -28,72 +28,29 @@ content: [![License](https://img.shields.io/badge/License-Apache_2.0-blue)](https://github.com/NVIDIA/NemoClaw/blob/main/LICENSE) [![PyPI](https://img.shields.io/badge/PyPI-nemoclaw-orange?logo=pypi)](https://pypi.org/project/nemoclaw/) -NemoClaw is the safe, private runtime for autonomous AI agents. It provides sandboxed execution environments -that protect your data, credentials, and infrastructure. Agents run with exactly the permissions they need and -nothing more, governed by declarative policies that prevent unauthorized file access, data exfiltration, and +NemoClaw is the safe, private runtime for autonomous AI agents. It provides sandboxed execution environments +that protect your data, credentials, and infrastructure. Agents run with exactly the permissions they need and +nothing more, governed by declarative policies that prevent unauthorized file access, data exfiltration, and uncontrolled network activity. -## Install and Create a Sandbox +## Get Started -NemoClaw is designed for minimal setup with safety and privacy built in from the start. Two commands take you from zero to a running, policy-enforced sandbox. - -### Prerequisites - -The following are the prerequisites for the NemoClaw CLI. - -- Docker must be running. -- Python 3.12+ is required. - -### Install the NemoClaw CLI +Install the CLI and create your first sandbox in two commands. Refer to the [Quickstart](get-started/quickstart.md) to get up and running. ```console $ pip install nemoclaw -``` - -### Create Your First NemoClaw Sandbox - -::::{tab-set} - -:::{tab-item} Claude Code -```console $ nemoclaw sandbox create -- claude ``` -```text -✓ Runtime ready -✓ Discovered Claude credentials (ANTHROPIC_API_KEY) -✓ Created sandbox: keen-fox -✓ Policy loaded (4 protection layers active) - -Connecting to keen-fox... -``` - -Claude Code works out of the box with the default policy. -::: - -:::{tab-item} Community Sandbox -```console -$ nemoclaw sandbox create --from openclaw -``` - -The `--from` flag pulls from the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) catalog, which contains a collection of domain-specific sandbox images bundled with their own containers, policies, and skills. -::: - -:::: - -The agent runs with filesystem, network, process, and inference protection active. Credentials stay inside the sandbox, network access follows your policy, and inference traffic remains private. A single YAML policy controls all four protection layers and is hot-reloadable on a running sandbox. - -For OpenCode or Codex, refer to the [](tutorials/run-opencode.md) tutorial for agent-specific setup. - --- -## Next Steps +## Explore ::::{grid} 2 2 3 3 :gutter: 3 :::{grid-item-card} Tutorials -:link: tutorials/run-claude +:link: get-started/tutorials :link-type: doc Step-by-step walkthroughs for Claude Code, OpenClaw, and OpenCode with NVIDIA inference. @@ -102,18 +59,8 @@ Step-by-step walkthroughs for Claude Code, OpenClaw, and OpenCode with NVIDIA in {bdg-secondary}`Tutorial` ::: -:::{grid-item-card} Security Model -:link: safety-and-privacy/security-model -:link-type: doc - -How NemoClaw protects against data exfiltration, credential theft, unauthorized API calls, and privilege escalation. - -+++ -{bdg-secondary}`Concept` -::: - :::{grid-item-card} Sandboxes -:link: sandboxes/create-and-manage +:link: sandboxes/index :link-type: doc Create, manage, and customize sandboxes. Use community images or bring your own container. @@ -155,24 +102,27 @@ CLI commands, policy schema, environment variables, and system architecture. :::: ```{toctree} +:caption: About :hidden: -Get Started +Overview +Architecture +Release Notes ``` ```{toctree} -:caption: Tutorials +:caption: Get Started :hidden: -Run Claude Safely -Run OpenClaw Safely -Run OpenCode with NVIDIA Inference +get-started/quickstart +get-started/tutorials ``` ```{toctree} :caption: Sandboxes :hidden: +sandboxes/index sandboxes/create-and-manage sandboxes/providers sandboxes/custom-containers @@ -202,10 +152,8 @@ inference/configure-routes :caption: Reference :hidden: -release-notes reference/cli reference/policy-schema -reference/architecture ``` ```{toctree} diff --git a/docs/inference/index.md b/docs/inference/index.md index 3a973835..04955ce8 100644 --- a/docs/inference/index.md +++ b/docs/inference/index.md @@ -3,7 +3,7 @@ SPDX-License-Identifier: Apache-2.0 --> -# Inference Routing +# About Inference Routing The inference routing system keeps your AI inference traffic private by transparently intercepting API calls from sandboxed agents and rerouting them diff --git a/docs/safety-and-privacy/index.md b/docs/safety-and-privacy/index.md index c3ad0991..cff4c13c 100644 --- a/docs/safety-and-privacy/index.md +++ b/docs/safety-and-privacy/index.md @@ -3,7 +3,7 @@ SPDX-License-Identifier: Apache-2.0 --> -# Safety and Privacy +# About Safety and Privacy NemoClaw wraps every sandbox in four independent protection layers. No single point of failure can compromise your environment. Each layer covers gaps the diff --git a/docs/sandboxes/create-and-manage.md b/docs/sandboxes/create-and-manage.md index 1e88feb2..f6bb2bd2 100644 --- a/docs/sandboxes/create-and-manage.md +++ b/docs/sandboxes/create-and-manage.md @@ -5,43 +5,7 @@ # Create and Manage Sandboxes -A NemoClaw sandbox is a safe, private execution environment for an AI agent. Each sandbox runs inside a Kubernetes pod with multiple layers of protection that prevent unauthorized data access, credential exposure, and network exfiltration. Protection layers include filesystem restrictions (Landlock), system call filtering (seccomp), network namespace isolation, and a privacy-enforcing HTTP CONNECT proxy. - -This page walks you through the full sandbox lifecycle: creating, inspecting, connecting to, monitoring, and deleting sandboxes. - -## Sandbox Lifecycle - -Every sandbox moves through a defined set of phases: - -| Phase | Description | -|---|---| -| Provisioning | The runtime is setting up the sandbox environment, injecting credentials, and applying your policy. | -| Ready | The sandbox is running. The agent process is active and all isolation layers are enforced. You can connect, sync files, and view logs. | -| Error | Something went wrong during provisioning or execution. Check logs with `nemoclaw sandbox logs` for details. | -| Deleting | The sandbox is being torn down. The system releases resources and purges credentials. | - -## The NemoClaw Runtime - -Sandboxes run inside a lightweight runtime cluster that NemoClaw manages for -you. The cluster runs as a [k3s](https://k3s.io/) Kubernetes distribution -inside a Docker container on your machine. - -You do not need to set this up manually. The first time you run a command -that needs a cluster (such as `nemoclaw sandbox create`), the CLI provisions -one automatically. This is the "Runtime ready" line you see in the output. -Subsequent commands reuse the existing cluster. - -For teams or when you need more resources, you can deploy the cluster to a -remote host instead of your local machine: - -```console -$ nemoclaw cluster admin deploy --remote user@host -``` - -Refer to [Remote Deployment](../reference/architecture.md) for -details. If you have multiple clusters (local and remote), switch between them -with `nemoclaw cluster use `. Refer to the -[CLI Reference](../reference/cli.md#cluster-commands) for the full command set. +This page walks you through the full sandbox lifecycle: creating, inspecting, connecting to, monitoring, and deleting sandboxes. For background on what sandboxes are and how the runtime works, refer to [About Sandboxes](index.md). ## Prerequisites diff --git a/docs/sandboxes/index.md b/docs/sandboxes/index.md new file mode 100644 index 00000000..f93319f1 --- /dev/null +++ b/docs/sandboxes/index.md @@ -0,0 +1,49 @@ + + +# About Sandboxes + +A NemoClaw sandbox is a safe, private execution environment for an AI agent. Each sandbox runs inside a Kubernetes pod with multiple layers of protection that prevent unauthorized data access, credential exposure, and network exfiltration. Protection layers include filesystem restrictions (Landlock), system call filtering (seccomp), network namespace isolation, and a privacy-enforcing HTTP CONNECT proxy. + +## Sandbox Lifecycle + +Every sandbox moves through a defined set of phases: + +| Phase | Description | +|---|---| +| Provisioning | The runtime is setting up the sandbox environment, injecting credentials, and applying your policy. | +| Ready | The sandbox is running. The agent process is active and all isolation layers are enforced. You can connect, sync files, and view logs. | +| Error | Something went wrong during provisioning or execution. Check logs with `nemoclaw sandbox logs` for details. | +| Deleting | The sandbox is being torn down. The system releases resources and purges credentials. | + +## The NemoClaw Runtime + +Sandboxes run inside a lightweight runtime cluster that NemoClaw manages for +you. The cluster runs as a [k3s](https://k3s.io/) Kubernetes distribution +inside a Docker container on your machine. + +You do not need to set this up manually. The first time you run a command +that needs a cluster (such as `nemoclaw sandbox create`), the CLI provisions +one automatically. This is the "Runtime ready" line you see in the output. +Subsequent commands reuse the existing cluster. + +For teams or when you need more resources, you can deploy the cluster to a +remote host instead of your local machine: + +```console +$ nemoclaw cluster admin deploy --remote user@host +``` + +Refer to [Remote Deployment](../about/architecture.md) for +details. If you have multiple clusters (local and remote), switch between them +with `nemoclaw cluster use `. Refer to the +[CLI Reference](../reference/cli.md#cluster-commands) for the full command set. + +## Next Steps + +- [Create and Manage Sandboxes](create-and-manage.md): The full sandbox lifecycle — create, inspect, connect, monitor, and delete. +- [Providers](providers.md): Create and attach credential providers. +- [Custom Containers](custom-containers.md): Build and run your own container image. +- [Community Sandboxes](community-sandboxes.md): Use pre-built sandboxes from the community catalog. From 726b424926d1ca20e72c2cc793cd6950b4bade73 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Fri, 6 Mar 2026 14:12:51 -0800 Subject: [PATCH 22/39] update cards --- docs/index.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/docs/index.md b/docs/index.md index 33f9001f..253d8774 100644 --- a/docs/index.md +++ b/docs/index.md @@ -49,11 +49,21 @@ $ nemoclaw sandbox create -- claude ::::{grid} 2 2 3 3 :gutter: 3 -:::{grid-item-card} Tutorials -:link: get-started/tutorials +:::{grid-item-card} About NemoClaw +:link: about/index :link-type: doc -Step-by-step walkthroughs for Claude Code, OpenClaw, and OpenCode with NVIDIA inference. +Learn about NemoClaw and its capabilities. + ++++ +{bdg-secondary}`Concept` +::: + +:::{grid-item-card} Get Started +:link: get-started/quickstart +:link-type: doc + +Quickstart guide for creating a NemoClaw sandbox with Claude Code, OpenClaw, and OpenCode. +++ {bdg-secondary}`Tutorial` From 37876839e74bb9febd63db37f86597ccd77cb81a Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Fri, 6 Mar 2026 18:51:41 -0800 Subject: [PATCH 23/39] improve --- docs/about/architecture.md | 201 ++++------------- docs/about/overview.md | 22 +- docs/conf.py | 17 ++ docs/get-started/quickstart.md | 39 +++- docs/get-started/run-claude.md | 79 +++---- docs/get-started/run-openclaw.md | 67 +++--- docs/get-started/run-opencode.md | 102 ++++----- docs/get-started/tutorials.md | 8 +- docs/index.md | 5 +- docs/reference/architecture.md | 208 ++++++++++++++++++ docs/safety-and-privacy/index.md | 11 + .../network-access-rules.md | 12 + docs/safety-and-privacy/policies.md | 9 + docs/sandboxes/providers.md | 8 + 14 files changed, 468 insertions(+), 320 deletions(-) create mode 100644 docs/reference/architecture.md diff --git a/docs/about/architecture.md b/docs/about/architecture.md index a38835ef..05716c5a 100644 --- a/docs/about/architecture.md +++ b/docs/about/architecture.md @@ -2,13 +2,13 @@ title: page: "Architecture Overview" nav: "Architecture" -description: "Understand the architecture of NVIDIA NemoClaw: the gateway, sandbox pods, policy engine, and privacy router." +description: "High-level overview of the NemoClaw architecture: gateway, sandboxes, policy engine, and privacy router." keywords: ["nemoclaw architecture", "sandbox architecture", "agent isolation", "k3s", "policy engine"] topics: ["generative_ai", "cybersecurity"] tags: ["ai_agents", "sandboxing", "security", "architecture"] content: type: concept - difficulty: technical_advanced + difficulty: technical_beginner audience: [engineer, data_scientist] --- @@ -17,180 +17,65 @@ content: SPDX-License-Identifier: Apache-2.0 --> -# Architecture Overview +# How NemoClaw Works -NemoClaw runs as a [k3s](https://k3s.io/) Kubernetes cluster inside a Docker -container. Sandboxes are Kubernetes pods managed by the NemoClaw control plane. -The system has four core components. - -| Component | Role | -|---|---| -| Gateway | Control-plane API that coordinates sandbox lifecycle and state, acts as the auth boundary, and brokers requests across the platform. | -| Sandbox | Isolated runtime that includes container supervision and general L7 egress routing. | -| Policy Engine | Policy definition and enforcement layer for filesystem, network, and process constraints. Defense in depth enforces policies from the application layer down to infrastructure and kernel layers. | -| Privacy Router | Privacy-aware LLM routing layer that keeps sensitive context on sandbox compute and routes based on cost/privacy policy. | - -## Component Diagram +NemoClaw runs as a [k3s](https://k3s.io/) Kubernetes cluster inside a Docker container. +Each sandbox is an isolated Kubernetes pod managed by the NemoClaw control plane. +Four components work together to keep agents secure. ```{mermaid} -graph TB - subgraph docker["Docker Container"] - subgraph k3s["k3s Cluster"] - gw["Gateway"] - pr["Privacy Router"] - - subgraph pod1["Sandbox"] - sup1["Supervisor"] - proxy1["L7 Proxy"] - pe1["Policy Engine"] - agent1["Agent"] - - sup1 --> proxy1 - sup1 --> agent1 - proxy1 --> pe1 - end - - subgraph pod2["Sandbox"] - sup2["Supervisor"] - proxy2["L7 Proxy"] - pe2["Policy Engine"] - agent2["Agent"] - - sup2 --> proxy2 - sup2 --> agent2 - proxy2 --> pe2 - end - - gw -- "credentials,
policies" --> sup1 - gw -- "credentials,
policies" --> sup2 - end +flowchart LR + CLI["CLI"] -->|gRPC| GW["Gateway"] + GW --> SBX["Sandbox"] + + subgraph SBX["Sandbox"] + direction TB + AGENT["Agent Process"] -->|All traffic| PROXY["Network Proxy"] + PROXY -->|Evaluate| OPA["Policy Engine"] end - cli["nemoclaw CLI"] -- "gRPC" --> gw - agent1 -- "all outbound
traffic" --> proxy1 - agent2 -- "all outbound
traffic" --> proxy2 - proxy1 -- "policy-approved
traffic" --> internet["External Services"] - proxy2 -- "policy-approved
traffic" --> internet - proxy1 -- "inference traffic" --> pr - proxy2 -- "inference traffic" --> pr - pr -- "routed requests" --> backend["LLM Backend"] -``` - -## Gateway - -The gateway is the central control-plane API. It coordinates sandbox lifecycle -and state, acts as the auth boundary, and brokers all requests across the -platform. It exposes a gRPC API consumed by the CLI and handles: - -- Sandbox lifecycle: creates, monitors, and deletes sandbox pods. -- Provider storage: stores encrypted provider credentials. -- Policy distribution: delivers policy YAML to sandboxes at startup and on - hot-reload. -- SSH termination: terminates SSH tunnels from the CLI and routes them to - the correct sandbox. - -The CLI never talks to sandbox pods directly. All commands go through the -gateway. - -## Sandbox - -Each sandbox is an isolated runtime that includes container supervision and -general L7 egress routing. It runs as a Kubernetes pod containing a supervisor -process, an L7 proxy, and the agent. - -### Supervisor - -The supervisor is the sandbox's init process. It establishes all isolation -boundaries before starting the agent: - -1. Fetch credentials from the gateway for all attached providers. -2. Set up the network namespace. The sandbox gets its own network stack - with no default route. All outbound traffic is redirected through the proxy. -3. Apply Landlock filesystem restrictions based on the policy. -4. Apply seccomp filters to restrict available system calls. -5. Start the L7 proxy in the sandbox's network namespace. -6. Start the SSH server for interactive access. -7. Start the agent as a child process with credentials injected as - environment variables. + PROXY -->|Allowed traffic| EXT["External Services"] -### L7 Proxy + style CLI fill:#ffffff,stroke:#000000,color:#000000 + style GW fill:#76b900,stroke:#000000,color:#000000 + style SBX fill:#f5f5f5,stroke:#000000,color:#000000 + style AGENT fill:#ffffff,stroke:#000000,color:#000000 + style PROXY fill:#76b900,stroke:#000000,color:#000000 + style OPA fill:#76b900,stroke:#000000,color:#000000 + style EXT fill:#ffffff,stroke:#000000,color:#000000 -Every outbound TCP connection from any process in the sandbox is routed through -the proxy. For each connection, the proxy: - -1. Resolves the calling binary through `/proc//exe`, ancestor process - walking, and `/proc//cmdline`. -2. Queries the policy engine with the destination host, port, and resolved - binary path. -3. Acts on the decision: allow the connection directly, hand it to the - privacy router for inference routing, or deny it. Refer to - [How the Proxy Evaluates Connections](../safety-and-privacy/network-access-rules.md#how-the-proxy-evaluates-connections) - for the full decision model. + linkStyle default stroke:#76b900,stroke-width:2px +``` -For endpoints configured with `protocol: rest` and `tls: terminate`, the proxy -performs full L7 inspection: it decrypts TLS, reads the HTTP method and path, -evaluates access rules, then re-encrypts and forwards the request. +## Components -## Policy Engine +NemoClaw consists of the following components. -The policy engine is the definition and enforcement layer for filesystem, -network, and process constraints. Defense in depth enforces policies from the -application layer down to infrastructure and kernel layers. +Gateway +: The control-plane API that manages sandbox lifecycle, stores encrypted credentials, distributes policies, and terminates SSH tunnels. The CLI communicates exclusively with the gateway—it never talks to sandbox pods directly. -The engine evaluates policies compiled from the sandbox's policy YAML. It is -queried synchronously by the proxy on every outbound connection. Policy updates -delivered through hot-reload are compiled and loaded without restarting the proxy. +Sandbox +: An isolated pod that runs your agent. Each sandbox contains a **supervisor** (sets up isolation and starts the agent), an **L7 proxy** (intercepts and evaluates every outbound connection), and the agent process itself. -## Privacy Router +Policy Engine +: Evaluates declarative YAML policies that define filesystem, network, and process constraints. The proxy queries the engine on every outbound connection. Policies can be hot-reloaded without restarting the agent. -The privacy router is a privacy-aware LLM routing layer that keeps sensitive -context on sandbox compute and routes based on cost/privacy policy. +Privacy Router +: Intercepts LLM API calls and routes them to local or self-hosted backends based on your routing policy. Sensitive prompts and completions stay on infrastructure you control. -When the policy engine determines that a connection should be inspected for -inference, the privacy router: +## How a Request Flows -1. Reads the intercepted HTTP request. -2. Checks whether the method and path match a recognized inference API pattern - (`/v1/chat/completions`, `/v1/completions`, `/v1/messages`). -3. Selects a route whose `routing_hint` appears in the sandbox policy's - `allowed_routes`. -4. Strips the original authorization header. -5. Injects the route's API key and model ID. -6. Forwards the request to the route's backend URL. +NemoClaw works in the following way: -The router refreshes its route list periodically from the gateway, so routes -created with `nemoclaw inference create` become available without restarting -sandboxes. +1. The agent makes an outbound connection (for example, an API call). +2. The L7 proxy intercepts the connection and identifies the calling process. +3. The proxy queries the policy engine with the destination and process identity. +4. Based on the policy decision, the proxy either allows the connection, routes it through the privacy router for inference, or denies it. ## Remote Deployment -NemoClaw can deploy the cluster to a remote host via SSH. This is useful for -shared team environments or running sandboxes on machines with more resources. - -### Deploy - -```console -$ nemoclaw cluster admin deploy --remote user@host --ssh-key ~/.ssh/id_rsa -``` - -The CLI connects to the remote machine over SSH, installs k3s, deploys the -NemoClaw control plane, and registers the cluster locally. The remote machine -needs Docker installed. +NemoClaw can also run on a remote host. Deploy with `nemoclaw cluster admin deploy --remote user@host`, then set up a tunnel with `nemoclaw cluster admin tunnel`. The architecture is identical—only the Docker container location changes. -### Tunnel - -After deploying to a remote host, set up a tunnel for CLI access: - -```console -$ nemoclaw cluster admin tunnel -``` - -This establishes an SSH tunnel from your local machine to the remote cluster's -API server. All subsequent CLI commands route through this tunnel transparently. - -### Remote Architecture +--- -The architecture is identical to a local deployment. The only difference is -that the Docker container runs on the remote host instead of your workstation. -The CLI communicates with the gateway over the SSH tunnel. Sandbox SSH -connections are also tunneled through the gateway. +For detailed component internals, refer to the [Architecture Reference](../reference/architecture.md). diff --git a/docs/about/overview.md b/docs/about/overview.md index eaa1b822..923128fb 100644 --- a/docs/about/overview.md +++ b/docs/about/overview.md @@ -21,21 +21,15 @@ content: NVIDIA NemoClaw is an open-source runtime that executes autonomous AI agents inside sandboxed environments with kernel-level isolation. It prevents agents from accessing unauthorized files, exfiltrating data, leaking credentials, or making uncontrolled network requests. A single declarative YAML policy governs filesystem, network, process, and inference protections across all sandboxes and is hot-reloadable without restarting running agents. -## Challenge +## Common Challenges with AI Agents -Autonomous AI agents need broad system access to be effective. They read and write files, install packages, make network requests, and invoke LLM APIs with credentials. This creates a set of risks that traditional application sandboxing does not address. +AI agents are most useful when they have broad access to reading files, installing packages, calling APIs, and using credentials. However, this same access makes them dangerous. An unrestricted agent can leak your API keys, send proprietary code to unauthorized endpoints, or reach infrastructure it was never meant to touch. -- **Data exfiltration.** An agent with network access can send sensitive files, environment variables, or API keys to external endpoints. -- **Credential theft.** API keys, SSH keys, and cloud tokens stored in the environment are visible to any process the agent spawns. -- **Uncontrolled network activity.** Agents can reach arbitrary hosts, call unauthorized APIs, or route inference through unintended backends. -- **Privilege escalation.** Without process-level restrictions, agents can install software, modify system files, or spawn background processes that outlive the session. -- **Inference privacy leaks.** Prompts, completions, and tool calls routed through third-party APIs expose proprietary context to external providers. +Conventional containers do not solve this. They isolate processes from the host, but they do not control what an agent does *inside* the container — which files it reads, which hosts it contacts, or where it sends your prompts. -Running agents on bare metal or in conventional containers leaves these attack surfaces open. Organizations need a runtime that gives agents the access they require while enforcing strict boundaries on everything else. +## Benefits of Using NemoClaw -## Benefits - -NemoClaw addresses these risks through defense-in-depth enforcement across four protection layers. +NemoClaw addresses these risks through defense-in-depth enforcement across four policy domains: filesystem, network, process, and inference. :::{dropdown} Kernel-Level Isolation NemoClaw enforces isolation at the Linux kernel level using Landlock for filesystem restrictions, seccomp for system call filtering, and network namespaces for traffic control. These mechanisms operate below the application layer, so agents cannot bypass them regardless of the tools or languages they use. @@ -50,7 +44,7 @@ Credentials are injected into sandboxes as environment variables at startup and ::: :::{dropdown} Private Inference Routing -The built-in privacy router intercepts LLM API calls and redirects them to local or self-hosted backends based on your routing policy. Sensitive prompts and completions stay on infrastructure you control. Routes are configurable per sandbox and can be updated without restarting agents. +The built-in inference router intercepts LLM API calls and redirects them to local or self-hosted backends based on your routing policy. Sensitive prompts and completions stay on infrastructure you control. Routes are configurable per sandbox and can be updated without restarting agents. ::: :::{dropdown} Full L7 Traffic Inspection @@ -69,10 +63,6 @@ Run AI coding assistants such as Claude Code, OpenCode, or OpenClaw inside a san Route all LLM inference through self-hosted NVIDIA NIM endpoints or private API backends. Proprietary source code and internal documentation stay on your infrastructure and are never sent to third-party LLM providers. ::: -:::{dropdown} Multi-Agent Orchestration -Run multiple agents in separate sandboxes, each with its own policy. One agent can access a database while another can reach an external API, with no cross-sandbox communication unless explicitly permitted. The gateway manages lifecycle and credential distribution across all sandboxes. -::: - :::{dropdown} Compliance and Audit Declarative policies serve as auditable security controls. Each sandbox runs under a well-defined policy that specifies exactly what the agent can access. Policy files can be version-controlled and reviewed as part of your security and compliance processes. ::: diff --git a/docs/conf.py b/docs/conf.py index 17c00993..3f7ee3ff 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -64,6 +64,23 @@ html_show_sourcelink = False html_show_sphinx = False +mermaid_init_js = ( + "mermaid.initialize({" + " startOnLoad: true," + " theme: 'base'," + " themeVariables: {" + " background: '#ffffff'," + " primaryColor: '#76b900'," + " primaryTextColor: '#000000'," + " primaryBorderColor: '#000000'," + " lineColor: '#000000'," + " textColor: '#000000'," + " mainBkg: '#ffffff'," + " nodeBorder: '#000000'" + " }" + "});" +) + html_domain_indices = False html_use_index = False highlight_language = "console" diff --git a/docs/get-started/quickstart.md b/docs/get-started/quickstart.md index f2b6ec05..6309b2b2 100644 --- a/docs/get-started/quickstart.md +++ b/docs/get-started/quickstart.md @@ -19,23 +19,27 @@ content: # Quickstart -NemoClaw is designed for minimal setup with safety and privacy built in from the start. Two commands take you from zero to a running, policy-enforced sandbox. +This page gets you from zero to a running, policy-enforced sandbox in two commands. ## Prerequisites -The following are the prerequisites for the NemoClaw CLI. +Before you begin, make sure you have: -- Docker must be running. -- Python 3.12+ is required. +- Docker installed and running. +- Python 3.12 or later. ## Install the NemoClaw CLI +Install the NemoClaw CLI from PyPI. + ```console $ pip install nemoclaw ``` ## Create Your First NemoClaw Sandbox +Choose the tab that matches your agent: + ::::{tab-set} :::{tab-item} Claude Code @@ -52,7 +56,7 @@ $ nemoclaw sandbox create -- claude Connecting to keen-fox... ``` -Claude Code works out of the box with the default policy. +The CLI detects your `ANTHROPIC_API_KEY`, creates a provider, builds the sandbox, applies a default policy, and drops you into an interactive session. No additional configuration is required. ::: :::{tab-item} Community Sandbox @@ -60,17 +64,30 @@ Claude Code works out of the box with the default policy. $ nemoclaw sandbox create --from openclaw ``` -The `--from` flag pulls from the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) catalog, which contains a collection of domain-specific sandbox images bundled with their own containers, policies, and skills. +The `--from` flag pulls a pre-built sandbox definition from the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) catalog. Each definition bundles a container image, a tailored policy, and optional skills into a single package. ::: :::: -The agent runs with filesystem, network, process, and inference protection active. Credentials stay inside the sandbox, network access follows your policy, and inference traffic remains private. A single YAML policy controls all four protection layers and is hot-reloadable on a running sandbox. +## What Happens Behind the Scenes + +When you create a sandbox, NemoClaw activates four protection layers: + +- **Filesystem isolation.** The agent can only read and write paths that the policy explicitly permits. +- **Network enforcement.** Outbound connections are denied by default. The policy allowlists specific hosts, ports, and binaries. +- **Process restrictions.** The agent runs as a non-root user inside the container. +- **Inference privacy.** LLM API traffic is routed through a privacy-aware proxy. Credentials never leak outside the sandbox. -For OpenCode or Codex, refer to the [Run OpenCode with NVIDIA Inference](run-opencode.md) tutorial for agent-specific setup. +A single YAML policy file controls all four layers. You can hot-reload network and inference rules on a running sandbox without restarting it. + +:::{note} +For OpenCode or Codex, the default policy does not cover the required endpoints. Follow the [Run OpenCode with NVIDIA Inference](run-opencode.md) tutorial for agent-specific setup. +::: ## Next Steps -- [Tutorials](tutorials.md): Step-by-step walkthroughs for Claude Code, OpenClaw, and OpenCode. -- [Sandboxes](../sandboxes/create-and-manage.md): Understand the isolation model and sandbox lifecycle. -- [Safety and Privacy](../safety-and-privacy/index.md): Write policies that control what agents can access. +You now have a working sandbox. From here, you can: + +- Follow the [Tutorials](tutorials.md) for step-by-step walkthroughs with Claude Code, OpenClaw, and OpenCode. +- Learn how sandboxes work in [Sandboxes](../sandboxes/create-and-manage.md). +- Write your own policies in [Safety and Privacy](../safety-and-privacy/index.md). diff --git a/docs/get-started/run-claude.md b/docs/get-started/run-claude.md index 51050700..42a318bb 100644 --- a/docs/get-started/run-claude.md +++ b/docs/get-started/run-claude.md @@ -3,20 +3,23 @@ SPDX-License-Identifier: Apache-2.0 --> -# Run Claude Code Inside a NemoClaw Sandbox +# Run Claude Code Safely -This tutorial walks you through the simplest path to running Claude Code inside a NemoClaw sandbox. By the end, you will have an isolated environment with Claude Code running, your credentials securely injected, and a default policy controlling what the agent can access. +This tutorial walks you through the path to running Claude Code inside a NemoClaw sandbox. By the end of this tutorial, you will have an isolated environment with credentials securely injected and a default policy controlling what the agent can access. -## What you will learn +## What You Will Learn -You will learn the following from this tutorial: +- Create a sandbox with a single command. +- Understand how NemoClaw auto-discovers provider credentials. +- Inspect what the default policy allows and denies. +- Connect to a running sandbox and work inside it. -- How to create a sandbox with a single command -- How NemoClaw auto-discovers provider credentials -- What the default policy allows and denies -- How to connect to a sandbox and work inside it +## Prerequisites -## Step 1: Create a Sandbox +- Meet the prerequisites in the [Quickstart](quickstart.md). +- `ANTHROPIC_API_KEY` environment variable set on your host machine. + +## Create the Sandbox Run the following command: @@ -24,37 +27,37 @@ Run the following command: $ nemoclaw sandbox create -- claude ``` -This single command does several things: +This single command performs four actions: -1. Bootstraps the runtime. If this is your first time using NemoClaw, the CLI provisions a local k3s cluster inside Docker and deploys the NemoClaw control plane. This happens once. Subsequent commands reuse the existing cluster. -2. Auto-discovers credentials. The CLI detects that `claude` is a recognized tool and looks for your Anthropic credentials. It reads the `ANTHROPIC_API_KEY` environment variable and creates a provider automatically. -3. Creates the sandbox. The CLI provisions an isolated environment and applies the default policy. The policy allows Claude Code to reach `api.anthropic.com` and a small set of supporting endpoints while blocking everything else. -4. Drops you into the sandbox. You land in an interactive SSH session inside the sandbox, ready to work. +1. Bootstraps the runtime. On first use, the CLI provisions a local k3s cluster inside Docker and deploys the NemoClaw control plane. This happens once. Subsequent commands reuse the existing cluster. +2. Auto-discovers credentials. The CLI detects that `claude` is a recognized tool and reads the `ANTHROPIC_API_KEY` environment variable from your shell. It creates a provider automatically. +3. Creates the sandbox. The CLI provisions an isolated container and applies the default policy. This policy allows Claude Code to reach `api.anthropic.com` and a small set of supporting endpoints while blocking everything else. +4. Drops you into the sandbox. You land in an interactive SSH session, ready to work. :::{note} The first bootstrap takes a few minutes depending on your network speed. The CLI prints progress as each component starts. Subsequent sandbox creations are much faster. ::: -## Step 2: Work Inside the Sandbox +## Work Inside the Sandbox -You are now in an SSH session inside the sandbox. Start Claude Code: +You are now inside the sandbox. Start Claude Code: ```console $ claude ``` -Your credentials are available as environment variables inside the sandbox. You can verify this: +Your credentials are available as environment variables. Verify this with: ```console $ echo $ANTHROPIC_API_KEY sk-ant-... ``` -The sandbox has a working directory at `/sandbox` where you can create and edit files. Claude Code has access to standard development tools (git, common language runtimes, and package managers) within the boundaries set by the policy. +The sandbox provides a working directory at `/sandbox` where you can create and edit files. Standard development tools — git, common language runtimes, and package managers — are available within the boundaries set by the policy. -## Step 3: Check Sandbox Status +## Check Sandbox Status -Open a second terminal on your host machine. You can inspect running sandboxes from there. +Open a second terminal on your host machine to inspect the sandbox from outside. List all sandboxes: @@ -62,55 +65,55 @@ List all sandboxes: $ nemoclaw sandbox list ``` -For a live dashboard view, launch the NemoClaw Terminal: +Launch the NemoClaw Terminal for a live dashboard that shows sandbox status, active network connections, and policy decisions in real time: ```console $ nemoclaw term ``` -The terminal dashboard shows sandbox status, active network connections, and policy decisions in real time. - -## Step 4: Connect from VS Code +## Connect from VS Code (Optional) -If you prefer to work in VS Code rather than a terminal, you can connect using Remote-SSH. +If you prefer a graphical editor, connect to the sandbox with VS Code Remote-SSH. -First, export the sandbox's SSH configuration: +Export the sandbox SSH configuration: ```console -$ nemoclaw sandbox ssh-config my-sandbox >> ~/.ssh/config +$ nemoclaw sandbox ssh-config >> ~/.ssh/config ``` -Then open VS Code, install the Remote - SSH extension if you have not already, and connect to the host named `my-sandbox`. VS Code opens a full editor session inside the sandbox. +Then open VS Code, install the Remote - SSH extension if needed, and connect to the host named after your sandbox. VS Code opens a full editor session inside the isolated environment. :::{tip} -Replace `my-sandbox` with the actual name of your sandbox. Run `nemoclaw sandbox list` to find it if you did not specify a name at creation time. +Replace `` with your sandbox name. Run `nemoclaw sandbox list` to find it if you did not specify one at creation time. ::: -## Step 5: Clean Up +## Clean Up -When you are done, exit the sandbox shell: +Exit the sandbox shell: ```console $ exit ``` -Then delete the sandbox: +Delete the sandbox: ```console -$ nemoclaw sandbox delete my-sandbox +$ nemoclaw sandbox delete ``` :::{tip} -Use the `--keep` flag when you want the sandbox to stay alive after the command exits. This is useful when you plan to connect later or want to iterate on the policy while the sandbox runs. +If you want the sandbox to persist after you disconnect, add the `--keep` flag at creation time: ```console $ nemoclaw sandbox create --keep -- claude ``` + +This is useful when you plan to reconnect later or iterate on the policy while the sandbox runs. ::: ## Next Steps -- {doc}`../sandboxes/create-and-manage`: Understand the isolation model and sandbox lifecycle -- {doc}`../sandboxes/providers`: How credentials are injected without exposing them to agent code -- {doc}`../safety-and-privacy/policies`: Learn how the default policy works and how to customize it -- {doc}`../safety-and-privacy/network-access-rules`: Dig into the network proxy and per-endpoint rules +- {doc}`../sandboxes/create-and-manage`: Learn the isolation model and sandbox lifecycle. +- {doc}`../sandboxes/providers`: Understand how credentials are injected without exposing them to agent code. +- {doc}`../safety-and-privacy/policies`: Customize the default policy or write your own. +- {doc}`../safety-and-privacy/network-access-rules`: Explore the network proxy and per-endpoint rules. diff --git a/docs/get-started/run-openclaw.md b/docs/get-started/run-openclaw.md index 501bd31b..61db2f44 100644 --- a/docs/get-started/run-openclaw.md +++ b/docs/get-started/run-openclaw.md @@ -3,27 +3,22 @@ SPDX-License-Identifier: Apache-2.0 --> -# Run OpenClaw Inside a NemoClaw Sandbox +# Run OpenClaw Safely -This tutorial shows you how to launch a community sandbox using the `--from` flag. Community sandboxes are pre-built configurations published to the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) repository. They bundle a container image, a tailored policy, and optional skills into a single package you can run with one command. +This tutorial shows you how to launch a sandbox with OpenClaw from the [NemoClaw Community catalog](https://github.com/NVIDIA/NemoClaw-Community) using the `--from` flag. This is a pre-built sandbox configuration that includes a container image, a tailored policy, and optional skills. -## What you will learn +## What You Will Learn -You will learn the following from this tutorial: - -- What community sandboxes are and how they differ from default sandboxes -- How to use the `--from` flag to pull and build a complete sandbox configuration -- How to inspect the bundled policy that ships with a community sandbox +- Understand what community sandboxes are and how they differ from default sandboxes. +- Use the `--from` flag to pull and build a complete sandbox configuration. +- Inspect the bundled policy that ships with a community sandbox. ## Prerequisites -Before you begin, make sure you have: - -- Docker running on your machine. -- NVIDIA GPU with drivers installed. Required for GPU-accelerated workloads in the OpenClaw sandbox. -- [NemoClaw CLI installed](quickstart.md#install-the-nemoclaw-cli) +- Meet the prerequisites in the [Quickstart](quickstart.md). +- NVIDIA GPU with drivers installed. OpenClaw requires GPU acceleration. -## Step 1: Create a Sandbox from the Community Image +## Create the Sandbox Run the following command: @@ -31,20 +26,20 @@ Run the following command: $ nemoclaw sandbox create --from openclaw --keep ``` -The `--from` flag tells the CLI to pull a sandbox definition from the NemoClaw Community catalog. Here is what happens: +The `--from` flag tells the CLI to pull a sandbox definition from the NemoClaw Community catalog. Here is what happens behind the scenes: 1. Fetches the definition. The CLI downloads the OpenClaw sandbox definition from the NemoClaw-Community repository. This includes a Dockerfile, a policy YAML, and any bundled skills. -2. Builds the image. The CLI builds the Dockerfile locally using Docker. The image includes all tools and dependencies that OpenClaw needs. -3. Applies the bundled policy. Instead of the generic default policy, the sandbox starts with a policy specifically written for the OpenClaw workload. It allows the endpoints and binaries that OpenClaw requires. +2. Builds the image. The CLI builds the Dockerfile locally using Docker. The resulting image includes all tools and dependencies that OpenClaw needs. +3. Applies the bundled policy. Instead of the generic default policy, the sandbox starts with a policy written specifically for the OpenClaw workload. It allows the endpoints and binaries that OpenClaw requires. 4. Creates and keeps the sandbox. The `--keep` flag ensures the sandbox stays running after creation so you can connect and disconnect freely. :::{note} The first build takes longer because Docker needs to pull base layers and install dependencies. Subsequent creates reuse the cached image. ::: -## Step 2: Connect to the Sandbox +## Connect to the Sandbox -After the sandbox is running, connect to it: +After creation completes, connect to the running sandbox: ```console $ nemoclaw sandbox connect @@ -52,55 +47,55 @@ $ nemoclaw sandbox connect Replace `` with the sandbox name shown in the creation output. If you did not specify a name with `--name`, the CLI assigns one automatically. Run `nemoclaw sandbox list` to find it. -## Step 3: Explore the Environment +## Explore the Environment The sandbox comes pre-configured for the OpenClaw workload. The tools, runtimes, and libraries that OpenClaw needs are already installed in the container image. The policy is tuned to allow the specific network endpoints and operations that OpenClaw uses, so you can start working immediately without policy adjustments. -## Step 4: Check the Bundled Policy +## Inspect the Bundled Policy To see exactly what the sandbox is allowed to do, pull the full policy: ```console -$ nemoclaw sandbox policy get --full +$ nemoclaw sandbox policy get --full ``` -This outputs the complete policy YAML, including: +This outputs the complete policy YAML. Review it to understand the sandbox's permissions: -- Network policies: which hosts and ports the sandbox can reach, and which binaries are allowed to initiate those connections -- Filesystem policy: which paths are read-only and which are read-write -- Process restrictions: the user and group the sandbox runs as -- Inference rules: which inference routing hints are allowed +- Network policies, which hosts and ports the sandbox can reach, and which binaries are allowed to initiate those connections. +- Filesystem policy, which paths are read-only and which are read-write. +- Process restrictions, which user and group the sandbox runs as. +- Inference rules, which inference routing hints are allowed. -Reviewing the bundled policy is a good way to understand what a community sandbox has access to before you start using it for sensitive work. +Reviewing the bundled policy is a good practice before you use a community sandbox for sensitive work. :::{tip} -You can save the policy to a file for reference or as a starting point for customization: +Save the policy to a file for reference or as a starting point for customization: ```console $ nemoclaw sandbox policy get --full > openclaw-policy.yaml ``` ::: -## Step 5: Clean Up +## Clean Up -When you are finished, exit the sandbox if you are connected: +Exit the sandbox if you are connected: ```console $ exit ``` -Then delete it: +Delete the sandbox: ```console $ nemoclaw sandbox delete ``` :::{note} -The NemoClaw Community repository accepts contributions. If you build a sandbox configuration that would be useful to others, you can submit it to the [NemoClaw-Community](https://github.com/NVIDIA/NemoClaw-Community) repository. +The NemoClaw Community repository accepts contributions. If you build a sandbox configuration that would be useful to others, submit it to the [NemoClaw-Community](https://github.com/NVIDIA/NemoClaw-Community) repository. ::: ## Next Steps -- {doc}`../sandboxes/community-sandboxes`: Full reference on community sandbox definitions, available images, and how to contribute your own -- {doc}`../safety-and-privacy/policies`: Understand the policy format and how to customize what a sandbox can do -- {doc}`../sandboxes/create-and-manage`: The isolation model and lifecycle behind every sandbox \ No newline at end of file +- {doc}`../sandboxes/community-sandboxes`: Full reference on community sandbox definitions, available images, and how to contribute your own. +- {doc}`../safety-and-privacy/policies`: Learn the policy format and how to customize what a sandbox can do. +- {doc}`../sandboxes/create-and-manage`: Understand the isolation model and lifecycle behind every sandbox. diff --git a/docs/get-started/run-opencode.md b/docs/get-started/run-opencode.md index ee21ac3b..ee03fbca 100644 --- a/docs/get-started/run-opencode.md +++ b/docs/get-started/run-opencode.md @@ -5,28 +5,24 @@ # Run OpenCode with NVIDIA Inference -This tutorial walks through a realistic setup where you run [OpenCode](https://opencode.ai) inside a NemoClaw sandbox with inference routed to NVIDIA API endpoints. Along the way, you will hit policy problems, diagnose them from logs, write a custom policy, and configure inference routing. This is the full policy iteration loop. +This tutorial walks you through a realistic setup where you run [OpenCode](https://opencode.ai) inside a NemoClaw sandbox with inference routed to NVIDIA API endpoints. Along the way, you will hit a policy denial, diagnose it from logs, write a custom policy, and configure inference routing. This is the full policy iteration loop that you will use whenever you onboard a new tool. -## What you will learn +## What You Will Learn -You will learn the following from this tutorial: - -- How to create a provider manually using the `--from-existing` flag -- How to write a custom policy to replace the default policy -- How to read sandbox logs to diagnose denied actions -- The difference between agent traffic and userland inference -- How to set up inference routes for code running inside the sandbox +- Create a provider manually using the `--from-existing` flag. +- Write a custom policy to replace the default policy. +- Read sandbox logs to diagnose denied actions. +- Distinguish between agent traffic and userland inference. +- Set up inference routes for code running inside the sandbox. ## Prerequisites -Before you begin: - -- `NVIDIA_API_KEY` environment variable set on your host machine with a valid NVIDIA API key -- NemoClaw CLI installed (`pip install nemoclaw`) +- Meet the prerequisites in the [Quickstart](quickstart.md). +- `NVIDIA_API_KEY` environment variable set on your host machine with a valid NVIDIA API key. -## Step 1: Create the Provider +## Create the Provider -Unlike the Claude Code tutorial where the CLI auto-discovered credentials, here you create a provider explicitly. This gives you control over the provider name and type. +In the Claude Code tutorial, the CLI auto-discovered credentials. Here you create a provider explicitly, which gives you control over the provider name and type. ```console $ nemoclaw provider create --name nvidia --type nvidia --from-existing @@ -34,13 +30,13 @@ $ nemoclaw provider create --name nvidia --type nvidia --from-existing The `--from-existing` flag tells the CLI to discover credentials from your local environment. It finds `NVIDIA_API_KEY` and stores it securely. The provider is now available to attach to any sandbox. -Verify the provider: +Verify the provider exists: ```console $ nemoclaw provider list ``` -## Step 2: Create the Sandbox +## Create the Sandbox Create a sandbox with the NVIDIA provider attached and OpenCode as the startup command: @@ -48,11 +44,11 @@ Create a sandbox with the NVIDIA provider attached and OpenCode as the startup c $ nemoclaw sandbox create --name opencode-sandbox --provider nvidia --keep -- opencode ``` -The `--keep` flag keeps the sandbox alive after you exit, which you will need for the iteration steps ahead. The CLI creates the sandbox with the default policy, injects the NVIDIA credentials, and starts OpenCode. +The `--keep` flag keeps the sandbox alive after you exit, which you need for the iteration steps ahead. The CLI creates the sandbox with the default policy, injects the NVIDIA credentials, and starts OpenCode. -## Step 3: Hit a Problem +## Hit a Policy Denial -Try using OpenCode inside the sandbox. You will likely find that calls to NVIDIA inference endpoints fail or behave unexpectedly. The default policy is designed around Claude Code, not OpenCode. +Try using OpenCode inside the sandbox. You will find that calls to NVIDIA inference endpoints fail. The default policy is designed around Claude Code, not OpenCode, so the required endpoints are not allowlisted. Open a second terminal and check the logs: @@ -60,13 +56,13 @@ Open a second terminal and check the logs: $ nemoclaw sandbox logs opencode-sandbox --tail ``` -Or launch the NemoClaw Terminal for a live view: +Alternatively, launch the NemoClaw Terminal for a live view: ```console $ nemoclaw term ``` -Look for lines like these in the output: +Look for lines like these: ``` action=deny host=integrate.api.nvidia.com binary=/usr/local/bin/opencode reason="no matching network policy" @@ -74,20 +70,20 @@ action=deny host=opencode.ai binary=/usr/bin/node reas action=inspect_for_inference host=integrate.api.nvidia.com binary=/bin/bash ``` -These log entries tell you exactly what the policy blocks and why. +Each log entry tells you the exact host, binary, and reason for the denial. -## Step 4: Understand Why +## Understand the Denial -The default policy has a `nvidia_inference` network policy entry, but it is configured for a narrow set of binaries, typically `/usr/local/bin/claude` and `/usr/bin/node`. If OpenCode makes HTTP calls through a different binary (its own binary, `curl`, or a shell subprocess), those connections do not match any policy rule and get denied. +The default policy contains a `nvidia_inference` network policy entry, but it is configured for a narrow set of binaries — typically `/usr/local/bin/claude` and `/usr/bin/node`. When OpenCode makes HTTP calls through its own binary, `curl`, or a shell subprocess, those connections do not match any policy rule and get denied. -There are two separate problems: +Two separate problems are at play: -1. OpenCode's own traffic. OpenCode contacts `opencode.ai` for its API and `integrate.api.nvidia.com` for inference. Neither of these endpoints has a matching policy entry for the binaries OpenCode uses. -2. No opencode.ai endpoint. The default policy has no entry for `opencode.ai` at all. Even if the binary matched, the destination is not listed. +- OpenCode's own traffic. OpenCode contacts `opencode.ai` for its API and `integrate.api.nvidia.com` for inference. Neither endpoint has a matching rule for the binaries OpenCode uses. +- Missing endpoint. The default policy has no entry for `opencode.ai` at all. Even if the binary matched, the destination is not listed. -This is the expected behavior. NemoClaw denies by default. You need to write a policy that explicitly allows what OpenCode needs. +This is expected behavior. NemoClaw denies everything by default. You need to write a policy that explicitly allows what OpenCode needs. -## Step 5: Write a Custom Policy +## Write a Custom Policy Create a file called `opencode-policy.yaml` with the following content: @@ -184,26 +180,26 @@ network_policies: - path: /usr/bin/git ``` -Compared to the default policy, this adds: +This policy differs from the default in four key ways: -- `opencode_api`: allows opencode and Node.js to reach `opencode.ai:443` -- Broader `nvidia_inference` binaries: adds `/usr/local/bin/opencode`, `/usr/bin/curl`, and `/bin/bash` so opencode's subprocesses can reach the NVIDIA endpoint -- `inference.allowed_routes`: includes `nvidia` so inference routing works for userland code -- GitHub access scoped for opencode's git operations +- `opencode_api`: Allows OpenCode and Node.js to reach `opencode.ai:443`. +- Broader `nvidia_inference` binaries: Adds `/usr/local/bin/opencode`, `/usr/bin/curl`, and `/bin/bash` so OpenCode's subprocesses can reach the NVIDIA endpoint. +- `inference.allowed_routes`: Includes `nvidia` so inference routing works for userland code. +- GitHub access: Scoped to support OpenCode's git operations. :::{warning} -The `filesystem_policy`, `landlock`, and `process` sections are static. They are set at sandbox creation time and cannot be changed on a running sandbox. If you need to modify these, you must delete and recreate the sandbox. The `network_policies` and `inference` sections are dynamic and can be hot-reloaded. +The `filesystem_policy`, `landlock`, and `process` sections are static. They are set at sandbox creation time and cannot be changed on a running sandbox. To modify these, delete and recreate the sandbox. The `network_policies` and `inference` sections are dynamic and can be hot-reloaded. ::: -## Step 6: Push the Policy +## Apply the Policy -Apply your custom policy to the running sandbox: +Push your custom policy to the running sandbox: ```console $ nemoclaw sandbox policy set opencode-sandbox --policy opencode-policy.yaml --wait ``` -The `--wait` flag blocks until the sandbox confirms the policy is loaded. You will see output indicating success or failure. +The `--wait` flag blocks until the sandbox confirms the policy is loaded. Verify the policy revision was accepted: @@ -213,9 +209,9 @@ $ nemoclaw sandbox policy list opencode-sandbox The latest revision should show status `loaded`. -## Step 7: Set Up Inference Routing +## Set Up Inference Routing -So far, you have allowed the opencode *agent* to reach `integrate.api.nvidia.com` directly through network policy. But what about code that opencode writes and runs inside the sandbox? If that code calls an LLM API, it goes through the privacy router: a separate mechanism. +So far, you have allowed the OpenCode *agent* to reach `integrate.api.nvidia.com` directly through network policy. But code that OpenCode writes and runs inside the sandbox — scripts, notebooks, applications — uses a separate mechanism called the privacy router. Create an inference route so userland code can access NVIDIA models: @@ -227,17 +223,13 @@ $ nemoclaw inference create \ --api-key $NVIDIA_API_KEY ``` -The policy you wrote in Step 5 already includes `nvidia` in `inference.allowed_routes`, so you do not need to push a policy update. If you had not included it, you would add it to the policy and push again: - -```console -$ nemoclaw sandbox policy set opencode-sandbox --policy opencode-policy.yaml --wait -``` +The policy you wrote earlier already includes `nvidia` in `inference.allowed_routes`, so no policy update is needed. If you had omitted it, you would add the route to the policy and push again. :::{note} -The *network policies* control which hosts the agent binary can reach directly. The *inference routes* control where LLM API calls from userland code (scripts, notebooks, applications the agent writes) get routed. These are two separate enforcement points. +*Network policies* and *inference routes* are two separate enforcement points. Network policies control which hosts the agent binary can reach directly. Inference routes control where LLM API calls from userland code get routed through the privacy proxy. ::: -## Step 8: Verify +## Verify the Policy Tail the logs again: @@ -247,11 +239,11 @@ $ nemoclaw sandbox logs opencode-sandbox --tail You should no longer see `action=deny` lines for the endpoints you added. Connections to `opencode.ai`, `integrate.api.nvidia.com`, and GitHub should show `action=allow`. -If you still see denials, read the log line carefully. It tells you the exact host, port, and binary that was blocked. Add the missing entry to your policy and push again. This observe-modify-push cycle is the policy iteration loop, and it is the normal workflow for getting a new tool running in NemoClaw. +If you still see denials, read the log line carefully. It tells you the exact host, port, and binary that was blocked. Add the missing entry to your policy and push again with `nemoclaw sandbox policy set`. This observe-modify-push cycle is the normal workflow for onboarding any new tool in NemoClaw. ## Clean Up -When you are done: +When you are finished, delete the sandbox: ```console $ nemoclaw sandbox delete opencode-sandbox @@ -259,8 +251,8 @@ $ nemoclaw sandbox delete opencode-sandbox ## Next Steps -- {doc}`../safety-and-privacy/policies`: Full reference on policy YAML structure, static and dynamic fields, and enforcement modes -- {doc}`../safety-and-privacy/network-access-rules`: How the proxy evaluates network rules, L4 and L7 inspection, and TLS termination -- {doc}`../inference/index`: Inference route configuration, protocol detection, and transparent rerouting -- {doc}`../sandboxes/providers`: Provider types, credential discovery, and manual and automatic creation -- {doc}`../safety-and-privacy/security-model`: The four protection layers and how they interact +- {doc}`../safety-and-privacy/policies`: Full reference on policy YAML structure, static and dynamic fields, and enforcement modes. +- {doc}`../safety-and-privacy/network-access-rules`: How the proxy evaluates network rules, L4 and L7 inspection, and TLS termination. +- {doc}`../inference/index`: Inference route configuration, protocol detection, and transparent rerouting. +- {doc}`../sandboxes/providers`: Provider types, credential discovery, and manual and automatic creation. +- {doc}`../safety-and-privacy/security-model`: The four protection layers and how they interact. diff --git a/docs/get-started/tutorials.md b/docs/get-started/tutorials.md index 808e28ad..7c9295dd 100644 --- a/docs/get-started/tutorials.md +++ b/docs/get-started/tutorials.md @@ -19,7 +19,7 @@ content: # Tutorials -This section contains tutorials that help you run AI agents inside NemoClaw sandboxes. Each tutorial covers a different agent and setup, from a single-command quickstart to full policy iteration with inference routing. +Each tutorial below walks you through running a specific AI agent inside a NemoClaw sandbox. Choose the tutorial that matches your agent. ::::{grid} 1 1 2 2 :gutter: 3 @@ -28,7 +28,7 @@ This section contains tutorials that help you run AI agents inside NemoClaw sand :link: run-claude :link-type: doc -Create a sandbox with a single command, auto-discover credentials, and work inside an isolated environment with the default policy. +Create a sandbox with Claude Code. +++ {bdg-secondary}`Tutorial` @@ -38,7 +38,7 @@ Create a sandbox with a single command, auto-discover credentials, and work insi :link: run-openclaw :link-type: doc -Launch a community sandbox using the `--from` flag. Explore pre-built configurations bundled with tailored policies and container images. +Launch a sandbox with OpenClaw from the NemoClaw Community catalog using the `--from` flag. +++ {bdg-secondary}`Tutorial` @@ -48,7 +48,7 @@ Launch a community sandbox using the `--from` flag. Explore pre-built configurat :link: run-opencode :link-type: doc -Write a custom policy, diagnose denied actions from logs, and configure inference routing to NVIDIA API endpoints. +Launch a sandbox with OpenCode with NVIDIA inference routed to NVIDIA API endpoints. +++ {bdg-secondary}`Tutorial` diff --git a/docs/index.md b/docs/index.md index 253d8774..7e821dcf 100644 --- a/docs/index.md +++ b/docs/index.md @@ -50,7 +50,7 @@ $ nemoclaw sandbox create -- claude :gutter: 3 :::{grid-item-card} About NemoClaw -:link: about/index +:link: about/overview :link-type: doc Learn about NemoClaw and its capabilities. @@ -116,7 +116,7 @@ CLI commands, policy schema, environment variables, and system architecture. :hidden: Overview -Architecture +How It Works Release Notes ``` @@ -164,6 +164,7 @@ inference/configure-routes reference/cli reference/policy-schema +reference/architecture ``` ```{toctree} diff --git a/docs/reference/architecture.md b/docs/reference/architecture.md new file mode 100644 index 00000000..b1c1842f --- /dev/null +++ b/docs/reference/architecture.md @@ -0,0 +1,208 @@ +--- +title: + page: "Architecture Reference" + nav: "Architecture" +description: "Detailed reference for NemoClaw architecture: gateway, sandbox internals, policy engine, privacy router, and remote deployment." +keywords: ["nemoclaw architecture", "sandbox architecture", "agent isolation", "k3s", "policy engine"] +topics: ["generative_ai", "cybersecurity"] +tags: ["ai_agents", "sandboxing", "security", "architecture"] +content: + type: reference + difficulty: technical_advanced + audience: [engineer, data_scientist] +--- + + + +# Architecture Reference + +This page provides detailed technical information about each NemoClaw component. +For a high-level summary, refer to the [Architecture Overview](../about/architecture.md). + +## Component Diagram + +```{mermaid} +graph TB + subgraph docker["Docker Container"] + subgraph k3s["k3s Cluster"] + gw["Gateway"] + pr["Privacy Router"] + + subgraph pod1["Sandbox"] + sup1["Supervisor"] + proxy1["L7 Proxy"] + pe1["Policy Engine"] + agent1["Agent"] + + sup1 --> proxy1 + sup1 --> agent1 + proxy1 --> pe1 + end + + subgraph pod2["Sandbox"] + sup2["Supervisor"] + proxy2["L7 Proxy"] + pe2["Policy Engine"] + agent2["Agent"] + + sup2 --> proxy2 + sup2 --> agent2 + proxy2 --> pe2 + end + + gw -- "credentials,
policies" --> sup1 + gw -- "credentials,
policies" --> sup2 + end + end + + cli["nemoclaw CLI"] -- "gRPC" --> gw + agent1 -- "all outbound
traffic" --> proxy1 + agent2 -- "all outbound
traffic" --> proxy2 + proxy1 -- "policy-approved
traffic" --> internet["External Services"] + proxy2 -- "policy-approved
traffic" --> internet + proxy1 -- "inference traffic" --> pr + proxy2 -- "inference traffic" --> pr + pr -- "routed requests" --> backend["LLM Backend"] + + style cli fill:#ffffff,stroke:#000000,color:#000000 + style gw fill:#76b900,stroke:#000000,color:#000000 + style pr fill:#76b900,stroke:#000000,color:#000000 + style sup1 fill:#76b900,stroke:#000000,color:#000000 + style proxy1 fill:#76b900,stroke:#000000,color:#000000 + style pe1 fill:#76b900,stroke:#000000,color:#000000 + style agent1 fill:#ffffff,stroke:#000000,color:#000000 + style sup2 fill:#76b900,stroke:#000000,color:#000000 + style proxy2 fill:#76b900,stroke:#000000,color:#000000 + style pe2 fill:#76b900,stroke:#000000,color:#000000 + style agent2 fill:#ffffff,stroke:#000000,color:#000000 + style internet fill:#ffffff,stroke:#000000,color:#000000 + style backend fill:#ffffff,stroke:#000000,color:#000000 + style docker fill:#f5f5f5,stroke:#000000,color:#000000 + style k3s fill:#e8e8e8,stroke:#000000,color:#000000 + style pod1 fill:#f5f5f5,stroke:#000000,color:#000000 + style pod2 fill:#f5f5f5,stroke:#000000,color:#000000 + + linkStyle default stroke:#76b900,stroke-width:2px +``` + +## Gateway + +The gateway is the central control-plane API. It coordinates sandbox lifecycle +and state, acts as the auth boundary, and brokers all requests across the +platform. It exposes a gRPC API consumed by the CLI and handles: + +- Sandbox lifecycle: creates, monitors, and deletes sandbox pods. +- Provider storage: stores encrypted provider credentials. +- Policy distribution: delivers policy YAML to sandboxes at startup and on + hot-reload. +- SSH termination: terminates SSH tunnels from the CLI and routes them to + the correct sandbox. + +The CLI never talks to sandbox pods directly. All commands go through the +gateway. + +## Sandbox + +Each sandbox is an isolated runtime that includes container supervision and +general L7 egress routing. It runs as a Kubernetes pod containing a supervisor +process, an L7 proxy, and the agent. + +### Supervisor + +The supervisor is the sandbox's init process. It establishes all isolation +boundaries before starting the agent: + +1. Fetch credentials from the gateway for all attached providers. +2. Set up the network namespace. The sandbox gets its own network stack + with no default route. All outbound traffic is redirected through the proxy. +3. Apply Landlock filesystem restrictions based on the policy. +4. Apply seccomp filters to restrict available system calls. +5. Start the L7 proxy in the sandbox's network namespace. +6. Start the SSH server for interactive access. +7. Start the agent as a child process with credentials injected as + environment variables. + +### L7 Proxy + +Every outbound TCP connection from any process in the sandbox is routed through +the proxy. For each connection, the proxy: + +1. Resolves the calling binary through `/proc//exe`, ancestor process + walking, and `/proc//cmdline`. +2. Queries the policy engine with the destination host, port, and resolved + binary path. +3. Acts on the decision: allow the connection directly, hand it to the + privacy router for inference routing, or deny it. Refer to + [How the Proxy Evaluates Connections](../safety-and-privacy/network-access-rules.md#how-the-proxy-evaluates-connections) + for the full decision model. + +For endpoints configured with `protocol: rest` and `tls: terminate`, the proxy +performs full L7 inspection: it decrypts TLS, reads the HTTP method and path, +evaluates access rules, then re-encrypts and forwards the request. + +## Policy Engine + +The policy engine is the definition and enforcement layer for filesystem, +network, and process constraints. Defense in depth enforces policies from the +application layer down to infrastructure and kernel layers. + +The engine evaluates policies compiled from the sandbox's policy YAML. It is +queried synchronously by the proxy on every outbound connection. Policy updates +delivered through hot-reload are compiled and loaded without restarting the proxy. + +## Privacy Router + +The privacy router is a privacy-aware LLM routing layer that keeps sensitive +context on sandbox compute and routes based on cost/privacy policy. + +When the policy engine determines that a connection should be inspected for +inference, the privacy router: + +1. Reads the intercepted HTTP request. +2. Checks whether the method and path match a recognized inference API pattern + (`/v1/chat/completions`, `/v1/completions`, `/v1/messages`). +3. Selects a route whose `routing_hint` appears in the sandbox policy's + `allowed_routes`. +4. Strips the original authorization header. +5. Injects the route's API key and model ID. +6. Forwards the request to the route's backend URL. + +The router refreshes its route list periodically from the gateway, so routes +created with `nemoclaw inference create` become available without restarting +sandboxes. + +## Remote Deployment + +NemoClaw can deploy the cluster to a remote host via SSH. This is useful for +shared team environments or running sandboxes on machines with more resources. + +### Deploy + +```console +$ nemoclaw cluster admin deploy --remote user@host --ssh-key ~/.ssh/id_rsa +``` + +The CLI connects to the remote machine over SSH, installs k3s, deploys the +NemoClaw control plane, and registers the cluster locally. The remote machine +needs Docker installed. + +### Tunnel + +After deploying to a remote host, set up a tunnel for CLI access: + +```console +$ nemoclaw cluster admin tunnel +``` + +This establishes an SSH tunnel from your local machine to the remote cluster's +API server. All subsequent CLI commands route through this tunnel transparently. + +### Remote Architecture + +The architecture is identical to a local deployment. The only difference is +that the Docker container runs on the remote host instead of your workstation. +The CLI communicates with the gateway over the SSH tunnel. Sandbox SSH +connections are also tunneled through the gateway. diff --git a/docs/safety-and-privacy/index.md b/docs/safety-and-privacy/index.md index cff4c13c..4ace7aac 100644 --- a/docs/safety-and-privacy/index.md +++ b/docs/safety-and-privacy/index.md @@ -35,6 +35,17 @@ graph TB agent -- "sudo install pkg ✘" --> proc agent -- "call api.openai.com" --> inf inf -- "reroute → your backend ✔" --> net + + style runtime fill:#f5f5f5,stroke:#000000,color:#000000 + style layers fill:#e8e8e8,stroke:#000000,color:#000000 + style sandbox fill:#f5f5f5,stroke:#000000,color:#000000 + style agent fill:#ffffff,stroke:#000000,color:#000000 + style fs fill:#76b900,stroke:#000000,color:#000000 + style net fill:#76b900,stroke:#000000,color:#000000 + style proc fill:#76b900,stroke:#000000,color:#000000 + style inf fill:#76b900,stroke:#000000,color:#000000 + + linkStyle default stroke:#76b900,stroke-width:2px ``` You control all four layers through a single YAML policy. Network and inference diff --git a/docs/safety-and-privacy/network-access-rules.md b/docs/safety-and-privacy/network-access-rules.md index b31eed93..56ccab2d 100644 --- a/docs/safety-and-privacy/network-access-rules.md +++ b/docs/safety-and-privacy/network-access-rules.md @@ -39,6 +39,18 @@ flowchart TD G -- Yes --> H["Route to configured\ninference backend"] G -- No --> I["Deny: 403"] E -- No --> I + + style A fill:#ffffff,stroke:#000000,color:#000000 + style B fill:#76b900,stroke:#000000,color:#000000 + style C fill:#76b900,stroke:#000000,color:#000000 + style D fill:#76b900,stroke:#000000,color:#000000 + style E fill:#76b900,stroke:#000000,color:#000000 + style F fill:#76b900,stroke:#000000,color:#000000 + style G fill:#76b900,stroke:#000000,color:#000000 + style H fill:#76b900,stroke:#000000,color:#000000 + style I fill:#ff4444,stroke:#000000,color:#ffffff + + linkStyle default stroke:#76b900,stroke-width:2px ``` ## Structure of a Network Policy Entry diff --git a/docs/safety-and-privacy/policies.md b/docs/safety-and-privacy/policies.md index cb6307c4..46fb712d 100644 --- a/docs/safety-and-privacy/policies.md +++ b/docs/safety-and-privacy/policies.md @@ -113,6 +113,15 @@ flowchart TD D --> E["5. Push updated policy"] E --> F["6. Verify the new revision loaded"] F --> B + + style A fill:#76b900,stroke:#000000,color:#000000 + style B fill:#76b900,stroke:#000000,color:#000000 + style C fill:#76b900,stroke:#000000,color:#000000 + style D fill:#ffffff,stroke:#000000,color:#000000 + style E fill:#76b900,stroke:#000000,color:#000000 + style F fill:#76b900,stroke:#000000,color:#000000 + + linkStyle default stroke:#76b900,stroke-width:2px ``` ### Step 1: Create the Sandbox with Your Initial Policy diff --git a/docs/sandboxes/providers.md b/docs/sandboxes/providers.md index 70907b82..dd412724 100644 --- a/docs/sandboxes/providers.md +++ b/docs/sandboxes/providers.md @@ -112,6 +112,14 @@ flowchart LR B --> C["Sandbox starts"] C --> D["Supervisor fetches\ncredentials from gateway"] D --> E["Credentials injected into\nagent process + SSH sessions"] + + style A fill:#ffffff,stroke:#000000,color:#000000 + style B fill:#ffffff,stroke:#000000,color:#000000 + style C fill:#76b900,stroke:#000000,color:#000000 + style D fill:#76b900,stroke:#000000,color:#000000 + style E fill:#76b900,stroke:#000000,color:#000000 + + linkStyle default stroke:#76b900,stroke-width:2px ``` 1. You create a provider with credentials from your environment or From c380e694fccdb7532f38ace52d9b0235d75d9430 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Fri, 6 Mar 2026 19:02:19 -0800 Subject: [PATCH 24/39] add some emojis --- docs/about/overview.md | 18 +++++++++--------- docs/conf.py | 6 ++++++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/docs/about/overview.md b/docs/about/overview.md index 923128fb..4a7648d2 100644 --- a/docs/about/overview.md +++ b/docs/about/overview.md @@ -31,23 +31,23 @@ Conventional containers do not solve this. They isolate processes from the host, NemoClaw addresses these risks through defense-in-depth enforcement across four policy domains: filesystem, network, process, and inference. -:::{dropdown} Kernel-Level Isolation +:::{dropdown} 🛡️ Kernel-Level Isolation NemoClaw enforces isolation at the Linux kernel level using Landlock for filesystem restrictions, seccomp for system call filtering, and network namespaces for traffic control. These mechanisms operate below the application layer, so agents cannot bypass them regardless of the tools or languages they use. ::: -:::{dropdown} Declarative Policy Enforcement +:::{dropdown} 📜 Declarative Policy Enforcement A single YAML policy file defines all security boundaries for a sandbox: allowed filesystem paths, permitted network destinations, restricted processes, and inference routing rules. Policies are hot-reloadable, so you can tighten or relax rules on a running sandbox without restarting the agent. ::: -:::{dropdown} Credential Containment +:::{dropdown} 🔐 Credential Containment Credentials are injected into sandboxes as environment variables at startup and are scoped to the sandbox's isolated namespace. They cannot be read by processes outside the sandbox, and network policies prevent agents from transmitting them to unauthorized endpoints. ::: -:::{dropdown} Private Inference Routing +:::{dropdown} 🔀 Private Inference Routing The built-in inference router intercepts LLM API calls and redirects them to local or self-hosted backends based on your routing policy. Sensitive prompts and completions stay on infrastructure you control. Routes are configurable per sandbox and can be updated without restarting agents. ::: -:::{dropdown} Full L7 Traffic Inspection +:::{dropdown} 🔍 Full L7 Traffic Inspection Every outbound TCP connection from a sandbox passes through an L7 proxy that resolves the calling process, evaluates the destination against the active policy, and either allows, denies, or reroutes the request. For REST endpoints, the proxy decrypts TLS, inspects HTTP method and path, and applies fine-grained access rules. ::: @@ -55,19 +55,19 @@ Every outbound TCP connection from a sandbox passes through an L7 proxy that res The following are common use cases for NemoClaw. -:::{dropdown} Secure Coding Agents +:::{dropdown} 💻 Secure Coding Agents Run AI coding assistants such as Claude Code, OpenCode, or OpenClaw inside a sandbox where they can read and modify project files but cannot access SSH keys, cloud credentials, or files outside the project directory. Network policies restrict which package registries and APIs the agent can reach. ::: -:::{dropdown} Private Enterprise Development +:::{dropdown} 🏢 Private Enterprise Development Route all LLM inference through self-hosted NVIDIA NIM endpoints or private API backends. Proprietary source code and internal documentation stay on your infrastructure and are never sent to third-party LLM providers. ::: -:::{dropdown} Compliance and Audit +:::{dropdown} ✅ Compliance and Audit Declarative policies serve as auditable security controls. Each sandbox runs under a well-defined policy that specifies exactly what the agent can access. Policy files can be version-controlled and reviewed as part of your security and compliance processes. ::: -:::{dropdown} Community and Custom Sandbox Images +:::{dropdown} 📦 Community and Custom Sandbox Images Use pre-built sandbox images from the [NemoClaw Community](https://github.com/NVIDIA/NemoClaw-Community) catalog or bring your own container. Community sandboxes bundle domain-specific tools, policies, and skills, while custom containers let you package any environment your agents need. ::: diff --git a/docs/conf.py b/docs/conf.py index 3f7ee3ff..ec5069ff 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -93,5 +93,11 @@ "icon": "fa-brands fa-github", "type": "fontawesome", }, + { + "name": "PyPI", + "url": "https://pypi.org/project/nemoclaw/", + "icon": "fa-brands fa-python", + "type": "fontawesome", + }, ], } From 614d55e1cb5ffaa07c44b51374f4f6d27fdac407 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Fri, 6 Mar 2026 19:49:10 -0800 Subject: [PATCH 25/39] improve landing page with animated getting started code --- docs/index.md | 83 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/docs/index.md b/docs/index.md index 7e821dcf..f90144b7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -35,13 +35,84 @@ uncontrolled network activity. ## Get Started -Install the CLI and create your first sandbox in two commands. Refer to the [Quickstart](get-started/quickstart.md) to get up and running. - -```console -$ pip install nemoclaw -$ nemoclaw sandbox create -- claude +Install the CLI and create your first sandbox in two commands. + +```{raw} html + +
+
+ + + +
+
+
$ pip install nemoclaw
+
$ nemoclaw sandbox create -- claudeopenclawopencode
+
+
``` +Refer to the [Quickstart](get-started/quickstart.md) for more details. + --- ## Explore @@ -63,7 +134,7 @@ Learn about NemoClaw and its capabilities. :link: get-started/quickstart :link-type: doc -Quickstart guide for creating a NemoClaw sandbox with Claude Code, OpenClaw, and OpenCode. +Quickstart guide and tutorials for creating a NemoClaw sandbox with Claude Code, OpenClaw, and OpenCode. +++ {bdg-secondary}`Tutorial` From 619c43fd0ec4bdb842fcbaef320c72518c5d1fec Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Fri, 6 Mar 2026 19:58:56 -0800 Subject: [PATCH 26/39] fix the animated code --- docs/index.md | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/docs/index.md b/docs/index.md index f90144b7..29779a4f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -62,31 +62,23 @@ Install the CLI and create your first sandbox in two commands. .nc-term-dot-g { background: #27c93f; } .nc-term-body { padding: 16px 20px; color: #d4d4d8; } .nc-term-body .nc-ps { color: #76b900; user-select: none; } -.nc-term-agent { - position: relative; - display: inline-block; - min-width: 9ch; - height: 1.2em; +.nc-swap { + display: inline-grid; vertical-align: baseline; - color: #76b900; - font-weight: 600; } -.nc-term-agent span { - position: absolute; - left: 0; - top: 0; +.nc-swap > span { + grid-area: 1 / 1; white-space: nowrap; opacity: 0; - animation: nc-cycle 9s ease-in-out infinite; + animation: nc-cycle 6s ease-in-out infinite; } -.nc-term-agent span:nth-child(1) { animation-delay: 0s; } -.nc-term-agent span:nth-child(2) { animation-delay: 3s; } -.nc-term-agent span:nth-child(3) { animation-delay: 6s; } +.nc-swap > span:nth-child(2) { animation-delay: 3s; } @keyframes nc-cycle { - 0%, 3% { opacity: 0; transform: translateY(4px); } - 8%, 28% { opacity: 1; transform: translateY(0); } - 33.33%, 100% { opacity: 0; transform: translateY(-4px); } + 0%, 5% { opacity: 0; } + 10%, 42% { opacity: 1; } + 50%, 100% { opacity: 0; } } +.nc-hl { color: #76b900; font-weight: 600; } .nc-cursor { display: inline-block; width: 2px; @@ -106,7 +98,7 @@ Install the CLI and create your first sandbox in two commands.
$ pip install nemoclaw
-
$ nemoclaw sandbox create -- claudeopenclawopencode
+
$ nemoclaw sandbox create -- claude--from openclaw
``` From 678b65273fef4dfb5edf13371f60220c6c14eceb Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Sat, 7 Mar 2026 11:17:47 -0800 Subject: [PATCH 27/39] small improvements --- docs/get-started/quickstart.md | 14 ++++++++------ docs/get-started/run-claude.md | 18 +++++++++--------- docs/get-started/run-openclaw.md | 2 +- docs/get-started/run-opencode.md | 2 +- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/docs/get-started/quickstart.md b/docs/get-started/quickstart.md index 6309b2b2..2bed169e 100644 --- a/docs/get-started/quickstart.md +++ b/docs/get-started/quickstart.md @@ -71,12 +71,14 @@ The `--from` flag pulls a pre-built sandbox definition from the [NemoClaw Commun ## What Happens Behind the Scenes -When you create a sandbox, NemoClaw activates four protection layers: - -- **Filesystem isolation.** The agent can only read and write paths that the policy explicitly permits. -- **Network enforcement.** Outbound connections are denied by default. The policy allowlists specific hosts, ports, and binaries. -- **Process restrictions.** The agent runs as a non-root user inside the container. -- **Inference privacy.** LLM API traffic is routed through a privacy-aware proxy. Credentials never leak outside the sandbox. +When you create a sandbox, NemoClaw activates the following protection layers. + +| Protection Layer | Description | +|------------------------|-----------------------------------------------------------------------------------------------| +| Filesystem isolation | The agent can only read and write paths that the policy explicitly permits. | +| Network enforcement | Outbound connections are denied by default. The policy allowlists specific hosts, ports, and binaries. | +| Process restrictions | The agent runs as a non-root user inside the container. | +| Inference privacy | LLM API traffic is routed through a privacy-aware proxy. Credentials never leak outside the sandbox. | A single YAML policy file controls all four layers. You can hot-reload network and inference rules on a running sandbox without restarting it. diff --git a/docs/get-started/run-claude.md b/docs/get-started/run-claude.md index 42a318bb..50eee948 100644 --- a/docs/get-started/run-claude.md +++ b/docs/get-started/run-claude.md @@ -16,7 +16,7 @@ This tutorial walks you through the path to running Claude Code inside a NemoCla ## Prerequisites -- Meet the prerequisites in the [Quickstart](quickstart.md). +- Met the prerequisites and installed the NemoClaw CLI as described in the {doc}`quickstart` guide. - `ANTHROPIC_API_KEY` environment variable set on your host machine. ## Create the Sandbox @@ -59,17 +59,17 @@ The sandbox provides a working directory at `/sandbox` where you can create and Open a second terminal on your host machine to inspect the sandbox from outside. -List all sandboxes: +1. In the second terminal, list all sandboxes: -```console -$ nemoclaw sandbox list -``` + ```console + $ nemoclaw sandbox list + ``` -Launch the NemoClaw Terminal for a live dashboard that shows sandbox status, active network connections, and policy decisions in real time: +2. Launch the NemoClaw Terminal for a live dashboard that shows sandbox status, active network connections, and policy decisions in real time: -```console -$ nemoclaw term -``` + ```console + $ nemoclaw term + ``` ## Connect from VS Code (Optional) diff --git a/docs/get-started/run-openclaw.md b/docs/get-started/run-openclaw.md index 61db2f44..4e7d9614 100644 --- a/docs/get-started/run-openclaw.md +++ b/docs/get-started/run-openclaw.md @@ -15,7 +15,7 @@ This tutorial shows you how to launch a sandbox with OpenClaw from the [NemoClaw ## Prerequisites -- Meet the prerequisites in the [Quickstart](quickstart.md). +- Met the prerequisites and installed the NemoClaw CLI as described in the {doc}`quickstart` guide. - NVIDIA GPU with drivers installed. OpenClaw requires GPU acceleration. ## Create the Sandbox diff --git a/docs/get-started/run-opencode.md b/docs/get-started/run-opencode.md index ee03fbca..0a8f6d6f 100644 --- a/docs/get-started/run-opencode.md +++ b/docs/get-started/run-opencode.md @@ -17,7 +17,7 @@ This tutorial walks you through a realistic setup where you run [OpenCode](https ## Prerequisites -- Meet the prerequisites in the [Quickstart](quickstart.md). +- Met the prerequisites and installed the NemoClaw CLI as described in the {doc}`quickstart` guide. - `NVIDIA_API_KEY` environment variable set on your host machine with a valid NVIDIA API key. ## Create the Provider From ad53641172a7888ca6faa5c19713f0c35c8bbed7 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Sat, 7 Mar 2026 11:27:09 -0800 Subject: [PATCH 28/39] refresh content based on PR 156 and 158 --- docs/about/architecture.md | 2 +- docs/get-started/run-openclaw.md | 4 +- docs/get-started/run-opencode.md | 10 +- docs/inference/configure-routes.md | 2 +- docs/reference/architecture.md | 4 +- docs/reference/cli.md | 91 ++++++++++--------- docs/reference/policy-schema.md | 2 +- .../network-access-rules.md | 62 +++++++++++++ docs/safety-and-privacy/policies.md | 12 +-- docs/sandboxes/create-and-manage.md | 30 +++--- docs/sandboxes/custom-containers.md | 2 +- docs/sandboxes/index.md | 8 +- docs/troubleshooting.md | 24 ++--- 13 files changed, 161 insertions(+), 92 deletions(-) diff --git a/docs/about/architecture.md b/docs/about/architecture.md index 05716c5a..9a121ab5 100644 --- a/docs/about/architecture.md +++ b/docs/about/architecture.md @@ -74,7 +74,7 @@ NemoClaw works in the following way: ## Remote Deployment -NemoClaw can also run on a remote host. Deploy with `nemoclaw cluster admin deploy --remote user@host`, then set up a tunnel with `nemoclaw cluster admin tunnel`. The architecture is identical—only the Docker container location changes. +NemoClaw can also run on a remote host. Deploy with `nemoclaw gateway start --remote user@host`, then set up a tunnel with `nemoclaw gateway tunnel`. The architecture is identical—only the Docker container location changes. --- diff --git a/docs/get-started/run-openclaw.md b/docs/get-started/run-openclaw.md index 4e7d9614..db098e43 100644 --- a/docs/get-started/run-openclaw.md +++ b/docs/get-started/run-openclaw.md @@ -56,7 +56,7 @@ The sandbox comes pre-configured for the OpenClaw workload. The tools, runtimes, To see exactly what the sandbox is allowed to do, pull the full policy: ```console -$ nemoclaw sandbox policy get --full +$ nemoclaw policy get --full ``` This outputs the complete policy YAML. Review it to understand the sandbox's permissions: @@ -72,7 +72,7 @@ Reviewing the bundled policy is a good practice before you use a community sandb Save the policy to a file for reference or as a starting point for customization: ```console -$ nemoclaw sandbox policy get --full > openclaw-policy.yaml +$ nemoclaw policy get --full > openclaw-policy.yaml ``` ::: diff --git a/docs/get-started/run-opencode.md b/docs/get-started/run-opencode.md index 0a8f6d6f..e22338fe 100644 --- a/docs/get-started/run-opencode.md +++ b/docs/get-started/run-opencode.md @@ -53,7 +53,7 @@ Try using OpenCode inside the sandbox. You will find that calls to NVIDIA infere Open a second terminal and check the logs: ```console -$ nemoclaw sandbox logs opencode-sandbox --tail +$ nemoclaw logs opencode-sandbox --tail ``` Alternatively, launch the NemoClaw Terminal for a live view: @@ -196,7 +196,7 @@ The `filesystem_policy`, `landlock`, and `process` sections are static. They are Push your custom policy to the running sandbox: ```console -$ nemoclaw sandbox policy set opencode-sandbox --policy opencode-policy.yaml --wait +$ nemoclaw policy set opencode-sandbox --policy opencode-policy.yaml --wait ``` The `--wait` flag blocks until the sandbox confirms the policy is loaded. @@ -204,7 +204,7 @@ The `--wait` flag blocks until the sandbox confirms the policy is loaded. Verify the policy revision was accepted: ```console -$ nemoclaw sandbox policy list opencode-sandbox +$ nemoclaw policy list opencode-sandbox ``` The latest revision should show status `loaded`. @@ -234,12 +234,12 @@ The policy you wrote earlier already includes `nvidia` in `inference.allowed_rou Tail the logs again: ```console -$ nemoclaw sandbox logs opencode-sandbox --tail +$ nemoclaw logs opencode-sandbox --tail ``` You should no longer see `action=deny` lines for the endpoints you added. Connections to `opencode.ai`, `integrate.api.nvidia.com`, and GitHub should show `action=allow`. -If you still see denials, read the log line carefully. It tells you the exact host, port, and binary that was blocked. Add the missing entry to your policy and push again with `nemoclaw sandbox policy set`. This observe-modify-push cycle is the normal workflow for onboarding any new tool in NemoClaw. +If you still see denials, read the log line carefully. It tells you the exact host, port, and binary that was blocked. Add the missing entry to your policy and push again with `nemoclaw policy set`. This observe-modify-push cycle is the normal workflow for onboarding any new tool in NemoClaw. ## Clean Up diff --git a/docs/inference/configure-routes.md b/docs/inference/configure-routes.md index 24f5c656..b81c6180 100644 --- a/docs/inference/configure-routes.md +++ b/docs/inference/configure-routes.md @@ -74,7 +74,7 @@ $ nemoclaw sandbox create --policy ./my-policy.yaml --keep -- claude Or, if the sandbox is already running, push an updated policy: ```console -$ nemoclaw sandbox policy set --policy ./my-policy.yaml --wait +$ nemoclaw policy set --policy ./my-policy.yaml --wait ``` The `inference` section is a dynamic field, so you can add or remove routing hints on a running sandbox without recreating it. diff --git a/docs/reference/architecture.md b/docs/reference/architecture.md index b1c1842f..d1f4bfa3 100644 --- a/docs/reference/architecture.md +++ b/docs/reference/architecture.md @@ -182,7 +182,7 @@ shared team environments or running sandboxes on machines with more resources. ### Deploy ```console -$ nemoclaw cluster admin deploy --remote user@host --ssh-key ~/.ssh/id_rsa +$ nemoclaw gateway start --remote user@host --ssh-key ~/.ssh/id_rsa ``` The CLI connects to the remote machine over SSH, installs k3s, deploys the @@ -194,7 +194,7 @@ needs Docker installed. After deploying to a remote host, set up a tunnel for CLI access: ```console -$ nemoclaw cluster admin tunnel +$ nemoclaw gateway tunnel ``` This establishes an SSH tunnel from your local machine to the remote cluster's diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 6406d923..febd5e26 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -11,33 +11,32 @@ Complete command reference for the `nemoclaw` CLI. Every subcommand, flag, and o ```text nemoclaw -├── cluster -│ ├── status -│ ├── use -│ ├── list -│ └── admin -│ ├── deploy -│ ├── stop -│ ├── destroy -│ ├── info -│ └── tunnel +├── status +├── logs [name] +├── forward +│ ├── start +│ ├── stop +│ └── list +├── policy +│ ├── set +│ ├── get +│ └── list +├── gateway +│ ├── start +│ ├── stop +│ ├── destroy +│ ├── info +│ ├── tunnel +│ └── select [name] ├── sandbox │ ├── create │ ├── get [name] │ ├── list │ ├── delete │ ├── connect [name] -│ ├── sync [name] -│ ├── logs [name] -│ ├── ssh-config -│ ├── forward -│ │ ├── start -│ │ ├── stop -│ │ └── list -│ └── policy -│ ├── set -│ ├── get -│ └── list +│ ├── upload [name] +│ ├── download [name] +│ └── ssh-config ├── provider │ ├── create │ ├── get @@ -53,20 +52,34 @@ nemoclaw └── completions ``` -## Cluster Commands +## Top-Level Commands + +Commands available directly under `nemoclaw` for common operations. + +| Command | Description | +|---|---| +| `nemoclaw status` | Show the health and status of the active gateway. | +| `nemoclaw logs [name]` | View sandbox logs. Use `--tail` for streaming, `--source` and `--level` to filter. When name is omitted, uses the last-used sandbox. | +| `nemoclaw forward start ` | Forward a sandbox port to the host. Add `-d` for background mode. | +| `nemoclaw forward stop ` | Stop an active port forward. | +| `nemoclaw forward list` | List all active port forwards. | +| `nemoclaw policy set ` | Apply or update a policy on a running sandbox. Pass `--policy `. | +| `nemoclaw policy get ` | Show the active policy for a sandbox. Add `--full` for the complete policy with metadata. | +| `nemoclaw policy list ` | List all policy versions applied to a sandbox, with status. | + +## Gateway Commands Manage the NemoClaw runtime cluster. | Command | Description | |---|---| -| `nemoclaw cluster status` | Show the health and status of the active cluster. | -| `nemoclaw cluster use ` | Set the active cluster. All subsequent commands target this cluster. | -| `nemoclaw cluster list` | List all registered clusters. | -| `nemoclaw cluster admin deploy` | Deploy a new cluster. Add `--remote user@host` for remote deployment. | -| `nemoclaw cluster admin stop` | Stop the active cluster, preserving state. | -| `nemoclaw cluster admin destroy` | Permanently remove the cluster and all its data. | -| `nemoclaw cluster admin info` | Show detailed information about the cluster. | -| `nemoclaw cluster admin tunnel` | Set up a kubectl tunnel to a remote cluster. | +| `nemoclaw gateway start` | Deploy a new cluster. Add `--remote user@host` for remote deployment. | +| `nemoclaw gateway stop` | Stop the active cluster, preserving state. | +| `nemoclaw gateway destroy` | Permanently remove the cluster and all its data. | +| `nemoclaw gateway info` | Show detailed information about the cluster. | +| `nemoclaw gateway tunnel` | Set up a kubectl tunnel to a remote cluster. | +| `nemoclaw gateway select ` | Set the active cluster. All subsequent commands target this cluster. | +| `nemoclaw gateway select` | List all registered clusters (when called without a name). | ## Sandbox Commands @@ -79,15 +92,9 @@ Create and manage isolated agent execution environments. | `nemoclaw sandbox list` | List all sandboxes in the active cluster. | | `nemoclaw sandbox delete ` | Delete one or more sandboxes by name. | | `nemoclaw sandbox connect [name]` | Open an interactive SSH session into a running sandbox. When name is omitted, reconnects to the last-used sandbox. | -| `nemoclaw sandbox sync [name]` | Sync files between host and sandbox. Use `--up` or `--down`. When name is omitted, uses the last-used sandbox. | -| `nemoclaw sandbox logs [name]` | View sandbox logs. Use `--tail` for streaming, `--source` and `--level` to filter. When name is omitted, uses the last-used sandbox. | +| `nemoclaw sandbox upload [name]` | Upload files from the host into a sandbox. When name is omitted, uses the last-used sandbox. | +| `nemoclaw sandbox download [name]` | Download files from a sandbox to the host. When name is omitted, uses the last-used sandbox. | | `nemoclaw sandbox ssh-config ` | Print SSH config for a sandbox. Append to `~/.ssh/config` for VS Code Remote-SSH. | -| `nemoclaw sandbox forward start ` | Forward a sandbox port to the host. Add `-d` for background mode. | -| `nemoclaw sandbox forward stop ` | Stop an active port forward. | -| `nemoclaw sandbox forward list` | List all active port forwards. | -| `nemoclaw sandbox policy set ` | Apply or update a policy on a running sandbox. Pass `--policy `. | -| `nemoclaw sandbox policy get ` | Show the active policy for a sandbox. Add `--full` for the complete policy with metadata. | -| `nemoclaw sandbox policy list ` | List all policy versions applied to a sandbox, with status. | ### Sandbox Create Flags @@ -96,7 +103,7 @@ Create and manage isolated agent execution environments. | `--name` | Assign a human-readable name to the sandbox. Auto-generated if omitted. | | `--provider` | Attach a credential provider. Repeatable for multiple providers. | | `--policy` | Path to a policy YAML file to apply at creation time. | -| `--sync` | Sync local files into the sandbox before running. | +| `--upload` | Upload local files into the sandbox before running. | | `--keep` | Keep the sandbox alive after the trailing command exits. | | `--forward` | Forward a local port into the sandbox at startup. | | `--from` | Build from a community sandbox name, local Dockerfile directory, or container image reference. | @@ -157,7 +164,7 @@ entries, diagnose blocked connections, and interpret inference interception. ## Sandbox Name Fallback -Commands that accept an optional `[name]` argument, such as `get`, `connect`, `sync`, and `logs`, fall back to the last-used sandbox when the name is omitted. The CLI records the sandbox name each time you create or connect to a sandbox. When falling back, the CLI prints a hint showing which sandbox was selected. +Commands that accept an optional `[name]` argument, such as `get`, `connect`, `upload`, `download`, and `logs`, fall back to the last-used sandbox when the name is omitted. The CLI records the sandbox name each time you create or connect to a sandbox. When falling back, the CLI prints a hint showing which sandbox was selected. If no sandbox has been used yet and no name is provided, the command exits with an error prompting you to specify a name. @@ -165,7 +172,7 @@ If no sandbox has been used yet and no name is provided, the command exits with | Variable | Description | |---|---| -| `NEMOCLAW_CLUSTER` | Name of the cluster to operate on. Overrides the active cluster set by `nemoclaw cluster use`. | +| `NEMOCLAW_CLUSTER` | Name of the cluster to operate on. Overrides the active cluster set by `nemoclaw gateway select`. | | `NEMOCLAW_SANDBOX_POLICY` | Default path to a policy YAML file. When set, `nemoclaw sandbox create` uses this policy if no `--policy` flag is provided. | ## Shell Completions @@ -193,5 +200,5 @@ Every command and subcommand includes built-in help. Use `--help` at any level t $ nemoclaw --help $ nemoclaw sandbox --help $ nemoclaw sandbox create --help -$ nemoclaw cluster admin --help +$ nemoclaw gateway --help ``` diff --git a/docs/reference/policy-schema.md b/docs/reference/policy-schema.md index 3bacad0e..c48d35f4 100644 --- a/docs/reference/policy-schema.md +++ b/docs/reference/policy-schema.md @@ -27,7 +27,7 @@ inference: { ... } | `network_policies` | map | No | Dynamic | Declares which binaries can reach which network endpoints. | | `inference` | object | No | Dynamic | Controls which inference routing backends are available. | -Static fields are set at sandbox creation time. Changing them requires destroying and recreating the sandbox. Dynamic fields can be updated on a running sandbox with `nemoclaw sandbox policy set` and take effect without restarting. +Static fields are set at sandbox creation time. Changing them requires destroying and recreating the sandbox. Dynamic fields can be updated on a running sandbox with `nemoclaw policy set` and take effect without restarting. ## Version diff --git a/docs/safety-and-privacy/network-access-rules.md b/docs/safety-and-privacy/network-access-rules.md index 56ccab2d..69afe2cd 100644 --- a/docs/safety-and-privacy/network-access-rules.md +++ b/docs/safety-and-privacy/network-access-rules.md @@ -160,6 +160,68 @@ The proxy allows the TCP connection through to the destination without decryptin With L4-only rules, you have no control over *what* is sent to the endpoint: only *whether* the connection is allowed. Any binary listed in the entry can send any data to the host. If you need to restrict HTTP methods or paths, add `protocol: rest` and `tls: terminate`. ::: +## Forward Proxy Mode + +The sandbox proxy supports two request modes: CONNECT tunnels (the default for +HTTPS) and forward proxy (for plain HTTP to private endpoints). + +When a client inside the sandbox sets `HTTP_PROXY` and makes a plain `http://` +request, standard HTTP libraries send a forward proxy request instead of a +CONNECT tunnel. The proxy handles these transparently. + +### Security Constraints + +Forward proxy mode is restricted to private IP endpoints that are explicitly +allowed by policy. Plain HTTP traffic never reaches the public internet. All +three conditions must be true: + +1. The OPA policy explicitly allows the destination. +2. The matched endpoint has `allowed_ips` configured. +3. All resolved IP addresses are RFC 1918 private (`10/8`, `172.16/12`, `192.168/16`). + +If any condition fails, the proxy returns 403. + +| Condition | Forward proxy | CONNECT | +|---|---|---| +| Public IP, no `allowed_ips` | 403 | Allowed (standard SSRF check) | +| Public IP, with `allowed_ips` | 403 (private-IP gate) | Allowed if IP in allowlist | +| Private IP, no `allowed_ips` | 403 | 403 (SSRF block) | +| Private IP, with `allowed_ips` | Allowed | Allowed | +| `https://` scheme | 403 (must use CONNECT) | N/A | + +### Policy Configuration + +No new policy fields are needed. The same `network_policies` entry that enables +CONNECT access to a private endpoint also enables forward proxy access. Add +`allowed_ips` to the endpoint: + +```yaml +network_policies: + internal_service: + name: internal-service + endpoints: + - host: 10.86.8.223 + port: 8000 + allowed_ips: + - "10.86.8.223/32" + binaries: + - path: /usr/local/bin/python3.12 +``` + +With this policy, both CONNECT and forward proxy requests to the endpoint work: + +```python +import httpx +resp = httpx.get("http://10.86.8.223:8000/api/", + proxy="http://10.200.0.1:3128") +``` + +### Limitations + +- Forward proxy v1 injects `Connection: close` (no keep-alive). Each connection handles exactly one request-response exchange. +- L7 inspection is not performed on forwarded traffic. +- `https://` URLs must use the CONNECT tunnel, not the forward proxy path. + ## Enforcement Modes Each endpoint can operate in one of two enforcement modes: diff --git a/docs/safety-and-privacy/policies.md b/docs/safety-and-privacy/policies.md index 46fb712d..c75d8f67 100644 --- a/docs/safety-and-privacy/policies.md +++ b/docs/safety-and-privacy/policies.md @@ -135,7 +135,7 @@ $ nemoclaw sandbox create --policy ./my-policy.yaml --keep -- claude In a second terminal, tail the sandbox logs and look for `action: deny` entries: ```console -$ nemoclaw sandbox logs --tail --source sandbox +$ nemoclaw logs --tail --source sandbox ``` Each deny entry shows the blocked host, port, calling binary, and reason. This tells you exactly what the agent tried to reach and why it was blocked. @@ -155,7 +155,7 @@ push an updated policy without leaving the terminal. Export the running policy to a file: ```console -$ nemoclaw sandbox policy get --full > current-policy.yaml +$ nemoclaw policy get --full > current-policy.yaml ``` :::{warning} @@ -175,7 +175,7 @@ Edit `current-policy.yaml` to address the denied actions you observed. Common ch ### Step 5: Push the Updated Policy ```console -$ nemoclaw sandbox policy set --policy current-policy.yaml --wait +$ nemoclaw policy set --policy current-policy.yaml --wait ``` The `--wait` flag blocks until the policy engine processes the update. Exit codes: @@ -189,7 +189,7 @@ The `--wait` flag blocks until the policy engine processes the update. Exit code ### Step 6: Verify the New Revision Loaded ```console -$ nemoclaw sandbox policy list +$ nemoclaw policy list ``` Check that the latest revision shows status `loaded`. If it shows `failed`, review the error message and go back to Step 4. @@ -203,13 +203,13 @@ Return to Step 2. Monitor logs, observe new denied actions (or confirm everythin Every `policy set` creates a new revision. You can inspect the full revision history: ```console -$ nemoclaw sandbox policy list --limit 50 +$ nemoclaw policy list --limit 50 ``` To retrieve a specific revision: ```console -$ nemoclaw sandbox policy get --rev 3 --full +$ nemoclaw policy get --rev 3 --full ``` ### Revision Statuses diff --git a/docs/sandboxes/create-and-manage.md b/docs/sandboxes/create-and-manage.md index f6bb2bd2..caa7e442 100644 --- a/docs/sandboxes/create-and-manage.md +++ b/docs/sandboxes/create-and-manage.md @@ -26,7 +26,7 @@ The CLI bootstraps the runtime (if this is your first run), discovers your credentials, applies the default policy, and drops you into the sandbox. You can customize creation with flags like `--name`, `--provider`, `--policy`, -`--sync`, `--keep`, `--forward`, and `--from`. See the +`--upload`, `--keep`, `--forward`, and `--from`. See the [CLI Reference](../reference/cli.md) for the full flag list. A fully specified creation command might look like: @@ -36,7 +36,7 @@ $ nemoclaw sandbox create \ --name dev \ --provider my-claude \ --policy policy.yaml \ - --sync \ + --upload \ --keep \ -- claude ``` @@ -93,14 +93,14 @@ Stream and filter sandbox logs to monitor agent activity and diagnose policy dec Stream sandbox logs: ```console -$ nemoclaw sandbox logs my-sandbox +$ nemoclaw logs my-sandbox ``` Use flags to filter and follow output: | Flag | Purpose | Example | |---|---|---| -| `--tail` | Stream logs in real time | `nemoclaw sandbox logs my-sandbox --tail` | +| `--tail` | Stream logs in real time | `nemoclaw logs my-sandbox --tail` | | `--source` | Filter by log source | `--source sandbox` | | `--level` | Filter by severity | `--level warn` | | `--since` | Show logs from a time window | `--since 5m` | @@ -108,7 +108,7 @@ Use flags to filter and follow output: Combine flags to narrow in on what you need: ```console -$ nemoclaw sandbox logs my-sandbox --tail --source sandbox --level warn --since 5m +$ nemoclaw logs my-sandbox --tail --source sandbox --level warn --since 5m ``` :::{tip} @@ -117,24 +117,24 @@ run `nemoclaw term`. Refer to {doc}`terminal` for details on reading log entries diagnosing blocked connections. ::: -## Sync Files +## Transfer Files Transfer files between your host machine and a running sandbox. -Push files from your host into the sandbox: +Upload files from your host into the sandbox: ```console -$ nemoclaw sandbox sync my-sandbox --up ./src /sandbox/src +$ nemoclaw sandbox upload my-sandbox ./src /sandbox/src ``` -Pull files from the sandbox to your host: +Download files from the sandbox to your host: ```console -$ nemoclaw sandbox sync my-sandbox --down /sandbox/output ./local +$ nemoclaw sandbox download my-sandbox /sandbox/output ./local ``` :::{note} -You can also sync files at creation time with the `--sync` flag on +You can also upload files at creation time with the `--upload` flag on `nemoclaw sandbox create`. ::: @@ -144,25 +144,25 @@ Forward a port from the sandbox to your host machine. This runs in the foreground by default: ```console -$ nemoclaw sandbox forward start 8080 my-sandbox +$ nemoclaw forward start 8080 my-sandbox ``` Add `-d` to run the forward in the background: ```console -$ nemoclaw sandbox forward start 8080 my-sandbox -d +$ nemoclaw forward start 8080 my-sandbox -d ``` List active port forwards: ```console -$ nemoclaw sandbox forward list +$ nemoclaw forward list ``` Stop a port forward: ```console -$ nemoclaw sandbox forward stop 8080 my-sandbox +$ nemoclaw forward stop 8080 my-sandbox ``` :::{note} diff --git a/docs/sandboxes/custom-containers.md b/docs/sandboxes/custom-containers.md index 14a28579..a5b3a94d 100644 --- a/docs/sandboxes/custom-containers.md +++ b/docs/sandboxes/custom-containers.md @@ -39,7 +39,7 @@ $ nemoclaw sandbox create --from my-registry.example.com/my-image:latest --keep If your container runs a service, forward the port to your host: ```console -$ nemoclaw sandbox forward start 8080 my-app -d +$ nemoclaw forward start 8080 my-app -d ``` The `-d` flag runs the forward in the background so you can continue using diff --git a/docs/sandboxes/index.md b/docs/sandboxes/index.md index f93319f1..7749caba 100644 --- a/docs/sandboxes/index.md +++ b/docs/sandboxes/index.md @@ -15,7 +15,7 @@ Every sandbox moves through a defined set of phases: |---|---| | Provisioning | The runtime is setting up the sandbox environment, injecting credentials, and applying your policy. | | Ready | The sandbox is running. The agent process is active and all isolation layers are enforced. You can connect, sync files, and view logs. | -| Error | Something went wrong during provisioning or execution. Check logs with `nemoclaw sandbox logs` for details. | +| Error | Something went wrong during provisioning or execution. Check logs with `nemoclaw logs` for details. | | Deleting | The sandbox is being torn down. The system releases resources and purges credentials. | ## The NemoClaw Runtime @@ -33,13 +33,13 @@ For teams or when you need more resources, you can deploy the cluster to a remote host instead of your local machine: ```console -$ nemoclaw cluster admin deploy --remote user@host +$ nemoclaw gateway start --remote user@host ``` Refer to [Remote Deployment](../about/architecture.md) for details. If you have multiple clusters (local and remote), switch between them -with `nemoclaw cluster use `. Refer to the -[CLI Reference](../reference/cli.md#cluster-commands) for the full command set. +with `nemoclaw gateway select `. Refer to the +[CLI Reference](../reference/cli.md#gateway-commands) for the full command set. ## Next Steps diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index ed1b0783..ffbbfcbb 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -13,20 +13,20 @@ Troubleshoot problems with deploying, connecting to, and running NemoClaw cluste ### Cluster Deploy Fails -**Symptom:** `nemoclaw cluster admin deploy` exits with an error. +**Symptom:** `nemoclaw gateway start` exits with an error. **Check:** 1. Is Docker running? The cluster requires Docker to be active. 2. Is the port already in use? Try a different port: `--port 8081`. -3. Does a stale container exist? Destroy and redeploy: `nemoclaw cluster admin destroy && nemoclaw cluster admin deploy`. +3. Does a stale container exist? Destroy and redeploy: `nemoclaw gateway destroy && nemoclaw gateway start`. ### Cluster Not Reachable -**Symptom:** `nemoclaw cluster status` fails to connect. +**Symptom:** `nemoclaw status` fails to connect. **Check:** 1. Is the cluster container running? `docker ps | grep nemoclaw`. -2. Was the cluster stopped? Redeploy: `nemoclaw cluster admin deploy`. +2. Was the cluster stopped? Redeploy: `nemoclaw gateway start`. 3. For remote clusters, is the SSH connection working? ### Health Check Fails During Deploy @@ -47,7 +47,7 @@ Troubleshoot problems with creating, connecting to, and configuring sandboxes. **Symptom:** Sandbox shows `Provisioning` status and does not become `Ready`. **Check:** -1. View sandbox logs: `nemoclaw sandbox logs --source gateway`. +1. View sandbox logs: `nemoclaw logs --source gateway`. 2. Check if the container image can be pulled. 3. For custom images, verify the image was pushed: `nemoclaw sandbox image push`. @@ -64,18 +64,18 @@ Troubleshoot problems with creating, connecting to, and configuring sandboxes. **Symptom:** The agent cannot reach a remote host. **Check:** -1. Stream sandbox logs: `nemoclaw sandbox logs --tail --source sandbox`. +1. Stream sandbox logs: `nemoclaw logs --tail --source sandbox`. 2. Look for `deny` actions. They include the destination, binary, and reason. 3. Update the policy to allow the blocked endpoint. Refer to [Policy Iteration Loop](safety-and-privacy/policies.md#the-policy-iteration-loop). ### Policy Update Fails -**Symptom:** `nemoclaw sandbox policy set` returns an error or the status shows `failed`. +**Symptom:** `nemoclaw policy set` returns an error or the status shows `failed`. **Check:** 1. Are you changing a static field? `filesystem_policy`, `landlock`, and `process` cannot change after creation. 2. Are you adding/removing `network_policies` to change the network mode? This is not allowed. The mode is fixed at creation. -3. Check the error message in `nemoclaw sandbox policy list `. +3. Check the error message in `nemoclaw policy list `. ## Provider Issues @@ -121,15 +121,15 @@ Troubleshoot problems with forwarding local ports into sandbox services. **Symptom:** `localhost:` does not connect to the sandbox service. **Check:** -1. Is the forward running? `nemoclaw sandbox forward list`. +1. Is the forward running? `nemoclaw forward list`. 2. Is the service listening on that port inside the sandbox? 3. Is the sandbox still in `Ready` state? -4. Try stopping and restarting: `nemoclaw sandbox forward stop && nemoclaw sandbox forward start -d`. +4. Try stopping and restarting: `nemoclaw forward stop && nemoclaw forward start -d`. ## Getting More Information Use these techniques to gather additional diagnostic detail when troubleshooting. - Increase CLI verbosity: `nemoclaw -vvv ` for trace-level output. -- View gateway-side logs: `nemoclaw sandbox logs --source gateway`. -- View sandbox-side logs: `nemoclaw sandbox logs --source sandbox --level debug`. +- View gateway-side logs: `nemoclaw logs --source gateway`. +- View sandbox-side logs: `nemoclaw logs --source sandbox --level debug`. From fd4fae8cf196ebb4f41900c6a644cc3093a2277c Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Sat, 7 Mar 2026 11:59:39 -0800 Subject: [PATCH 29/39] README as the source of truth for quickstart --- README.md | 14 ++++++++++---- docs/get-started/quickstart.md | 13 +++++++------ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index df1a076a..96b902c0 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,17 @@ It transforms the data center from a static deployment target into a continuous ### Prerequisites -- **Docker** — Docker Desktop (or a Docker daemon) must be running. -- **Python 3.12+** -- [**uv**](https://docs.astral.sh/uv/) 0.9+ + +| Requirement | Details | +|-------------|---------------------------------------------------------------------------| +| **Docker** | Docker Desktop or a standalone Docker Engine daemon, running. | +| **Python** | 3.12 or later. | +| **uv** | [uv](https://docs.astral.sh/uv/) 0.9 or later. | + ### Install + ```bash uv pip install nemoclaw \ --upgrade \ @@ -23,7 +28,8 @@ uv pip install nemoclaw \ --index-url https://urm.nvidia.com/artifactory/api/pypi/nv-shared-pypi/simple ``` -The `nemoclaw` binary is installed into your Python environment. Use `uv run nemoclaw` to invoke it, or activate your venv first with `source .venv/bin/activate`. +The installer places the `nemoclaw` binary in your Python environment. Run it with `uv run nemoclaw`, or activate the virtual environment first (`source .venv/bin/activate`) and invoke `nemoclaw` directly. + ### Create a sandbox diff --git a/docs/get-started/quickstart.md b/docs/get-started/quickstart.md index 2bed169e..1a2f21ec 100644 --- a/docs/get-started/quickstart.md +++ b/docs/get-started/quickstart.md @@ -25,15 +25,16 @@ This page gets you from zero to a running, policy-enforced sandbox in two comman Before you begin, make sure you have: -- Docker installed and running. -- Python 3.12 or later. +```{include} ../../README.md +:start-after: +:end-before: +``` ## Install the NemoClaw CLI -Install the NemoClaw CLI from PyPI. - -```console -$ pip install nemoclaw +```{include} ../../README.md +:start-after: +:end-before: ``` ## Create Your First NemoClaw Sandbox From 7f25fe86d12058c924e680f4f45abd9cca8dc4e3 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Sat, 7 Mar 2026 12:18:24 -0800 Subject: [PATCH 30/39] update README --- README.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 96b902c0..1f937915 100644 --- a/README.md +++ b/README.md @@ -10,27 +10,35 @@ It transforms the data center from a static deployment target into a continuous ### Prerequisites + | Requirement | Details | |-------------|---------------------------------------------------------------------------| | **Docker** | Docker Desktop or a standalone Docker Engine daemon, running. | | **Python** | 3.12 or later. | -| **uv** | [uv](https://docs.astral.sh/uv/) 0.9 or later. | ### Install + ```bash -uv pip install nemoclaw \ - --upgrade \ - --pre \ - --index-url https://urm.nvidia.com/artifactory/api/pypi/nv-shared-pypi/simple +pip install nemoclaw ``` - -The installer places the `nemoclaw` binary in your Python environment. Run it with `uv run nemoclaw`, or activate the virtual environment first (`source .venv/bin/activate`) and invoke `nemoclaw` directly. +### Install from Source (Developer) + +Requires [mise](https://mise.jdx.dev/), Rust 1.88+, Python 3.12+, and Docker. + +```bash +git clone https://github.com/NVIDIA/NemoClaw.git +cd NemoClaw +mise trust +``` + +`mise` installs all remaining toolchain dependencies automatically. The local `nemoclaw` script builds and runs the debug CLI binary, so you can invoke `nemoclaw` directly from the repo. See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the full development workflow. + ### Create a sandbox To install a Openclaw cluster and start a sandbox From 5cacb7519bbdc2f3cf743aa2d5f3f5315e217e13 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Sat, 7 Mar 2026 12:51:23 -0800 Subject: [PATCH 31/39] run edits --- docs/inference/configure-routes.md | 6 +++--- docs/inference/index.md | 10 +++++----- docs/safety-and-privacy/network-access-rules.md | 3 ++- docs/safety-and-privacy/policies.md | 4 ++-- docs/sandboxes/community-sandboxes.md | 2 +- docs/sandboxes/create-and-manage.md | 2 +- docs/sandboxes/index.md | 1 + docs/sandboxes/providers.md | 2 +- 8 files changed, 16 insertions(+), 14 deletions(-) diff --git a/docs/inference/configure-routes.md b/docs/inference/configure-routes.md index b81c6180..a76f904a 100644 --- a/docs/inference/configure-routes.md +++ b/docs/inference/configure-routes.md @@ -5,10 +5,10 @@ # Configure Inference Routes -This guide covers how to create and manage inference routes so that sandboxes can route AI API calls from userland code to policy-controlled backends. You will learn to create routes, connect them to sandboxes via policy, and manage routes across a cluster. +This guide covers how to create and manage inference routes so that sandboxes can route AI API calls from userland code to policy-controlled backends. You will learn to create routes, connect them to sandboxes through policy, and manage routes across a cluster. :::{note} -Inference routes are for *userland code*, which are scripts and programs that the agent writes and executes inside the sandbox. The agent's own API traffic flows directly through network policies, not through inference routing. See {doc}`../safety-and-privacy/network-access-rules` for the distinction between agent traffic and userland traffic. +Inference routes are for *userland code*, which are scripts and programs that the agent writes and executes inside the sandbox. The agent's own API traffic flows directly through network policies, not through inference routing. Refer to {doc}`../safety-and-privacy/network-access-rules` for the distinction between agent traffic and userland traffic. ::: ## Create a Route @@ -23,7 +23,7 @@ $ nemoclaw inference create \ --api-key sk-abc123 ``` -This creates a route named after the routing hint. Any sandbox whose policy includes `local` in its `inference.allowed_routes` list can use this route. If you omit `--protocol`, the CLI probes the endpoint and auto-detects the supported protocol (see [Supported API Patterns](index.md#supported-api-patterns)). See the [CLI Reference](../reference/cli.md#inference-create-flags) for all flags. +This creates a route named after the routing hint. Any sandbox whose policy includes `local` in its `inference.allowed_routes` list can use this route. If you omit `--protocol`, the CLI probes the endpoint and auto-detects the supported protocol (refer to [Supported API Patterns](index.md#supported-api-patterns)). Refer to the [CLI Reference](../reference/cli.md#inference-create-flags) for all flags. ## Manage Routes diff --git a/docs/inference/index.md b/docs/inference/index.md index 04955ce8..435e2cc0 100644 --- a/docs/inference/index.md +++ b/docs/inference/index.md @@ -11,20 +11,20 @@ to backends you control. :::{note} Inference routing applies to userland traffic: code that the agent writes -or runs, not the agent itself. The agent's own API calls (e.g., Claude calling -`api.anthropic.com`) go direct via network policy. See +or runs, not the agent itself. The agent's own API calls (for example, Claude calling +`api.anthropic.com`) go directly through network policy. Refer to {doc}`/safety-and-privacy/network-access-rules` for the distinction. ::: ## How It Works -When userland code inside a sandbox makes an API call (e.g., using the OpenAI +When userland code inside a sandbox makes an API call (for example, using the OpenAI or Anthropic SDK), the request flows through the sandbox proxy. If the destination does not match any explicit network policy but the sandbox has inference routes configured, the proxy: 1. TLS-terminates the connection using the sandbox's ephemeral CA. -2. Detects the inference API pattern (e.g., `POST /v1/chat/completions`). +2. Detects the inference API pattern (for example, `POST /v1/chat/completions`). 3. Strips authorization headers and forwards to a matching backend. 4. Rewrites the authorization with the route's API key and model ID. 5. Returns the response to the agent's code. The agent sees a normal HTTP @@ -79,5 +79,5 @@ If an intercepted request does not match any known pattern, it is denied. ## Next Steps - {doc}`configure-routes`: create and manage inference routes. -- {doc}`/safety-and-privacy/network-access-rules`: understand agent traffic vs. +- {doc}`/safety-and-privacy/network-access-rules`: understand agent traffic compared to userland traffic. diff --git a/docs/safety-and-privacy/network-access-rules.md b/docs/safety-and-privacy/network-access-rules.md index 69afe2cd..3a97a4ef 100644 --- a/docs/safety-and-privacy/network-access-rules.md +++ b/docs/safety-and-privacy/network-access-rules.md @@ -175,7 +175,7 @@ Forward proxy mode is restricted to private IP endpoints that are explicitly allowed by policy. Plain HTTP traffic never reaches the public internet. All three conditions must be true: -1. The OPA policy explicitly allows the destination. +1. The network policy explicitly allows the destination. 2. The matched endpoint has `allowed_ips` configured. 3. All resolved IP addresses are RFC 1918 private (`10/8`, `172.16/12`, `192.168/16`). @@ -287,3 +287,4 @@ network_policies: ## Next Steps - [Write Sandbox Policies](policies.md): The full iterative workflow for authoring, testing, and updating policies. +- {doc}`security-model`: Threat scenarios and how the four protection layers work together. diff --git a/docs/safety-and-privacy/policies.md b/docs/safety-and-privacy/policies.md index c75d8f67..358f2a82 100644 --- a/docs/safety-and-privacy/policies.md +++ b/docs/safety-and-privacy/policies.md @@ -141,8 +141,8 @@ $ nemoclaw logs --tail --source sandbox Each deny entry shows the blocked host, port, calling binary, and reason. This tells you exactly what the agent tried to reach and why it was blocked. Alternatively, run `nemoclaw term` for the NemoClaw Terminal, a live dashboard -that shows status and logs in a single view. See {doc}`/sandboxes/terminal` for -how to read log entries and diagnose what's being blocked. +that shows status and logs in a single view. Refer to {doc}`/sandboxes/terminal` for +how to read log entries and diagnose what is being blocked. :::{tip} The NemoClaw Terminal is especially useful during policy iteration. You can diff --git a/docs/sandboxes/community-sandboxes.md b/docs/sandboxes/community-sandboxes.md index a907ea87..d0bed806 100644 --- a/docs/sandboxes/community-sandboxes.md +++ b/docs/sandboxes/community-sandboxes.md @@ -78,7 +78,7 @@ Optional files: - Startup scripts: Any scripts the Dockerfile or entrypoint invokes To contribute, fork the repository, add your sandbox directory, and open a pull -request. See the repository's +request. Refer to the repository's [CONTRIBUTING.md](https://github.com/NVIDIA/NemoClaw-Community/blob/main/CONTRIBUTING.md) for submission guidelines. diff --git a/docs/sandboxes/create-and-manage.md b/docs/sandboxes/create-and-manage.md index caa7e442..704ec3a2 100644 --- a/docs/sandboxes/create-and-manage.md +++ b/docs/sandboxes/create-and-manage.md @@ -26,7 +26,7 @@ The CLI bootstraps the runtime (if this is your first run), discovers your credentials, applies the default policy, and drops you into the sandbox. You can customize creation with flags like `--name`, `--provider`, `--policy`, -`--upload`, `--keep`, `--forward`, and `--from`. See the +`--upload`, `--keep`, `--forward`, and `--from`. Refer to the [CLI Reference](../reference/cli.md) for the full flag list. A fully specified creation command might look like: diff --git a/docs/sandboxes/index.md b/docs/sandboxes/index.md index 7749caba..8808c159 100644 --- a/docs/sandboxes/index.md +++ b/docs/sandboxes/index.md @@ -47,3 +47,4 @@ with `nemoclaw gateway select `. Refer to the - [Providers](providers.md): Create and attach credential providers. - [Custom Containers](custom-containers.md): Build and run your own container image. - [Community Sandboxes](community-sandboxes.md): Use pre-built sandboxes from the community catalog. +- [Terminal](terminal.md): Monitor sandbox status and live activity in a dashboard. diff --git a/docs/sandboxes/providers.md b/docs/sandboxes/providers.md index dd412724..5ff8383d 100644 --- a/docs/sandboxes/providers.md +++ b/docs/sandboxes/providers.md @@ -146,7 +146,7 @@ The following provider types are supported. |---|---|---| | `claude` | `ANTHROPIC_API_KEY`, `CLAUDE_API_KEY` | Claude Code, Anthropic API | | `codex` | `OPENAI_API_KEY` | OpenAI Codex | -| `OpenCode` | `OPENCODE_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY` | opencode tool | +| `opencode` | `OPENCODE_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY` | opencode tool | | `github` | `GITHUB_TOKEN`, `GH_TOKEN` | GitHub API, `gh` CLI | | `gitlab` | `GITLAB_TOKEN`, `GLAB_TOKEN`, `CI_JOB_TOKEN` | GitLab API, `glab` CLI | | `nvidia` | `NVIDIA_API_KEY` | NVIDIA API Catalog | From 1fbbafe09c9d5c0d45ba07b601b9dcb65eb27f6a Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Mon, 9 Mar 2026 08:55:44 -0700 Subject: [PATCH 32/39] change to the new prod name, text only, code swipe later --- docs/about/architecture.md | 6 +++--- docs/about/overview.md | 14 +++++++------- docs/about/release-notes.md | 4 ++-- docs/conf.py | 2 +- docs/get-started/quickstart.md | 8 ++++---- docs/get-started/run-claude.md | 10 +++++----- docs/get-started/run-openclaw.md | 8 ++++---- docs/get-started/run-opencode.md | 10 +++++----- docs/get-started/tutorials.md | 6 +++--- docs/index.md | 16 ++++++++-------- docs/reference/architecture.md | 4 ++-- docs/reference/cli.md | 6 +++--- docs/reference/policy-schema.md | 2 +- docs/safety-and-privacy/index.md | 2 +- docs/safety-and-privacy/network-access-rules.md | 6 +++--- docs/safety-and-privacy/policies.md | 8 ++++---- docs/safety-and-privacy/security-model.md | 12 ++++++------ docs/sandboxes/community-sandboxes.md | 2 +- docs/sandboxes/create-and-manage.md | 2 +- docs/sandboxes/custom-containers.md | 4 ++-- docs/sandboxes/index.md | 6 +++--- docs/sandboxes/providers.md | 4 ++-- docs/troubleshooting.md | 4 ++-- 23 files changed, 73 insertions(+), 73 deletions(-) diff --git a/docs/about/architecture.md b/docs/about/architecture.md index 9a121ab5..706124d7 100644 --- a/docs/about/architecture.md +++ b/docs/about/architecture.md @@ -2,7 +2,7 @@ title: page: "Architecture Overview" nav: "Architecture" -description: "High-level overview of the NemoClaw architecture: gateway, sandboxes, policy engine, and privacy router." +description: "High-level overview of the OpenShell architecture: gateway, sandboxes, policy engine, and privacy router." keywords: ["nemoclaw architecture", "sandbox architecture", "agent isolation", "k3s", "policy engine"] topics: ["generative_ai", "cybersecurity"] tags: ["ai_agents", "sandboxing", "security", "architecture"] @@ -17,10 +17,10 @@ content: SPDX-License-Identifier: Apache-2.0 --> -# How NemoClaw Works +# How OpenShell Works NemoClaw runs as a [k3s](https://k3s.io/) Kubernetes cluster inside a Docker container. -Each sandbox is an isolated Kubernetes pod managed by the NemoClaw control plane. +Each sandbox is an isolated Kubernetes pod managed by the OpenShell control plane. Four components work together to keep agents secure. ```{mermaid} diff --git a/docs/about/overview.md b/docs/about/overview.md index 4a7648d2..30040d94 100644 --- a/docs/about/overview.md +++ b/docs/about/overview.md @@ -1,6 +1,6 @@ --- title: - page: "Overview of NVIDIA NemoClaw" + page: "Overview of NVIDIA OpenShell" nav: "Overview" description: "NemoClaw is the safe, private runtime for autonomous AI agents. Run agents in sandboxed environments that protect your data, credentials, and infrastructure." keywords: ["nemoclaw", "ai agent sandbox", "agent security", "agent isolation", "inference routing"] @@ -17,9 +17,9 @@ content: SPDX-License-Identifier: Apache-2.0 --> -# Overview of NVIDIA NemoClaw +# Overview of NVIDIA OpenShell -NVIDIA NemoClaw is an open-source runtime that executes autonomous AI agents inside sandboxed environments with kernel-level isolation. It prevents agents from accessing unauthorized files, exfiltrating data, leaking credentials, or making uncontrolled network requests. A single declarative YAML policy governs filesystem, network, process, and inference protections across all sandboxes and is hot-reloadable without restarting running agents. +NVIDIA OpenShell is an open-source runtime that executes autonomous AI agents inside sandboxed environments with kernel-level isolation. It prevents agents from accessing unauthorized files, exfiltrating data, leaking credentials, or making uncontrolled network requests. A single declarative YAML policy governs filesystem, network, process, and inference protections across all sandboxes and is hot-reloadable without restarting running agents. ## Common Challenges with AI Agents @@ -27,7 +27,7 @@ AI agents are most useful when they have broad access to reading files, installi Conventional containers do not solve this. They isolate processes from the host, but they do not control what an agent does *inside* the container — which files it reads, which hosts it contacts, or where it sends your prompts. -## Benefits of Using NemoClaw +## Benefits of Using OpenShell NemoClaw addresses these risks through defense-in-depth enforcement across four policy domains: filesystem, network, process, and inference. @@ -53,7 +53,7 @@ Every outbound TCP connection from a sandbox passes through an L7 proxy that res ## Use Cases -The following are common use cases for NemoClaw. +The following are common use cases for OpenShell. :::{dropdown} 💻 Secure Coding Agents Run AI coding assistants such as Claude Code, OpenCode, or OpenClaw inside a sandbox where they can read and modify project files but cannot access SSH keys, cloud credentials, or files outside the project directory. Network policies restrict which package registries and APIs the agent can reach. @@ -75,6 +75,6 @@ Use pre-built sandbox images from the [NemoClaw Community](https://github.com/NV ## Next Steps -- [Architecture Overview](architecture.md): Understand the components that make up the NemoClaw runtime. +- [Architecture Overview](architecture.md): Understand the components that make up the OpenShell runtime. - [Get Started](../index.md): Install the CLI and create your first sandbox. -- [Security Model](../safety-and-privacy/security-model.md): Learn how NemoClaw enforces isolation across all protection layers. +- [Security Model](../safety-and-privacy/security-model.md): Learn how OpenShell enforces isolation across all protection layers. diff --git a/docs/about/release-notes.md b/docs/about/release-notes.md index 92d87ffa..f85907c4 100644 --- a/docs/about/release-notes.md +++ b/docs/about/release-notes.md @@ -5,9 +5,9 @@ # Release Notes -This page covers the highlights of each NemoClaw release. +This page covers the highlights of each OpenShell release. For more details, refer to the [NemoClaw GitHub Releases](https://github.com/NVIDIA/NemoClaw/releases). ## 0.1.0 -This is the first release of NVIDIA NemoClaw. It introduces sandboxed AI agent execution with kernel-level isolation, policy enforcement, and credential management. +This is the first release of NVIDIA OpenShell. It introduces sandboxed AI agent execution with kernel-level isolation, policy enforcement, and credential management. diff --git a/docs/conf.py b/docs/conf.py index ec5069ff..9ade62e9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -7,7 +7,7 @@ sys.path.insert(0, str(Path(__file__).parent.parent)) -project = "NVIDIA NemoClaw Developer Guide" +project = "NVIDIA OpenShell Developer Guide" this_year = date.today().year copyright = f"2025-{this_year}, NVIDIA Corporation" author = "NVIDIA Corporation" diff --git a/docs/get-started/quickstart.md b/docs/get-started/quickstart.md index 1a2f21ec..238a0a6e 100644 --- a/docs/get-started/quickstart.md +++ b/docs/get-started/quickstart.md @@ -2,7 +2,7 @@ title: page: "Quickstart" nav: "Quickstart" -description: "Install the NemoClaw CLI and create your first sandboxed AI agent in two commands." +description: "Install the OpenShell CLI and create your first sandboxed AI agent in two commands." keywords: ["nemoclaw install", "quickstart", "sandbox create", "getting started"] topics: ["generative_ai", "cybersecurity"] tags: ["ai_agents", "sandboxing", "installation", "quickstart"] @@ -30,14 +30,14 @@ Before you begin, make sure you have: :end-before: ``` -## Install the NemoClaw CLI +## Install the OpenShell CLI ```{include} ../../README.md :start-after: :end-before: ``` -## Create Your First NemoClaw Sandbox +## Create Your First OpenShell Sandbox Choose the tab that matches your agent: @@ -72,7 +72,7 @@ The `--from` flag pulls a pre-built sandbox definition from the [NemoClaw Commun ## What Happens Behind the Scenes -When you create a sandbox, NemoClaw activates the following protection layers. +When you create a sandbox, OpenShell activates the following protection layers. | Protection Layer | Description | |------------------------|-----------------------------------------------------------------------------------------------| diff --git a/docs/get-started/run-claude.md b/docs/get-started/run-claude.md index 50eee948..d09a2371 100644 --- a/docs/get-started/run-claude.md +++ b/docs/get-started/run-claude.md @@ -5,18 +5,18 @@ # Run Claude Code Safely -This tutorial walks you through the path to running Claude Code inside a NemoClaw sandbox. By the end of this tutorial, you will have an isolated environment with credentials securely injected and a default policy controlling what the agent can access. +This tutorial walks you through the path to running Claude Code inside a OpenShell sandbox. By the end of this tutorial, you will have an isolated environment with credentials securely injected and a default policy controlling what the agent can access. ## What You Will Learn - Create a sandbox with a single command. -- Understand how NemoClaw auto-discovers provider credentials. +- Understand how OpenShell auto-discovers provider credentials. - Inspect what the default policy allows and denies. - Connect to a running sandbox and work inside it. ## Prerequisites -- Met the prerequisites and installed the NemoClaw CLI as described in the {doc}`quickstart` guide. +- Met the prerequisites and installed the OpenShell CLI as described in the {doc}`quickstart` guide. - `ANTHROPIC_API_KEY` environment variable set on your host machine. ## Create the Sandbox @@ -29,7 +29,7 @@ $ nemoclaw sandbox create -- claude This single command performs four actions: -1. Bootstraps the runtime. On first use, the CLI provisions a local k3s cluster inside Docker and deploys the NemoClaw control plane. This happens once. Subsequent commands reuse the existing cluster. +1. Bootstraps the runtime. On first use, the CLI provisions a local k3s cluster inside Docker and deploys the OpenShell control plane. This happens once. Subsequent commands reuse the existing cluster. 2. Auto-discovers credentials. The CLI detects that `claude` is a recognized tool and reads the `ANTHROPIC_API_KEY` environment variable from your shell. It creates a provider automatically. 3. Creates the sandbox. The CLI provisions an isolated container and applies the default policy. This policy allows Claude Code to reach `api.anthropic.com` and a small set of supporting endpoints while blocking everything else. 4. Drops you into the sandbox. You land in an interactive SSH session, ready to work. @@ -65,7 +65,7 @@ Open a second terminal on your host machine to inspect the sandbox from outside. $ nemoclaw sandbox list ``` -2. Launch the NemoClaw Terminal for a live dashboard that shows sandbox status, active network connections, and policy decisions in real time: +2. Launch the OpenShell Terminal for a live dashboard that shows sandbox status, active network connections, and policy decisions in real time: ```console $ nemoclaw term diff --git a/docs/get-started/run-openclaw.md b/docs/get-started/run-openclaw.md index db098e43..97b50a34 100644 --- a/docs/get-started/run-openclaw.md +++ b/docs/get-started/run-openclaw.md @@ -15,7 +15,7 @@ This tutorial shows you how to launch a sandbox with OpenClaw from the [NemoClaw ## Prerequisites -- Met the prerequisites and installed the NemoClaw CLI as described in the {doc}`quickstart` guide. +- Met the prerequisites and installed the OpenShell CLI as described in the {doc}`quickstart` guide. - NVIDIA GPU with drivers installed. OpenClaw requires GPU acceleration. ## Create the Sandbox @@ -26,9 +26,9 @@ Run the following command: $ nemoclaw sandbox create --from openclaw --keep ``` -The `--from` flag tells the CLI to pull a sandbox definition from the NemoClaw Community catalog. Here is what happens behind the scenes: +The `--from` flag tells the CLI to pull a sandbox definition from the OpenShell Community catalog. Here is what happens behind the scenes: -1. Fetches the definition. The CLI downloads the OpenClaw sandbox definition from the NemoClaw-Community repository. This includes a Dockerfile, a policy YAML, and any bundled skills. +1. Fetches the definition. The CLI downloads the OpenClaw sandbox definition from the OpenShell-Community repository. This includes a Dockerfile, a policy YAML, and any bundled skills. 2. Builds the image. The CLI builds the Dockerfile locally using Docker. The resulting image includes all tools and dependencies that OpenClaw needs. 3. Applies the bundled policy. Instead of the generic default policy, the sandbox starts with a policy written specifically for the OpenClaw workload. It allows the endpoints and binaries that OpenClaw requires. 4. Creates and keeps the sandbox. The `--keep` flag ensures the sandbox stays running after creation so you can connect and disconnect freely. @@ -91,7 +91,7 @@ $ nemoclaw sandbox delete ``` :::{note} -The NemoClaw Community repository accepts contributions. If you build a sandbox configuration that would be useful to others, submit it to the [NemoClaw-Community](https://github.com/NVIDIA/NemoClaw-Community) repository. +The OpenShell Community repository accepts contributions. If you build a sandbox configuration that would be useful to others, submit it to the [NemoClaw-Community](https://github.com/NVIDIA/NemoClaw-Community) repository. ::: ## Next Steps diff --git a/docs/get-started/run-opencode.md b/docs/get-started/run-opencode.md index e22338fe..00a85bb9 100644 --- a/docs/get-started/run-opencode.md +++ b/docs/get-started/run-opencode.md @@ -5,7 +5,7 @@ # Run OpenCode with NVIDIA Inference -This tutorial walks you through a realistic setup where you run [OpenCode](https://opencode.ai) inside a NemoClaw sandbox with inference routed to NVIDIA API endpoints. Along the way, you will hit a policy denial, diagnose it from logs, write a custom policy, and configure inference routing. This is the full policy iteration loop that you will use whenever you onboard a new tool. +This tutorial walks you through a realistic setup where you run [OpenCode](https://opencode.ai) inside a OpenShell sandbox with inference routed to NVIDIA API endpoints. Along the way, you will hit a policy denial, diagnose it from logs, write a custom policy, and configure inference routing. This is the full policy iteration loop that you will use whenever you onboard a new tool. ## What You Will Learn @@ -17,7 +17,7 @@ This tutorial walks you through a realistic setup where you run [OpenCode](https ## Prerequisites -- Met the prerequisites and installed the NemoClaw CLI as described in the {doc}`quickstart` guide. +- Met the prerequisites and installed the OpenShell CLI as described in the {doc}`quickstart` guide. - `NVIDIA_API_KEY` environment variable set on your host machine with a valid NVIDIA API key. ## Create the Provider @@ -56,7 +56,7 @@ Open a second terminal and check the logs: $ nemoclaw logs opencode-sandbox --tail ``` -Alternatively, launch the NemoClaw Terminal for a live view: +Alternatively, launch the OpenShell Terminal for a live view: ```console $ nemoclaw term @@ -81,7 +81,7 @@ Two separate problems are at play: - OpenCode's own traffic. OpenCode contacts `opencode.ai` for its API and `integrate.api.nvidia.com` for inference. Neither endpoint has a matching rule for the binaries OpenCode uses. - Missing endpoint. The default policy has no entry for `opencode.ai` at all. Even if the binary matched, the destination is not listed. -This is expected behavior. NemoClaw denies everything by default. You need to write a policy that explicitly allows what OpenCode needs. +This is expected behavior. OpenShell denies everything by default. You need to write a policy that explicitly allows what OpenCode needs. ## Write a Custom Policy @@ -239,7 +239,7 @@ $ nemoclaw logs opencode-sandbox --tail You should no longer see `action=deny` lines for the endpoints you added. Connections to `opencode.ai`, `integrate.api.nvidia.com`, and GitHub should show `action=allow`. -If you still see denials, read the log line carefully. It tells you the exact host, port, and binary that was blocked. Add the missing entry to your policy and push again with `nemoclaw policy set`. This observe-modify-push cycle is the normal workflow for onboarding any new tool in NemoClaw. +If you still see denials, read the log line carefully. It tells you the exact host, port, and binary that was blocked. Add the missing entry to your policy and push again with `nemoclaw policy set`. This observe-modify-push cycle is the normal workflow for onboarding any new tool in OpenShell. ## Clean Up diff --git a/docs/get-started/tutorials.md b/docs/get-started/tutorials.md index 7c9295dd..c95cae8a 100644 --- a/docs/get-started/tutorials.md +++ b/docs/get-started/tutorials.md @@ -2,7 +2,7 @@ title: page: "NemoClaw Tutorials" nav: "Tutorials" -description: "Step-by-step tutorials for running AI agents inside NemoClaw sandboxes." +description: "Step-by-step tutorials for running AI agents inside OpenShell sandboxes." keywords: ["nemoclaw tutorials", "claude code sandbox", "opencode sandbox", "openclaw sandbox"] topics: ["generative_ai", "cybersecurity"] tags: ["ai_agents", "sandboxing", "tutorial"] @@ -19,7 +19,7 @@ content: # Tutorials -Each tutorial below walks you through running a specific AI agent inside a NemoClaw sandbox. Choose the tutorial that matches your agent. +Each tutorial below walks you through running a specific AI agent inside a OpenShell sandbox. Choose the tutorial that matches your agent. ::::{grid} 1 1 2 2 :gutter: 3 @@ -38,7 +38,7 @@ Create a sandbox with Claude Code. :link: run-openclaw :link-type: doc -Launch a sandbox with OpenClaw from the NemoClaw Community catalog using the `--from` flag. +Launch a sandbox with OpenClaw from the OpenShell Community catalog using the `--from` flag. +++ {bdg-secondary}`Tutorial` diff --git a/docs/index.md b/docs/index.md index 29779a4f..3e557898 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,9 +1,9 @@ --- title: - page: "NVIDIA NemoClaw Developer Guide" + page: "NVIDIA OpenShell Developer Guide" nav: "Get Started" - card: "NVIDIA NemoClaw" -description: "NemoClaw is the safe, private runtime for autonomous AI agents. Run agents in sandboxed environments that protect your data, credentials, and infrastructure." + card: "NVIDIA OpenShell" +description: "OpenShell is the safe, private runtime for autonomous AI agents. Run agents in sandboxed environments that protect your data, credentials, and infrastructure." topics: - Generative AI - Cybersecurity @@ -22,13 +22,13 @@ content: SPDX-License-Identifier: Apache-2.0 --> -# NVIDIA NemoClaw +# NVIDIA OpenShell [![GitHub](https://img.shields.io/badge/github-repo-green?logo=github)](https://github.com/NVIDIA/NemoClaw) [![License](https://img.shields.io/badge/License-Apache_2.0-blue)](https://github.com/NVIDIA/NemoClaw/blob/main/LICENSE) [![PyPI](https://img.shields.io/badge/PyPI-nemoclaw-orange?logo=pypi)](https://pypi.org/project/nemoclaw/) -NemoClaw is the safe, private runtime for autonomous AI agents. It provides sandboxed execution environments +OpenShell is the safe, private runtime for autonomous AI agents. It provides sandboxed execution environments that protect your data, credentials, and infrastructure. Agents run with exactly the permissions they need and nothing more, governed by declarative policies that prevent unauthorized file access, data exfiltration, and uncontrolled network activity. @@ -112,11 +112,11 @@ Refer to the [Quickstart](get-started/quickstart.md) for more details. ::::{grid} 2 2 3 3 :gutter: 3 -:::{grid-item-card} About NemoClaw +:::{grid-item-card} About OpenShell :link: about/overview :link-type: doc -Learn about NemoClaw and its capabilities. +Learn about OpenShell and its capabilities. +++ {bdg-secondary}`Concept` @@ -126,7 +126,7 @@ Learn about NemoClaw and its capabilities. :link: get-started/quickstart :link-type: doc -Quickstart guide and tutorials for creating a NemoClaw sandbox with Claude Code, OpenClaw, and OpenCode. +Quickstart guide and tutorials for creating a OpenShell sandbox with Claude Code, OpenClaw, and OpenCode. +++ {bdg-secondary}`Tutorial` diff --git a/docs/reference/architecture.md b/docs/reference/architecture.md index d1f4bfa3..d36af1d0 100644 --- a/docs/reference/architecture.md +++ b/docs/reference/architecture.md @@ -2,7 +2,7 @@ title: page: "Architecture Reference" nav: "Architecture" -description: "Detailed reference for NemoClaw architecture: gateway, sandbox internals, policy engine, privacy router, and remote deployment." +description: "Detailed reference for OpenShell architecture: gateway, sandbox internals, policy engine, privacy router, and remote deployment." keywords: ["nemoclaw architecture", "sandbox architecture", "agent isolation", "k3s", "policy engine"] topics: ["generative_ai", "cybersecurity"] tags: ["ai_agents", "sandboxing", "security", "architecture"] @@ -19,7 +19,7 @@ content: # Architecture Reference -This page provides detailed technical information about each NemoClaw component. +This page provides detailed technical information about each OpenShell component. For a high-level summary, refer to the [Architecture Overview](../about/architecture.md). ## Component Diagram diff --git a/docs/reference/cli.md b/docs/reference/cli.md index febd5e26..9856ee5f 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -69,7 +69,7 @@ Commands available directly under `nemoclaw` for common operations. ## Gateway Commands -Manage the NemoClaw runtime cluster. +Manage the OpenShell runtime cluster. | Command | Description | |---|---| @@ -153,9 +153,9 @@ Manage inference routes that intercept and reroute LLM API calls from userland c | `--protocol` | API protocol: `openai` or `anthropic`. Defaults to `openai`. | | `--disabled` | Create the route in a disabled state. | -## NemoClaw Terminal +## OpenShell Terminal -`nemoclaw term` launches the NemoClaw Terminal, a dashboard that shows sandbox +`nemoclaw term` launches the OpenShell Terminal, a dashboard that shows sandbox status, live logs, and policy decisions in a single view. Navigate with `j`/`k`, press `f` to follow live output, `s` to filter by source, and `q` to quit. diff --git a/docs/reference/policy-schema.md b/docs/reference/policy-schema.md index c48d35f4..033d1b09 100644 --- a/docs/reference/policy-schema.md +++ b/docs/reference/policy-schema.md @@ -82,7 +82,7 @@ Configures [Landlock LSM](https://docs.kernel.org/security/landlock.html) enforc | Field | Type | Required | Values | Description | |---|---|---|---|---| -| `compatibility` | string | No | `best_effort`, `hard_requirement` | How NemoClaw handles kernel ABI differences. `best_effort` uses the highest Landlock ABI the host kernel supports. `hard_requirement` fails if the required ABI is unavailable. | +| `compatibility` | string | No | `best_effort`, `hard_requirement` | How OpenShell handles kernel ABI differences. `best_effort` uses the highest Landlock ABI the host kernel supports. `hard_requirement` fails if the required ABI is unavailable. | Example: diff --git a/docs/safety-and-privacy/index.md b/docs/safety-and-privacy/index.md index 4ace7aac..afb26fe2 100644 --- a/docs/safety-and-privacy/index.md +++ b/docs/safety-and-privacy/index.md @@ -53,7 +53,7 @@ rules are hot-reloadable on a running sandbox. Filesystem and process restrictions are locked at creation time. - {doc}`security-model`: Threat scenarios (data exfiltration, credential - theft, unauthorized API calls, privilege escalation) and how NemoClaw + theft, unauthorized API calls, privilege escalation) and how OpenShell addresses each one. - {doc}`policies`: Author policies, monitor for blocked actions, and iterate on rules without restarting sandboxes. diff --git a/docs/safety-and-privacy/network-access-rules.md b/docs/safety-and-privacy/network-access-rules.md index 3a97a4ef..4ef9bd65 100644 --- a/docs/safety-and-privacy/network-access-rules.md +++ b/docs/safety-and-privacy/network-access-rules.md @@ -5,7 +5,7 @@ # Network Access Rules -Every outbound connection from a sandbox passes through NemoClaw's transparent +Every outbound connection from a sandbox passes through OpenShell's transparent proxy. Nothing leaves the sandbox directly. The proxy identifies which binary initiated the connection, evaluates the active policy, and decides what happens next. @@ -21,7 +21,7 @@ Each outbound connection resolves to one of three outcomes: | Deny | No network policy matches and no inference route applies. | The connection is blocked. The calling process receives a 403 or connection reset. | :::{note} -This is the most important distinction in NemoClaw's network model. +This is the most important distinction in OpenShell's network model. *Agent traffic* is the coding agent (Claude, OpenCode, Codex) calling its own API to get completions. This traffic matches a `network_policies` entry because the policy declares both the endpoint (for example, `api.anthropic.com:443`) and the binary (for example, `/usr/local/bin/claude`). The proxy allows it through directly. The agent's own API key (injected by the provider) is used as-is. @@ -72,7 +72,7 @@ network_policies: - path: /usr/local/bin/my-agent ``` -The key (`my_rule`) is a logical name for reference. The `name` field is the human-readable label that appears in logs and the NemoClaw Terminal. +The key (`my_rule`) is a logical name for reference. The `name` field is the human-readable label that appears in logs and the OpenShell Terminal. ## Endpoints diff --git a/docs/safety-and-privacy/policies.md b/docs/safety-and-privacy/policies.md index 358f2a82..375e47d6 100644 --- a/docs/safety-and-privacy/policies.md +++ b/docs/safety-and-privacy/policies.md @@ -5,7 +5,7 @@ # Write Sandbox Policies -This guide covers how to author, iterate, and manage sandbox policies that control what an agent can do inside a NemoClaw sandbox. You will learn to create sandboxes with custom policies, monitor denied traffic to discover missing rules, and push policy updates without restarting the sandbox. +This guide covers how to author, iterate, and manage sandbox policies that control what an agent can do inside a OpenShell sandbox. You will learn to create sandboxes with custom policies, monitor denied traffic to discover missing rules, and push policy updates without restarting the sandbox. ## Policy Structure @@ -32,7 +32,7 @@ filesystem_policy: - /dev/null landlock: - # How NemoClaw applies Landlock LSM enforcement. + # How OpenShell applies Landlock LSM enforcement. # "best_effort" uses the highest Landlock ABI the host kernel supports. # "strict" requires a specific ABI version and fails if unavailable. compatibility: best_effort @@ -140,12 +140,12 @@ $ nemoclaw logs --tail --source sandbox Each deny entry shows the blocked host, port, calling binary, and reason. This tells you exactly what the agent tried to reach and why it was blocked. -Alternatively, run `nemoclaw term` for the NemoClaw Terminal, a live dashboard +Alternatively, run `nemoclaw term` for the OpenShell Terminal, a live dashboard that shows status and logs in a single view. Refer to {doc}`/sandboxes/terminal` for how to read log entries and diagnose what is being blocked. :::{tip} -The NemoClaw Terminal is especially useful during policy iteration. You can +The OpenShell Terminal is especially useful during policy iteration. You can watch deny entries appear in real time as the agent hits blocked endpoints, then push an updated policy without leaving the terminal. ::: diff --git a/docs/safety-and-privacy/security-model.md b/docs/safety-and-privacy/security-model.md index 3fd68b74..5be80237 100644 --- a/docs/safety-and-privacy/security-model.md +++ b/docs/safety-and-privacy/security-model.md @@ -7,7 +7,7 @@ When an AI agent runs with unrestricted access to your system, it can read any file, reach any network host, call any API with your credentials, and install -arbitrary software. NemoClaw's security model exists to prevent all of that. +arbitrary software. OpenShell's security model exists to prevent all of that. :::{note} NemoClaw uses defense in depth. Four independent protection layers: filesystem, @@ -18,7 +18,7 @@ failure can compromise your environment. ## What Happens Without Protection Autonomous agents are powerful, but power without boundaries is risk. Here are -four concrete threat scenarios and how NemoClaw addresses each one. +four concrete threat scenarios and how OpenShell addresses each one. ### Data Exfiltration @@ -26,7 +26,7 @@ four concrete threat scenarios and how NemoClaw addresses each one. The agent writes a script that reads your source code and uploads it to an external server using `curl`. -**With NemoClaw:** +**With OpenShell:** The network policy blocks all outbound connections except to hosts you have explicitly approved. The `curl` command to an unapproved destination is denied at the proxy before the request ever leaves the sandbox. @@ -39,7 +39,7 @@ at the proxy before the request ever leaves the sandbox. The agent reads `~/.ssh/id_rsa`, `~/.aws/credentials`, or other sensitive files from your home directory and exfiltrates them. -**With NemoClaw:** +**With OpenShell:** Landlock filesystem restrictions limit the agent to declared paths. The agent can access `/sandbox`, `/tmp`, and read-only system directories, but not your home directory, SSH keys, cloud credentials, or anything else outside the @@ -53,7 +53,7 @@ policy. The agent code calls `api.openai.com` with your API key, sending proprietary data to a third-party inference provider you did not approve. -**With NemoClaw:** +**With OpenShell:** The privacy router intercepts outbound API calls and reroutes them to a backend you control: a local model, an NVIDIA endpoint, or your own deployment. The agent's code does not need to change; the rerouting is @@ -67,7 +67,7 @@ transparent. Your data never reaches an unauthorized provider. The agent runs `sudo apt install` to install packages, modifies `/etc/passwd`, or uses raw sockets to scan your internal network. -**With NemoClaw:** +**With OpenShell:** The agent runs as an unprivileged user with seccomp filters that block dangerous system calls. Landlock prevents writes outside allowed paths. There is no `sudo`, no `setuid`, and no path to elevated privileges. diff --git a/docs/sandboxes/community-sandboxes.md b/docs/sandboxes/community-sandboxes.md index d0bed806..f176abdf 100644 --- a/docs/sandboxes/community-sandboxes.md +++ b/docs/sandboxes/community-sandboxes.md @@ -5,7 +5,7 @@ # Community Sandboxes -Use pre-built sandboxes from the NemoClaw Community catalog, or contribute your +Use pre-built sandboxes from the OpenShell Community catalog, or contribute your own. ## What Are Community Sandboxes diff --git a/docs/sandboxes/create-and-manage.md b/docs/sandboxes/create-and-manage.md index 704ec3a2..f9653d1b 100644 --- a/docs/sandboxes/create-and-manage.md +++ b/docs/sandboxes/create-and-manage.md @@ -11,7 +11,7 @@ This page walks you through the full sandbox lifecycle: creating, inspecting, co Ensure the following are installed before creating sandboxes. -- NemoClaw CLI installed (`pip install nemoclaw`) +- OpenShell CLI installed (`pip install nemoclaw`) - Docker running on your machine ## Create a Sandbox diff --git a/docs/sandboxes/custom-containers.md b/docs/sandboxes/custom-containers.md index a5b3a94d..6eb1583a 100644 --- a/docs/sandboxes/custom-containers.md +++ b/docs/sandboxes/custom-containers.md @@ -5,13 +5,13 @@ # Custom Containers -Build a custom container image and run it as a NemoClaw sandbox. +Build a custom container image and run it as a OpenShell sandbox. ## Prerequisites Ensure the following are installed before building custom container sandboxes. -- NemoClaw CLI installed (`pip install nemoclaw`) +- OpenShell CLI installed (`pip install nemoclaw`) - Docker running on your machine - A Dockerfile for your workload diff --git a/docs/sandboxes/index.md b/docs/sandboxes/index.md index 8808c159..ce1945c6 100644 --- a/docs/sandboxes/index.md +++ b/docs/sandboxes/index.md @@ -5,7 +5,7 @@ # About Sandboxes -A NemoClaw sandbox is a safe, private execution environment for an AI agent. Each sandbox runs inside a Kubernetes pod with multiple layers of protection that prevent unauthorized data access, credential exposure, and network exfiltration. Protection layers include filesystem restrictions (Landlock), system call filtering (seccomp), network namespace isolation, and a privacy-enforcing HTTP CONNECT proxy. +A OpenShell sandbox is a safe, private execution environment for an AI agent. Each sandbox runs inside a Kubernetes pod with multiple layers of protection that prevent unauthorized data access, credential exposure, and network exfiltration. Protection layers include filesystem restrictions (Landlock), system call filtering (seccomp), network namespace isolation, and a privacy-enforcing HTTP CONNECT proxy. ## Sandbox Lifecycle @@ -18,9 +18,9 @@ Every sandbox moves through a defined set of phases: | Error | Something went wrong during provisioning or execution. Check logs with `nemoclaw logs` for details. | | Deleting | The sandbox is being torn down. The system releases resources and purges credentials. | -## The NemoClaw Runtime +## The OpenShell Runtime -Sandboxes run inside a lightweight runtime cluster that NemoClaw manages for +Sandboxes run inside a lightweight runtime cluster that OpenShell manages for you. The cluster runs as a [k3s](https://k3s.io/) Kubernetes distribution inside a Docker container on your machine. diff --git a/docs/sandboxes/providers.md b/docs/sandboxes/providers.md index 5ff8383d..1dc7d26f 100644 --- a/docs/sandboxes/providers.md +++ b/docs/sandboxes/providers.md @@ -5,7 +5,7 @@ # Providers -AI agents typically need credentials to access external services: an API key for the AI model provider, a token for GitHub or GitLab, and so on. NemoClaw manages these credentials as first-class entities called *providers*. +AI agents typically need credentials to access external services: an API key for the AI model provider, a token for GitHub or GitLab, and so on. OpenShell manages these credentials as first-class entities called *providers*. Create and manage providers that supply credentials to sandboxes. @@ -127,7 +127,7 @@ flowchart LR 2. You attach the provider to a sandbox at creation time using the `--provider` flag (one or more providers can be attached). 3. The sandbox starts. The supervisor process initializes. -4. The supervisor fetches credentials from the NemoClaw gateway at runtime. +4. The supervisor fetches credentials from the OpenShell gateway at runtime. The system does not store credentials in the sandbox specification. It retrieves them on demand. 5. Credentials are injected into the agent process as environment variables. They are also available in SSH sessions when you connect to the sandbox. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index ffbbfcbb..85afd743 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -5,11 +5,11 @@ # Troubleshooting -Use this guide to troubleshoot problems with NemoClaw. +Use this guide to troubleshoot problems with OpenShell. ## Cluster Issues -Troubleshoot problems with deploying, connecting to, and running NemoClaw clusters. +Troubleshoot problems with deploying, connecting to, and running OpenShell clusters. ### Cluster Deploy Fails From 470be2d69f684e8c6e659d6113cd6747c0596d99 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Mon, 9 Mar 2026 09:33:29 -0700 Subject: [PATCH 33/39] add Home --- docs/index.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/index.md b/docs/index.md index 3e557898..12c9b0d7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -174,6 +174,12 @@ CLI commands, policy schema, environment variables, and system architecture. :::: +```{toctree} +:hidden: + +Home +``` + ```{toctree} :caption: About :hidden: From bb16efbd204c4dc35b80ac28c56c9266a59e4f2b Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Mon, 9 Mar 2026 10:48:32 -0700 Subject: [PATCH 34/39] incorporate dev feedback on README --- README.md | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1f937915..4bfca683 100644 --- a/README.md +++ b/README.md @@ -23,21 +23,16 @@ It transforms the data center from a static deployment target into a continuous ```bash -pip install nemoclaw +uv pip install nemoclaw \ + --upgrade \ + --pre \ + --index-url https://urm.nvidia.com/artifactory/api/pypi/nv-shared-pypi/simple ``` ### Install from Source (Developer) -Requires [mise](https://mise.jdx.dev/), Rust 1.88+, Python 3.12+, and Docker. - -```bash -git clone https://github.com/NVIDIA/NemoClaw.git -cd NemoClaw -mise trust -``` - -`mise` installs all remaining toolchain dependencies automatically. The local `nemoclaw` script builds and runs the debug CLI binary, so you can invoke `nemoclaw` directly from the repo. See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the full development workflow. +Refer to [`CONTRIBUTING.md`](CONTRIBUTING.md) for the full development workflow and installation instructions. ### Create a sandbox From acd98bb3fd7204f836d4396736e723326a2f6223 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Mon, 9 Mar 2026 10:51:26 -0700 Subject: [PATCH 35/39] krit's edits --- docs/safety-and-privacy/index.md | 9 +- docs/safety-and-privacy/policies.md | 275 ++++++++++------------ docs/safety-and-privacy/security-model.md | 9 +- 3 files changed, 125 insertions(+), 168 deletions(-) diff --git a/docs/safety-and-privacy/index.md b/docs/safety-and-privacy/index.md index afb26fe2..32448a55 100644 --- a/docs/safety-and-privacy/index.md +++ b/docs/safety-and-privacy/index.md @@ -5,13 +5,13 @@ # About Safety and Privacy -NemoClaw wraps every sandbox in four independent protection layers. No single +OpenShell wraps every sandbox in four independent protection layers. No single point of failure can compromise your environment. Each layer covers gaps the others cannot. ```{mermaid} graph TB - subgraph runtime["NemoClaw Runtime"] + subgraph runtime["OpenShell Runtime"] direction TB subgraph layers["Protection Layers"] @@ -55,7 +55,4 @@ restrictions are locked at creation time. - {doc}`security-model`: Threat scenarios (data exfiltration, credential theft, unauthorized API calls, privilege escalation) and how OpenShell addresses each one. -- {doc}`policies`: Author policies, monitor for blocked actions, and - iterate on rules without restarting sandboxes. -- {doc}`network-access-rules`: Configure endpoint rules, binary matching, - L7 inspection, and access presets. +- {doc}`policies`: What a policy is, how it's evaluated, its structure, how to edit it, network access rules (including the GitHub push example), and the iteration workflow. diff --git a/docs/safety-and-privacy/policies.md b/docs/safety-and-privacy/policies.md index 375e47d6..d98f7b79 100644 --- a/docs/safety-and-privacy/policies.md +++ b/docs/safety-and-privacy/policies.md @@ -7,70 +7,119 @@ This guide covers how to author, iterate, and manage sandbox policies that control what an agent can do inside a OpenShell sandbox. You will learn to create sandboxes with custom policies, monitor denied traffic to discover missing rules, and push policy updates without restarting the sandbox. -## Policy Structure +## What is a policy -A policy is a YAML document with five sections. Static fields (`filesystem_policy`, `landlock`, `process`) are locked at sandbox creation and require recreation to change. Dynamic fields (`network_policies`, `inference`) are hot-reloadable on a running sandbox. +A policy is a single YAML document that controls what a sandbox can do: filesystem access, process identity, network access, and inference routing. You attach it when creating a sandbox; the network and inference parts can be updated on a running sandbox without restarting. OpenShell's four protection layers (filesystem, network, process, inference) are all configured through this one policy. + +## How is it evaluated + +For **network** traffic, the proxy matches destination (host and port) and calling binary to a policy block and optionally applies per-endpoint rules; see [Network access rules](#network-access-rules) below. For filesystem and process, the policy is applied at sandbox start (and for static fields, at creation only). For the full endpoint schema and binary matching, see the [Policy Schema Reference](../reference/policy-schema.md). + +## How is it structured + +A policy is a YAML document with five top-level sections: `version`, `filesystem_policy`, `landlock`, `process`, `network_policies`, and `inference`. Static fields (`filesystem_policy`, `landlock`, `process`) are locked at sandbox creation and require recreation to change. Dynamic fields (`network_policies`, `inference`) are hot-reloadable on a running sandbox. The `landlock` section configures [Landlock LSM](https://docs.kernel.org/security/landlock.html) enforcement at the kernel level. ```yaml version: 1 -# --- STATIC FIELDS (require sandbox recreation to change) --- - +# Static: locked at sandbox creation. Paths the agent can read vs read/write. filesystem_policy: - # Directories the agent can read but not modify. - read_only: - - /usr - - /lib - - /proc - - /dev/urandom - - /etc - - /var/log - # Directories the agent can read and write. - read_write: - - /sandbox # the agent's working directory - - /tmp - - /dev/null + read_only: [/usr, /lib, /etc] + read_write: [/sandbox, /tmp] +# Static: Landlock LSM kernel enforcement. best_effort uses highest ABI the host supports. landlock: - # How OpenShell applies Landlock LSM enforcement. - # "best_effort" uses the highest Landlock ABI the host kernel supports. - # "strict" requires a specific ABI version and fails if unavailable. compatibility: best_effort +# Static: Unprivileged user/group the agent process runs as. process: - # The OS user and group the agent process runs as inside the sandbox. - # "sandbox" is a non-root user created in the container image. run_as_user: sandbox run_as_group: sandbox -# --- DYNAMIC FIELDS (hot-reloadable on a running sandbox) --- - +# Dynamic: hot-reloadable. Named blocks of endpoints + binaries allowed to reach them. network_policies: - # Each key is a logical name for a set of allowed connections. - claude_api: + my_api: + name: my-api endpoints: - - host: api.anthropic.com + - host: api.example.com port: 443 - protocol: rest # enables L7 (HTTP) inspection - tls: terminate # proxy decrypts TLS to inspect traffic - enforcement: enforce # actively enforce access rules - access: full # allow all HTTP methods and paths + protocol: rest + tls: terminate + enforcement: enforce + access: full binaries: - # Only these binaries may connect to the endpoints above. - - path: /usr/local/bin/claude - - path: /usr/bin/node + - path: /usr/bin/curl +# Dynamic: hot-reloadable. Routing hints this sandbox can use for inference (e.g. local, nvidia). inference: - # Which inference route types userland code is allowed to use. - allowed_routes: - - local + allowed_routes: [local] ``` -Refer to the [Policy Schema Reference](../reference/policy-schema.md) for every field, type, and default value. +For the complete structure and every field, see the [Policy Schema Reference](../reference/policy-schema.md). + +## Network access rules + +Network access is controlled by policy blocks under `network_policies`. Each block has a **name**, a list of **endpoints** (host, port, protocol, and optional rules), and a list of **binaries** that are allowed to use those endpoints. The example below shows a full policy block. + +### How network access is evaluated + +Every outbound connection from the sandbox goes through the proxy. The proxy matches the **destination** (host and port) and the **calling binary** to an endpoint in one of your policy blocks. If an endpoint matches the destination and the binary is listed in that block's `binaries`, the connection is **allowed**. For endpoints with `protocol: rest` and `tls: terminate`, each HTTP request is also checked against that endpoint's `rules` (method and path). If no endpoint matches and inference routes are configured, the request may be **rerouted for inference**. Otherwise the connection is **denied**. Endpoints without `protocol` or `tls` (L4-only) allow the TCP stream through without inspecting payloads. For the full endpoint schema, access presets, and binary matching, see the [Policy Schema Reference](../reference/policy-schema.md). + +### Enable GitHub push + +The following policy block allows the listed binaries (Claude and the GitHub CLI) to reach `api.github.com` with the given rules: read-only (GET, HEAD, OPTIONS) and GraphQL (POST) for all paths; full write access for `alpha-repo`; and create/edit issues only for `bravo-repo`. Replace `` with your GitHub org or username. + +Add this to your existing sandbox policy if you want to apply this GitHub permission set. + +```yaml + github_repos: + name: github_repos + endpoints: + - host: api.github.com + port: 443 + protocol: rest + tls: terminate + enforcement: enforce + rules: + # Read-only access to all GitHub API paths + - allow: + method: GET + path: "/**" + - allow: + method: HEAD + path: "/**" + - allow: + method: OPTIONS + path: "/**" + # GraphQL API (used by gh CLI for most operations) + - allow: + method: POST + path: "/graphql" + # alpha-repo: full write access + - allow: + method: "*" + path: "/repos//alpha-repo/**" + # bravo-repo: create + edit issues + - allow: + method: POST + path: "/repos//bravo-repo/issues" + - allow: + method: PATCH + path: "/repos//bravo-repo/issues/*" + binaries: + - { path: /usr/local/bin/claude } + - { path: /usr/bin/gh } +``` + +Then run `openshell policy set --policy --wait` to apply. + +### If something is blocked + +Check `openshell logs --tail --source sandbox` for the denied host, path, and binary. Add or adjust the matching endpoint or rules in the relevant policy block (e.g. add a new `allow` rule for the method and path, or add the binary to that block's `binaries` list). See [How do I edit it](#how-do-i-edit-it) for the full iteration workflow. ## Default Policy -NemoClaw ships a built-in default policy designed for Claude Code. It covers Claude's API endpoints, telemetry hosts, GitHub access, and VS Code marketplace traffic out of the box. +OpenShell ships a built-in default policy designed for Claude Code. It covers Claude's API endpoints, telemetry hosts, GitHub access, and VS Code marketplace traffic out of the box. | Agent | Default policy coverage | What you need to do | |---|---|---| @@ -87,7 +136,7 @@ If you run a non-Claude agent without a custom policy, the agent's API calls wil Pass a policy YAML file when creating the sandbox: ```console -$ nemoclaw sandbox create --policy ./my-policy.yaml --keep -- claude +$ openshell sandbox create --policy ./my-policy.yaml --keep -- claude ``` The `--keep` flag keeps the sandbox running after the initial command exits, which is useful when you plan to iterate on the policy. @@ -95,15 +144,15 @@ The `--keep` flag keeps the sandbox running after the initial command exits, whi To avoid passing `--policy` every time, set a default policy with an environment variable: ```console -$ export NEMOCLAW_SANDBOX_POLICY=./my-policy.yaml -$ nemoclaw sandbox create --keep -- claude +$ export OPENSHELL_SANDBOX_POLICY=./my-policy.yaml +$ openshell sandbox create --keep -- claude ``` -The CLI uses the policy from `NEMOCLAW_SANDBOX_POLICY` whenever `--policy` is not explicitly provided. +The CLI uses the policy from `OPENSHELL_SANDBOX_POLICY` whenever `--policy` is not explicitly provided. -## The Policy Iteration Loop +## How do I edit it -Policy authoring is an iterative process. You start with a minimal policy, observe what the agent needs, and refine the rules until everything works. This is the core workflow: +To change what the sandbox can access, you pull the current policy, edit the YAML, and push the update. The workflow is iterative: create the sandbox, monitor logs for denied actions, pull the policy, modify it, push, and verify. ```{mermaid} flowchart TD @@ -124,129 +173,41 @@ flowchart TD linkStyle default stroke:#76b900,stroke-width:2px ``` -### Step 1: Create the Sandbox with Your Initial Policy - -```console -$ nemoclaw sandbox create --policy ./my-policy.yaml --keep -- claude -``` - -### Step 2: Monitor Logs for Denied Actions - -In a second terminal, tail the sandbox logs and look for `action: deny` entries: - -```console -$ nemoclaw logs --tail --source sandbox -``` - -Each deny entry shows the blocked host, port, calling binary, and reason. This tells you exactly what the agent tried to reach and why it was blocked. +**Steps** -Alternatively, run `nemoclaw term` for the OpenShell Terminal, a live dashboard -that shows status and logs in a single view. Refer to {doc}`/sandboxes/terminal` for -how to read log entries and diagnose what is being blocked. - -:::{tip} -The OpenShell Terminal is especially useful during policy iteration. You can -watch deny entries appear in real time as the agent hits blocked endpoints, then -push an updated policy without leaving the terminal. -::: - -### Step 3: Pull the Current Policy - -Export the running policy to a file: - -```console -$ nemoclaw policy get --full > current-policy.yaml -``` - -:::{warning} -The `--full` output includes a metadata header with `Version`, `Hash`, and `Status` lines that are not valid YAML. Strip these lines before re-submitting the file as a policy update, or the push will fail. -::: - -### Step 4: Modify the Policy YAML - -Edit `current-policy.yaml` to address the denied actions you observed. Common changes include: - -- Adding endpoints to `network_policies` entries -- Adding binary paths to existing endpoint rules -- Creating new named policy entries for new destinations -- Adjusting `access` levels or adding custom `rules` -- Updating `inference.allowed_routes` - -### Step 5: Push the Updated Policy - -```console -$ nemoclaw policy set --policy current-policy.yaml --wait -``` - -The `--wait` flag blocks until the policy engine processes the update. Exit codes: - -| Exit code | Meaning | -|-----------|---------| -| `0` | Policy loaded successfully | -| `1` | Policy failed validation | -| `124` | Timed out waiting for the policy engine | - -### Step 6: Verify the New Revision Loaded - -```console -$ nemoclaw policy list -``` - -Check that the latest revision shows status `loaded`. If it shows `failed`, review the error message and go back to Step 4. - -### Step 7: Repeat - -Return to Step 2. Monitor logs, observe new denied actions (or confirm everything works), and refine the policy until the agent operates correctly within the rules you have set. - -## Policy Revision History - -Every `policy set` creates a new revision. You can inspect the full revision history: - -```console -$ nemoclaw policy list --limit 50 -``` - -To retrieve a specific revision: - -```console -$ nemoclaw policy get --rev 3 --full -``` +1. **Create** the sandbox with your initial policy (or set `OPENSHELL_SANDBOX_POLICY`). -### Revision Statuses + ```console + $ openshell sandbox create --policy ./my-policy.yaml --keep -- claude + ``` -| Status | Meaning | -|--------------|---------| -| `pending` | The revision has been submitted and is awaiting processing by the policy engine. | -| `loaded` | The revision passed validation and is the active policy for the sandbox. | -| `failed` | The revision failed validation. The previous good revision remains active. | -| `superseded` | A newer revision has been loaded, replacing this one. | +2. **Monitor** denials — each log entry shows host, port, binary, and reason. Alternatively use `openshell term` for a live dashboard. -## Policy Validation + ```console + $ openshell logs --tail --source sandbox + ``` -The server validates every policy at creation and update time. Policies that violate any of the following rules are rejected with exit code `1` (`INVALID_ARGUMENT`): +3. **Pull** the current policy. Strip the metadata header (Version, Hash, Status) before reusing the file. -| Rule | Description | -|---|---| -| No root identity | `run_as_user` and `run_as_group` cannot be `root` or `0`. | -| Absolute paths only | All filesystem paths must start with `/`. | -| No path traversal | Filesystem paths must not contain `..` components. | -| No overly broad writes | Read-write paths like `/` alone are rejected. | -| Path length limit | Each path must not exceed 4096 characters. | -| Path count limit | The combined total of `read_only` and `read_write` paths must not exceed 256. | + ```console + $ openshell policy get --full > current-policy.yaml + ``` -When a disk-loaded YAML policy (via `--policy` or `NEMOCLAW_SANDBOX_POLICY`) fails validation, the sandbox falls back to a restrictive default policy rather than starting with an unsafe configuration. +4. **Edit** the YAML: add or adjust `network_policies` entries, binaries, `access` or `rules`, or `inference.allowed_routes`. -Refer to the [Policy Schema Reference](../reference/policy-schema.md) for the constraints documented alongside each field. +5. **Push** the updated policy. Exit codes: 0 = loaded, 1 = validation failed, 124 = timeout. -## Safety Properties + ```console + $ openshell policy set --policy current-policy.yaml --wait + ``` -**Last-known-good.** -If a new policy revision fails validation, the previous successfully loaded policy stays active. A bad push does not break a running sandbox. The agent continues operating under the last good policy. +6. **Verify** the new revision. If status is `loaded`, repeat from step 2 as needed; if `failed`, fix the policy and repeat from step 4. -**Idempotent.** -Submitting the same policy content again does not create a new revision. The CLI detects that the content has not changed and returns without modifying the revision history. + ```console + $ openshell policy list + ``` ## Next Steps -- [Network Access Rules](network-access-rules.md): How the proxy evaluates connections, endpoint allowlists, binary matching, and enforcement modes. -- {doc}`../reference/policy-schema`: Complete field reference for the policy YAML. +- [Policy Schema Reference](../reference/policy-schema.md): Complete field reference for the policy YAML. +- [Security Model](security-model.md): Threat scenarios and protection layers. diff --git a/docs/safety-and-privacy/security-model.md b/docs/safety-and-privacy/security-model.md index 5be80237..8108b564 100644 --- a/docs/safety-and-privacy/security-model.md +++ b/docs/safety-and-privacy/security-model.md @@ -10,7 +10,7 @@ file, reach any network host, call any API with your credentials, and install arbitrary software. OpenShell's security model exists to prevent all of that. :::{note} -NemoClaw uses defense in depth. Four independent protection layers: filesystem, +OpenShell uses defense in depth. Four independent protection layers: filesystem, network, process, and inference. They work together so that no single point of failure can compromise your environment. ::: @@ -40,7 +40,7 @@ The agent reads `~/.ssh/id_rsa`, `~/.aws/credentials`, or other sensitive files from your home directory and exfiltrates them. **With OpenShell:** -Landlock filesystem restrictions limit the agent to declared paths. The agent +[Landlock](https://docs.kernel.org/security/landlock.html) filesystem restrictions limit the agent to declared paths. The agent can access `/sandbox`, `/tmp`, and read-only system directories, but not your home directory, SSH keys, cloud credentials, or anything else outside the policy. @@ -69,7 +69,7 @@ or uses raw sockets to scan your internal network. **With OpenShell:** The agent runs as an unprivileged user with seccomp filters that block -dangerous system calls. Landlock prevents writes outside allowed paths. There +dangerous system calls. [Landlock](https://docs.kernel.org/security/landlock.html) prevents writes outside allowed paths. There is no `sudo`, no `setuid`, and no path to elevated privileges. :::{important} @@ -82,6 +82,5 @@ that the others cannot. ## Next Steps -- {doc}`policies`: Write and iterate on the policy YAML that configures all four layers -- {doc}`network-access-rules`: Configure network rules, binary matching, and TLS inspection +- {doc}`policies`: Write and iterate on the policy YAML that configures all four layers (including network rules, binary matching, and TLS inspection). - {doc}`../inference/index`: Set up private inference backends From 790277ca5ba52c14633681db361a7d68a92e52a9 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Mon, 9 Mar 2026 10:58:59 -0700 Subject: [PATCH 36/39] edit and improve index pages --- docs/inference/index.md | 7 ++++--- docs/safety-and-privacy/index.md | 29 +++++++++++++++++++++-------- docs/sandboxes/index.md | 15 ++++++++++----- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/docs/inference/index.md b/docs/inference/index.md index 435e2cc0..63a898f4 100644 --- a/docs/inference/index.md +++ b/docs/inference/index.md @@ -78,6 +78,7 @@ If an intercepted request does not match any known pattern, it is denied. ## Next Steps -- {doc}`configure-routes`: create and manage inference routes. -- {doc}`/safety-and-privacy/network-access-rules`: understand agent traffic compared to - userland traffic. +- {doc}`configure-routes`: Create and manage inference routes for your + backends. +- {doc}`/safety-and-privacy/network-access-rules`: Agent traffic versus + userland traffic and how network rules interact with inference routing. diff --git a/docs/safety-and-privacy/index.md b/docs/safety-and-privacy/index.md index 32448a55..68cc20e2 100644 --- a/docs/safety-and-privacy/index.md +++ b/docs/safety-and-privacy/index.md @@ -48,11 +48,24 @@ graph TB linkStyle default stroke:#76b900,stroke-width:2px ``` -You control all four layers through a single YAML policy. Network and inference -rules are hot-reloadable on a running sandbox. Filesystem and process -restrictions are locked at creation time. - -- {doc}`security-model`: Threat scenarios (data exfiltration, credential - theft, unauthorized API calls, privilege escalation) and how OpenShell - addresses each one. -- {doc}`policies`: What a policy is, how it's evaluated, its structure, how to edit it, network access rules (including the GitHub push example), and the iteration workflow. +## How the Layers Work Together + +You control all four layers through a single YAML policy. + +| Layer | What It Protects | When It Applies | +|---|---|---| +| **Filesystem** (Landlock LSM) | Prevents reads/writes outside allowed paths. | Locked at sandbox creation. | +| **Network** (Proxy + Policy Engine) | Blocks unauthorized outbound connections. | Hot-reloadable at runtime. | +| **Process** (seccomp + unprivileged user) | Blocks privilege escalation and dangerous syscalls. | Locked at sandbox creation. | +| **Inference** (Privacy Router) | Reroutes API calls to backends you control. | Hot-reloadable at runtime. | + +Filesystem and process restrictions are locked at creation time. Network and +inference rules are hot-reloadable on a running sandbox, so you can iterate on +access rules without recreating the sandbox. + +## Next Steps + +- {doc}`security-model`: Threat scenarios and how each protection layer + addresses them. +- {doc}`policies`: Policy structure, evaluation order, and how to iterate on + rules. diff --git a/docs/sandboxes/index.md b/docs/sandboxes/index.md index ce1945c6..18a20d33 100644 --- a/docs/sandboxes/index.md +++ b/docs/sandboxes/index.md @@ -43,8 +43,13 @@ with `nemoclaw gateway select `. Refer to the ## Next Steps -- [Create and Manage Sandboxes](create-and-manage.md): The full sandbox lifecycle — create, inspect, connect, monitor, and delete. -- [Providers](providers.md): Create and attach credential providers. -- [Custom Containers](custom-containers.md): Build and run your own container image. -- [Community Sandboxes](community-sandboxes.md): Use pre-built sandboxes from the community catalog. -- [Terminal](terminal.md): Monitor sandbox status and live activity in a dashboard. +- {doc}`create-and-manage`: Create, inspect, connect, monitor, and delete + sandboxes. +- {doc}`providers`: Create and attach credential providers so agents can + authenticate with external services. +- {doc}`custom-containers`: Build and run your own container image inside a + sandbox. +- {doc}`community-sandboxes`: Use pre-built sandboxes from the community + catalog. +- {doc}`terminal`: Monitor sandbox status and live activity in a terminal + dashboard. From 60404045c8d456018a3496706a9a3bc226556aa1 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Mon, 9 Mar 2026 11:13:37 -0700 Subject: [PATCH 37/39] fix build --- docs/index.md | 2 +- docs/troubleshooting.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 12c9b0d7..7c9584fd 100644 --- a/docs/index.md +++ b/docs/index.md @@ -181,7 +181,7 @@ Home ``` ```{toctree} -:caption: About +:caption: About NVIDIA OpenShell :hidden: Overview diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 85afd743..87d885f8 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -66,7 +66,7 @@ Troubleshoot problems with creating, connecting to, and configuring sandboxes. **Check:** 1. Stream sandbox logs: `nemoclaw logs --tail --source sandbox`. 2. Look for `deny` actions. They include the destination, binary, and reason. -3. Update the policy to allow the blocked endpoint. Refer to [Policy Iteration Loop](safety-and-privacy/policies.md#the-policy-iteration-loop). +3. Update the policy to allow the blocked endpoint. Refer to [](safety-and-privacy/policies.md). ### Policy Update Fails From 8d6411e9bc26cbba75ae5852770a8eee0fb2b1e4 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Mon, 9 Mar 2026 11:26:01 -0700 Subject: [PATCH 38/39] revert README --- README.md | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 4bfca683..df1a076a 100644 --- a/README.md +++ b/README.md @@ -10,29 +10,20 @@ It transforms the data center from a static deployment target into a continuous ### Prerequisites - - -| Requirement | Details | -|-------------|---------------------------------------------------------------------------| -| **Docker** | Docker Desktop or a standalone Docker Engine daemon, running. | -| **Python** | 3.12 or later. | - +- **Docker** — Docker Desktop (or a Docker daemon) must be running. +- **Python 3.12+** +- [**uv**](https://docs.astral.sh/uv/) 0.9+ ### Install - - ```bash uv pip install nemoclaw \ --upgrade \ --pre \ --index-url https://urm.nvidia.com/artifactory/api/pypi/nv-shared-pypi/simple ``` - -### Install from Source (Developer) - -Refer to [`CONTRIBUTING.md`](CONTRIBUTING.md) for the full development workflow and installation instructions. +The `nemoclaw` binary is installed into your Python environment. Use `uv run nemoclaw` to invoke it, or activate your venv first with `source .venv/bin/activate`. ### Create a sandbox From 2fd110f4449ef29b747cfc82d667bc3234d8e399 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Mon, 9 Mar 2026 11:28:37 -0700 Subject: [PATCH 39/39] revert quickstart to not pull from README --- docs/get-started/quickstart.md | 11 ++++------- docs/inference/index.md | 5 ++--- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/docs/get-started/quickstart.md b/docs/get-started/quickstart.md index 238a0a6e..ce4c907f 100644 --- a/docs/get-started/quickstart.md +++ b/docs/get-started/quickstart.md @@ -25,16 +25,13 @@ This page gets you from zero to a running, policy-enforced sandbox in two comman Before you begin, make sure you have: -```{include} ../../README.md -:start-after: -:end-before: -``` +- Python 3.12 or later +- Docker Desktop running on your machine ## Install the OpenShell CLI -```{include} ../../README.md -:start-after: -:end-before: +```bash +pip install nemoclaw ``` ## Create Your First OpenShell Sandbox diff --git a/docs/inference/index.md b/docs/inference/index.md index 63a898f4..67f47a30 100644 --- a/docs/inference/index.md +++ b/docs/inference/index.md @@ -78,7 +78,6 @@ If an intercepted request does not match any known pattern, it is denied. ## Next Steps -- {doc}`configure-routes`: Create and manage inference routes for your - backends. -- {doc}`/safety-and-privacy/network-access-rules`: Agent traffic versus +- {doc}`configure-routes`: Create and manage inference routes. +- {doc}`/safety-and-privacy/network-access-rules`: Understand agent traffic versus userland traffic and how network rules interact with inference routing.