Skip to main content
NVIDIA
Explore
Models
Skills
Blueprints
GPUs
Docs
Terms of Use
Privacy Policy
Your Privacy Choices
Contact

Copyright © 2026 NVIDIA Corporation

View All Playbooks
View All Playbooks

onboarding

  • Set Up Local Network Access
  • Open WebUI with Ollama

data science

  • Single-cell RNA Sequencing
  • Portfolio Optimization
  • CUDA-X Data Science
  • Text to Knowledge Graph
  • Optimized JAX

tools

  • DGX Dashboard
  • RAG Application in AI Workbench
  • Set up Tailscale on Your Spark
  • VS Code
  • Connect Three DGX Spark in a Ring Topology
  • Connect Multiple DGX Spark through a Switch

fine tuning

  • FLUX.1 Dreambooth LoRA Fine-tuning
  • LLaMA Factory
  • Fine-tune with NeMo
  • Fine-tune with Pytorch
  • Unsloth on DGX Spark

use case

  • Run NemoClaw with a Local LLM
  • 🦞 Set Up Example NemoClaw Agents 🦞
  • Run Hermes Agent with Local Models
  • cuTile Kernels
  • CLI Coding Agent
  • Live VLM WebUI
  • Install and Use Isaac Sim and Isaac Lab
  • Vibe Coding in VS Code
  • Build and Deploy a Multi-Agent Chatbot
  • Connect Two Sparks
  • NCCL for Two Sparks
  • Build a Video Search and Summarization (VSS) Agent
  • Spark & Reachy Photo Booth
  • Secure Long Running AI Agents with OpenShell on DGX Spark
  • OpenClaw 🦞

inference

  • Speculative Decoding
  • Run models with llama.cpp on DGX Spark
  • Nemotron Model Family on DGX Spark
  • SGLang for Inference
  • TRT LLM for Inference
  • NVFP4 Quantization
  • Multi-modal Inference
  • NIM on Spark
  • LM Studio on DGX Spark
  • vLLM for Inference

Secure Long Running AI Agents with OpenShell on DGX Spark

30 MINS

Run OpenClaw with local models in an NVIDIA OpenShell sandbox on DGX Spark

AI AgentDGXOpenShellSecuritySpark
OpenShell on GitHub
OverviewOverviewInstructionsInstructionsTroubleshootingTroubleshooting

Step 1
Confirm your environment

Verify the OS, GPU, Docker, and Python are available before installing anything.

head -n 2 /etc/os-release
nvidia-smi
docker info --format '{{.ServerVersion}}'
python3 --version

Ensure NVIDIA Sync is configured with a custom port: use "OpenClaw" as the Name and "18789" as the port.

Expected output should show Ubuntu 24.04 (DGX OS), a detected GPU, a Docker server version, and Python 3.12+.

Step 2
Docker Configuration

First, verify that the local user has Docker permissions using the following command.

docker ps

If you get a permission denied error (permission denied while trying to connect to the docker API at unix:///var/run/docker.sock), add your user to the system's Docker group. This will enable you to run Docker commands without requiring sudo. The command to do so is as follows:

sudo usermod -aG docker $USER
newgrp docker

Note that you should reboot the Spark after adding the user to the group for this to take persistent effect across all terminal sessions.

Now that we have verified the user's Docker permission, we must configure Docker so that it can use the NVIDIA Container Runtime.

sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

Run a sample workload to verify the setup:

docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi

Step 3
Install OpenShell

Run the official installer, which installs both the openshell CLI and the openshell-gateway daemon as a systemd user service.

curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh | sh

After installation, open a new shell (or source ~/.bashrc) so the openshell binary is on your PATH, then verify:

openshell --help

Expected output should show the openshell command tree with subcommands like sandbox, provider, and inference.

Step 4
Verify the OpenShell gateway

As of OpenShell v0.0.37, the gateway is managed as a systemd user service installed automatically in Step 3. Confirm the service is running and the CLI can reach it:

systemctl --user status --no-pager openshell-gateway
openshell status

openshell status should report the gateway as Connected. If the service is not running, start it manually:

systemctl --user start openshell-gateway

To ensure the gateway persists after you log out:

sudo loginctl enable-linger $USER

To follow gateway logs in real time (streams continuously — press Ctrl+C to exit):

journalctl --user -u openshell-gateway -f

Step 5
Serve a model with vLLM

Serve a model with vLLM for local inference. This playbook uses the agent-ready nvidia/Qwen3.6-35B-A3B-NVFP4 recipe — the same one documented in the vLLM playbook's Run Agent Ready Qwen3.6 35B Model with vLLM tab.

Follow that tab to launch the server in a separate terminal. It serves nvidia/Qwen3.6-35B-A3B-NVFP4 on an OpenAI-compatible API at port 8000.

IMPORTANT

The recipe binds --host 0.0.0.0, which is required here: the OpenShell gateway runs inside Docker and reaches the server over the Spark's IP address, not localhost. Keep the --host 0.0.0.0 flag when you launch it.

Once the server reports Application startup complete, verify it is reachable on all interfaces:

curl http://0.0.0.0:8000/v1/models

Expected: a JSON "data" array listing nvidia/Qwen3.6-35B-A3B-NVFP4. If the request hangs, the model is likely still loading — wait for the startup line and retry.

Step 6
Create an inference provider

We are going to create an OpenShell provider that points to your local vLLM server. This lets OpenShell route inference requests to your Spark-hosted model.

First, find the IP address of your DGX Spark:

hostname -I | awk '{print $1}'

Then create the provider, substituting your actual IP for MACHINE_IP in the command below. vLLM does not require an API key, so any non-empty placeholder works:

openshell provider create \
    --name local-vllm \
    --type openai \
    --credential OPENAI_API_KEY=not-needed \
    --config OPENAI_BASE_URL=http://MACHINE_IP:8000/v1

IMPORTANT

Do not use localhost or 127.0.0.1 here. The OpenShell gateway runs inside a Docker container, so it cannot reach the host via localhost. Replace MACHINE_IP with the machine's actual IP address.

Verify the provider was created:

openshell provider list

Step 7
Configure inference routing

Point the inference.local endpoint (available inside every sandbox) at your vLLM model. The model name must match the handle served in Step 5:

openshell inference set \
    --provider local-vllm \
    --model nvidia/Qwen3.6-35B-A3B-NVFP4

The output should confirm the route and show a validated endpoint URL, for example: http://10.110.106.169:8000/v1/chat/completions (openai_chat_completions).

NOTE

If you see failed to verify inference endpoint or failed to connect (for example because the gateway cannot reach the host IP from inside its container), add --no-verify to skip endpoint verification: openshell inference set --provider local-vllm --model nvidia/Qwen3.6-35B-A3B-NVFP4 --no-verify. Ensure the vLLM server is running and reachable on the Spark's IP (see Step 5).

Verify the configuration:

openshell inference get

Expected output should show provider: local-vllm and model: nvidia/Qwen3.6-35B-A3B-NVFP4.

Step 8
Deploy OpenShell Sandbox

Create a sandbox using the pre-built OpenClaw community sandbox. This pulls the OpenClaw Dockerfile, the default policy, and startup scripts from the OpenShell Community catalog:

openshell sandbox create \
  --keep \
  --tty \
  --forward 18789 \
  --name dgx-demo \
  --from openclaw \
  -- openclaw-start

NOTE

Do not pass --policy with a local file path (e.g. openclaw-policy.yaml) when using --from openclaw. The policy is bundled with the community sandbox; a local file path can cause "file not found."

The --keep flag keeps the sandbox running after the initial process exits, so you can reconnect later. This is the default behavior. To terminate the sandbox when the initial process exits, use the --no-keep flag instead.

The CLI will:

  1. Resolve openclaw against the community catalog
  2. Pull and build the container image
  3. Apply the bundled sandbox policy
  4. Launch OpenClaw inside the sandbox

Set the sandbox name as an environment variable now so subsequent commands can reference it:

export SANDBOX_NAME=dgx-demo

Step 9
Configure OpenClaw within OpenShell Sandbox

The sandbox container will spin up and the OpenClaw onboarding wizard will launch automatically in your terminal.

IMPORTANT

The onboarding wizard is fully interactive — it requires arrow-key navigation and Enter to select options. It cannot be completed from a non-interactive session (e.g. a script or automation tool). You must run openshell sandbox create from a terminal with full TTY support.

If the wizard did not complete during sandbox creation, reconnect to the sandbox to re-run it:

openshell sandbox connect dgx-demo

The wizard prompt structure varies across openclaw versions — the community sandbox image and the latest npm release may differ. Use this version-agnostic walkthrough rather than following prompts by position:

  1. Accept terms — select Yes.
  2. Quickstart vs Manual — select Quickstart.
  3. Model/auth Provider — find and select Custom Provider:
    • In openclaw 2026.6.5+: the short list shows OpenAI / Anthropic / xAI / Google / More… / Skip. Select More… to open the full provider submenu, then search for or scroll to Custom Provider.
    • In older openclaw (community image): Custom Provider appears directly in the list.
  4. API Base URL — enter https://inference.local/v1.
  5. API key — enter any non-empty value (e.g. not-needed; vLLM does not validate it).
  6. Model ID — enter the model handle from Step 5: nvidia/Qwen3.6-35B-A3B-NVFP4.
  7. Remaining prompts (Channel, Search provider, Skills, Hooks) — select Skip or No for each.

NOTE

The community sandbox image (ghcr.io/nvidia/openshell-community/sandboxes/openclaw:latest) may be several versions behind the latest openclaw npm release. If the wizard behaves unexpectedly, check the version baked into the image: docker exec $(docker ps --filter name=openshell-${SANDBOX_NAME} --format '{{.Names}}') openclaw --version.

It might take 1-2 minutes to get through the final stages. Afterwards, you should see a URL with a token you can use to connect to the gateway.

The expected output will be similar, but the token will be unique.

OpenClaw gateway starting in background.
  Logs: /tmp/gateway.log
  UI:   http://127.0.0.1:18789/?token=9b4c9a9c9f6905131327ce55b6d044bd53e0ec423dd6189e

In order to verify the default policy enabled for your sandbox, please run the following command:

openshell sandbox get $SANDBOX_NAME

NOTE

Step 8’s --forward 18789 already sets up port forwarding from the OpenShell gateway to the sandbox. You do not need a manual ssh command with openshell ssh-proxy for the usual case.

To verify the forward is active, use the following command:

openshell forward list

You should see your sandbox name (e.g. dgx-demo) with port 18789. If it is missing or dead, start it:

openshell forward start --background 18789 $SANDBOX_NAME

Path A: If you are using the Spark as the primary device, right-click on the URL in the UI section and select Open Link.

Path B: If you are using a laptop or workstation that is not on the Spark (e.g. you SSH into the Spark only): Install the OpenShell CLI on that machine.

IMPORTANT

SSH must work from this machine to the Spark before gateway add. Run ssh nvidia@<spark-ip> (or your user/host) and confirm you get a shell without Permission denied (publickey). If that fails, add your public key to the Spark: ssh-copy-id nvidia@<spark-ip> (from the same machine), or paste your ~/.ssh/id_ed25519.pub (or id_rsa.pub) into ~/.ssh/authorized_keys on the Spark. OpenShell uses this SSH session to reach the remote Docker API and extract gateway TLS certificates. If you use a non-default key, pass --ssh-key ~/.ssh/your_key to gateway add (same as Step 4’s remote gateway note).

Register the Spark’s already-running gateway. Do not use openshell gateway add user@ip alone—that is parsed as a cloud URL and will not write mtls/ca.crt.

Per the OpenShell gateway docs, register using hostname openshell, not the raw Spark IP, for HTTPS.

WARNING

The gateway TLS certificate is valid for openshell, localhost, and 127.0.0.1 — not for your Spark’s LAN IP. If you use https://10.x.x.x:8080 or ssh://user@10.x.x.x:8080, openshell status may fail with certificate not valid for name "10.x.x.x".

On your laptop/WSL, map openshell to the Spark (once per machine):

# Replace with your Spark’s IP. Requires sudo on Linux/WSL.
echo "<spark-ip> openshell" | sudo tee -a /etc/hosts
# Example: echo "10.110.17.10 openshell" | sudo tee -a /etc/hosts

Then add the gateway (SSH target stays the real IP or hostname; HTTPS URL uses openshell):

openshell gateway add https://openshell:8080 --remote <user>@<spark-ip>

Example:

openshell gateway add https://openshell:8080 --remote nvidia@10.110.17.10

If you already registered with the IP and see the cert error, remove that entry and re-add:

openshell gateway destroy 
openshell gateway add https://openshell:8080 --remote nvidia@10.110.17.10

(Use openshell gateway select if the destroy name differs.)

Complete any browser or CLI prompts until the command finishes (do not Ctrl+C early). Then:

openshell status   # should show Connected, not TLS CA errors
openshell forward start --background 18789 dgx-demo

Then on the laptop browser open (use #token= so the UI receives the gateway token):

http://127.0.0.1:18789/#token=<your-token>

Use the token value from the OpenClaw wizard output on the Spark. Path B requires SSH from the laptop to the Spark so the CLI can reach the gateway on :8080.

NVIDIA Sync: Right-click the URL in the UI and select Copy Link. Connect to your Spark in Sync, open the OpenClaw entry, and paste the URL in the browser address bar.

From this page, you can now Chat with your OpenClaw agent within the protected confines of the runtime OpenShell provides.

Step 10
Conduct Inference within Sandbox

Connecting to the Sandbox (Terminal)

Now that OpenClaw has been configured within the OpenShell protected runtime, you can connect directly into the sandbox environment via:

openshell sandbox connect $SANDBOX_NAME

Once loaded into the sandbox terminal, you can test connectivity to the vLLM model with this command:

curl https://inference.local/v1/chat/completions \
          -H "Content-Type: application/json" \
          -d '{
        "model": "nvidia/Qwen3.6-35B-A3B-NVFP4",
        "messages": [{"role": "user", "content": "Hello!"}]
      }'

Step 11
Verify sandbox isolation

Open a second terminal and check the sandbox status and live logs:

openshell term

The terminal dashboard shows:

  • Sandbox status — name, phase, image, providers, and port forwards
  • Live log stream — outbound connections, policy decisions (allow, deny, inspect_for_inference), and inference interceptions

Verify that the OpenClaw agent can reach inference.local for model requests and that unauthorized outbound traffic is denied.

TIP

Press f to follow live output, s to filter by source, and q to quit the terminal dashboard.

Step 12
Reconnect to the sandbox

If you exit the sandbox session, reconnect at any time:

openshell sandbox connect $SANDBOX_NAME

NOTE

openshell sandbox connect is interactive-only — it opens a terminal session inside the sandbox. There is no way to pass a command for non-interactive execution. Use openshell sandbox upload/download for file transfers, or openshell sandbox ssh-config for scripted SSH (see Step 14).

To transfer files in or out out of the sandbox, please use the following:

openshell sandbox upload $SANDBOX_NAME ./local-file /sandbox/destination
openshell sandbox download $SANDBOX_NAME /sandbox/file ./local-destination

Step 13
Cleanup

Stop and remove the sandbox:

openshell sandbox delete $SANDBOX_NAME

Remove the inference provider you created in Step 6:

openshell provider delete local-vllm

To stop the gateway service (it will restart automatically on next login unless you disable it):

systemctl --user stop openshell-gateway

To disable the gateway service entirely and remove linger:

systemctl --user disable openshell-gateway
sudo loginctl disable-linger $USER

To also stop and remove the vLLM container and image:

docker rm $(docker ps -aq --filter ancestor=vllm/vllm-openai:nightly-aarch64)
docker rmi vllm/vllm-openai:nightly-aarch64

Step 14
Next steps

  • Add more providers: Attach GitHub tokens, GitLab tokens, or cloud API keys as providers with openshell provider create. When creating the sandbox, pass the provider name(s) with --provider <name> (e.g. --provider my-github) to inject those credentials into the sandbox securely.
  • Try other community sandboxes: Run openshell sandbox create --from base or --from sdg for other pre-built environments.
  • Connect VS Code: Use openshell sandbox ssh-config <sandbox-name> and append the output to ~/.ssh/config to connect VS Code Remote-SSH directly into the sandbox.
  • Monitor and audit: Use openshell logs <sandbox-name> --tail or openshell term to continuously monitor agent activity and policy decisions.

Resources

  • NVIDIA OpenShell Documentation
  • OpenShell PyPI
  • OpenClaw Documentation
  • OpenClaw Gateway Security
  • DGX Spark Documentation
  • DGX Spark Forum