Learning NemoClaw

05 · NemoClaw — The Integration Layer (deep dive)

What lives in NemoClaw/: NVIDIA's opinionated reference stack for running OpenClaw inside OpenShell. It doesn't reinvent either project — it's a CLI, a plugin, a versioned blueprint, and a set of YAML policies that wire them together the way NVIDIA recommends.

What NemoClaw actually is (concretely)

Four things:

Piece What it is Where it lives
nemoclaw CLI Host‑side binary. Primary entrypoint. Orchestrates OpenShell under the hood. bin/, src/lib/ (TS, compiled to dist/)
NemoClaw plugin A small TypeScript package loaded inside the sandbox alongside OpenClaw. Registers a custom inference provider and the /nemoclaw slash command. nemoclaw/src/
Blueprint A versioned, digest‑pinned YAML manifest describing which image, which policy, which inference profile, which NVIDIA model. This is the thing the plugin "runs". nemoclaw-blueprint/blueprint.yaml
Network policies The actual YAML enforced by OpenShell inside the sandbox. A base + presets per integration. nemoclaw-blueprint/policies/

Rule of thumb: thin plugin, versioned blueprint. The CLI/plugin are stable and small; the interesting stuff (image digest, policy, inference profile) lives in the blueprint and evolves on its own cadence with digest verification.

The one‑minute tour

curl -fsSL https://www.nvidia.com/nemoclaw.sh | bash     # installs Node via nvm + nemoclaw CLI
nemoclaw onboard                                          # guided wizard
nemoclaw my-assistant connect                             # SSH into the sandbox
sandbox$ openclaw tui                                     # you are now using OpenClaw

That's it. From the assistant's point of view, OpenClaw is just OpenClaw — same CLI, same sessions, same tools. From your point of view, everything is inside an OpenShell sandbox with policies applied.

What nemoclaw onboard actually does

This single command does a lot. Conceptually it walks the blueprint lifecycle:

resolve → verify digest → plan → apply → status
  1. Preflight — checks Docker is reachable, warns on Podman, installs Node if needed.
  2. Prompt for provider — NVIDIA Endpoints, OpenAI, Anthropic, Gemini, Ollama, or an OpenAI/Anthropic‑compatible endpoint. Validates the credential from the host before committing.
  3. Prompt for sandbox name (RFC 1123 subdomain rules: my-assistant, not My_Assistant).
  4. Prompt for channels — e.g. Telegram (collects TELEGRAM_BOT_TOKEN, allowed IDs), Discord (server ID, @mention vs all‑message, user allowlist).
  5. Resolve the blueprint — downloads the blueprint artifact, checks min_openshell_version/min_openclaw_version, verifies its digest.
  6. Plan — decides which OpenShell resources to create or update: gateway, providers, sandbox, inference route, policy.
  7. Apply — calls the openshell CLI under the hood:
    • openshell gateway start (if needed)
    • openshell provider create for each credential (provider API key, channel tokens)
    • openshell sandbox create --from <pinned digest>
    • openshell policy set to push the NemoClaw policy (base + any selected presets)
    • openshell inference set to route inference.local to the chosen provider/model
  8. Bake host config — writes ~/.nemoclaw/credentials.json, ~/.nemoclaw/sandboxes.json.
  9. Install the plugin into the sandbox — so /nemoclaw works from inside OpenClaw chat.

Running it again is idempotent and reproducible — that is the whole point of a digest‑pinned blueprint.

What the blueprint actually says

From nemoclaw-blueprint/blueprint.yaml:

version: "0.1.0"
min_openshell_version: "0.0.24"
min_openclaw_version: "2026.3.0"
digest: "sha256:b3d832b596ab6b7184a9dcb4ae93337ca32851a4f93b00765cc12de26baa3a9a"

profiles: [default, ncp, nim-local, vllm]

components:
  sandbox:
    image: "ghcr.io/nvidia/openshell-community/sandboxes/openclaw@sha256:b3d..."
    name: "openclaw"
    forward_ports: [18789]            # ← OpenClaw Gateway WS

  inference:
    profiles:
      default:
        provider_type: "nvidia"
        endpoint: "https://integrate.api.nvidia.com/v1"
        model: "nvidia/nemotron-3-super-120b-a12b"
      nim-local:
        provider_type: "openai"
        endpoint: "http://nim-service.local:8000/v1"
      vllm:
        endpoint: "http://localhost:8000/v1"

  policy:
    base: "sandboxes/openclaw/policy.yaml"
    additions:
      nim_service: { ... }

Key points:

What NemoClaw adds beyond "just use OpenShell's community sandbox"

OpenShell already ships a community sandbox: openshell sandbox create --from openclaw gives you a running OpenClaw with default isolation. NemoClaw layers on:

Area NemoClaw hardening
Filesystem /sandbox (home) is read‑only. Gateway config /sandbox/.openclaw is immutable (auth tokens and CORS cannot be tampered with). Writable state is pinned to /sandbox/.openclaw-data, /sandbox/.nemoclaw, /tmp. Workdir auto‑grant is disabled.
Image Strips gcc, g++, make, netcat from the runtime image to shrink attack surface.
Processes ulimit -u 512 in the entrypoint to cap process count (anti fork‑bomb).
Credentials Filters provider API keys, DISCORD_BOT_TOKEN, SLACK_BOT_TOKEN, TELEGRAM_BOT_TOKEN out of host env during sandbox creation so they can't leak via build args. They become OpenShell providers instead.
Sentry exfil Blocks POST sentry.io/** entirely — Sentry is a multi‑tenant SaaS and any authed client can POST to any project, making a path‑based allowlist useless. Only GET stays open (issue #1437).
Blueprint Version‑pinned, digest‑verified. Reproducible setup across machines.
State migration Safe snapshot/restore with credential stripping and SSRF validation (see nemoclaw/src/blueprint/snapshot.ts, ssrf.ts).
Channel bridges No separate host daemon. Tokens live in OpenShell providers; OpenClaw config holds placeholders; L7 proxy resolves them at egress (including Telegram's /bot<token>/ URL pattern).

Host‑side state

NemoClaw keeps operator state on the host so sandboxes stay replaceable:

Path Purpose
~/.nemoclaw/credentials.json Provider credentials from onboarding (plaintext, filesystem‑perm protected)
~/.nemoclaw/sandboxes.json Registered sandbox metadata + default selection
~/.openclaw/openclaw.json Host OpenClaw config that NemoClaw snapshots during migration flows

For normal use you do not edit these by hand — rerun nemoclaw onboard.

Credential storage — what's actually on disk

~/.nemoclaw/credentials.json is plaintext JSON. NemoClaw does not encrypt it and does not integrate with the macOS Keychain or any OS secret store. What protects it is Unix file ownership and permissions:

A typical file looks like:

{
  "NVIDIA_API_KEY": "nvapi-...",
  "OPENAI_API_KEY": "sk-...",
  "GITHUB_TOKEN": "ghp_..."
}

Lookup precedence: when NemoClaw needs a credential, it checks environment variables first, then falls back to this file. This means NVIDIA_API_KEY=... nemoclaw onboard in a CI job skips the file entirely — use that for ephemeral automation.

Inspect: ls -ld ~/.nemoclaw ~/.nemoclaw/credentials.json should show drwx------ and -rw-------. If the perms drift, tighten with chmod 700 ~/.nemoclaw && chmod 600 ~/.nemoclaw/credentials.json.

Rotate / remove: the easiest rotation path is to rm -f ~/.nemoclaw/credentials.json (or nemoclaw credentials reset <KEY> to remove one entry) and rerun nemoclaw onboard. Do not copy this file into container images, git repos, bug reports, or nemoclaw debug output — treat it like any other local secret material.

The "do not fight the tooling" rule

The docs are blunt about this: for a NemoClaw‑managed environment, use nemoclaw onboard when you need to create or recreate the gateway or sandbox. Avoid:

…unless you intend to manage OpenShell independently and then re‑run nemoclaw onboard to put things back in a known state. The blueprint's job is to be the source of truth; sidestepping it breaks that.


Next: 06-openshell.md — the sandbox runtime NemoClaw sits on top of.