---
title: "Secure AI Agents with OpenShell — Instructions"
canonical: "https://build.nvidia.com/station/openshell/instructions.md"
---

# Step 1. Confirm your environment

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

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

Expected output should show Ubuntu 24.04 (or compatible DGX OS), a detected GPU, a Docker server version, and Python 3.12+. If you access the hardware remotely, ensure port `18789` is available for the OpenClaw dashboard.

# Step 2. Docker configuration

Verify that the local user has Docker permissions:

```bash
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 Docker group:

```bash
sudo usermod -aG docker $USER
newgrp docker
```

Reboot (or log out and back in) so the group membership applies to all sessions.

Configure Docker to use the NVIDIA Container Runtime:

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

Verify GPU access inside a container:

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

# Step 3. Install the OpenShell CLI

Install OpenShell with the official installer, which installs the `openshell` CLI and registers the `openshell-gateway` systemd user service:

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

Open a new shell (or `source ~/.bashrc`) so `openshell` is on your `PATH`, then verify:

```bash
openshell --help
```

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

> [!NOTE]
> Alternative install: `uv venv openshell-env && source openshell-env/bin/activate && uv pip install openshell`. If you use this path, activate the virtual environment in every new terminal before running `openshell` commands, and use `openshell gateway start` in Step 4 (the systemd unit is provided by the official installer).

# Step 4. Verify the OpenShell gateway

The official installer manages the gateway as a systemd user service. Confirm the service is running and the CLI can reach it:

```bash
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:

```bash
systemctl --user start openshell-gateway
```

To keep the gateway available after you log out:

```bash
sudo loginctl enable-linger $USER
```

Follow gateway logs in real time (press `Ctrl+C` to exit):

```bash
journalctl --user -u openshell-gateway -f
```

If you installed via `uv` (or the systemd unit is not present), start the gateway with the CLI instead:

```bash
openshell gateway start
openshell status
```

The first run may take a few minutes while Docker pulls images and the internal k3s cluster bootstraps.

> [!TIP]
> To manage a gateway on remote hardware from a separate workstation, ensure passwordless SSH works first, then use `openshell gateway start --remote <username>@<hostname>` (or register an existing gateway per the [OpenShell gateway docs](https://docs.nvidia.com/openshell/latest/sandboxes/manage-gateways.html)).

# Step 5. Serve a model with vLLM

Serve an OpenAI-compatible API for local inference. Use the recommended model for your hardware platform from the **Agent-ready Models** tab.

Launch the matching recipe in a **separate terminal**, keeping `--host 0.0.0.0` and port `8000` so the OpenShell gateway (inside Docker) can reach the server.

Once the server reports `Application startup complete`, verify it is reachable:

```bash
curl -s http://0.0.0.0:8000/v1/models
```

Expected: a JSON `"data"` array listing your model handle. Note the exact `id` — you will reuse it in Steps 6–7 and the OpenClaw wizard.

> [!IMPORTANT]
> Do not bind the server to `localhost` only. The OpenShell gateway cannot reach host services via `127.0.0.1` from inside its container network.

# Step 6. Create an inference provider

Create an OpenShell provider that points to your local vLLM server.

Find the IP address of your hardware:

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

Create the provider, replacing `{Machine_IP}` with that address. vLLM does not require an API key, so any non-empty placeholder works:

```bash
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. Use the machine's actual IP address. On some Linux Docker setups, `http://host.docker.internal:8000/v1` is an equivalent alternative if that hostname resolves inside the gateway container.

Verify:

```bash
openshell provider list
```

# Step 7. Configure inference routing

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

```bash
openshell inference set \
--provider local-vllm \
--model <MODEL_HANDLE>
```

Replace `<MODEL_HANDLE>` with the HuggingFace handle from the **Agent-ready Models** tab (for example `nvidia/Qwen3.6-35B-A3B-NVFP4` or `nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B-NVFP4`).

> [!NOTE]
> If you see `failed to verify inference endpoint` or `failed to connect`, confirm the server is healthy and warm up with one chat completion request. You can add `--no-verify` to skip endpoint verification after confirming reachability from the host.

Verify:

```bash
openshell inference get
```

Expected output should show `provider: local-vllm` and your chosen `model`.

# Step 8. Deploy the OpenShell sandbox

Create a sandbox using the pre-built OpenClaw community sandbox:

```bash
export SANDBOX_NAME=openshell-demo

openshell sandbox create \
--keep \
--forward 18789 \
--name "$SANDBOX_NAME" \
--from openclaw \
-- openclaw-start
```

> [!NOTE]
> Do not pass `--policy` with a local file path 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. To terminate when the initial process exits, use `--no-keep` 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

`--forward 18789` registers the port-forward intent. Activate it explicitly:

```bash
openshell forward start --background 18789 "$SANDBOX_NAME"
openshell forward list
```

You should see your sandbox name with port `18789`.

# Step 9. Configure OpenClaw within the sandbox

The OpenClaw onboarding wizard launches 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. You must run `openshell sandbox create` from a terminal with full TTY support.
>
> If the wizard did not complete during sandbox creation, reconnect:
> ```bash
> openshell sandbox connect "$SANDBOX_NAME"
> ```

> [!NOTE]
> If `openshell sandbox get` shows `Phase: Unspecified`, that is expected until the interactive wizard finishes. The sandbox container can still be healthy while the phase shows `Unspecified`. Confirm with supervisor logs if needed:
> ```bash
> docker logs $(docker ps --filter name=openshell-"$SANDBOX_NAME" --format '{{.Names}}') --tail 20
> ```
> Look for `OpenShell Sandbox Supervisor success` and `Applying Landlock filesystem sandbox`.

Use the arrow keys and Enter to complete onboarding:

- If you understand and agree, select **Yes** and press Enter.
- Quickstart vs Manual: select **Quickstart**.
- Model/auth Provider: select **Custom Provider**.
- API Base URL: `https://inference.local/v1`
- How do you want to provide this API key?: **Paste API key for now**.
- API key: enter any non-empty placeholder (for example `vllm` or `not-needed`).
- Endpoint compatibility: select **OpenAI-compatible**.
- Model ID: enter the same handle you set in Step 7.
- Endpoint ID: leave the default.
- Alias: optional; you can reuse the model name.
- Channel: **Skip for now**.
- Search provider: **Skip for now**.
- Skills: **No** for now.
- Enable hooks: **Skip for now** / **No**, then press Enter.

After 1–2 minutes you should see a URL with a token:

```bash
OpenClaw gateway starting in background.
Logs: /tmp/gateway.log
UI:   http://127.0.0.1:18789/?token=<unique-token>
```

Verify the sandbox:

```bash
openshell sandbox get "$SANDBOX_NAME"
```

## Access the dashboard

**On the hardware itself:** open the UI URL from the wizard output in a local browser (right-click → Open Link when available).

**From a remote workstation:** ensure port forwarding is active (`openshell forward list`), then open:

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

If you manage the gateway from a remote machine, register it with hostname `openshell` (not the raw LAN IP) so TLS certificate validation succeeds — see the [OpenShell gateway docs](https://docs.nvidia.com/openshell/latest/sandboxes/manage-gateways.html). Map `openshell` to the hardware IP in `/etc/hosts` on the workstation, then:

```bash
openshell gateway add https://openshell:8080 --remote <user>@<hardware-ip>
openshell forward start --background 18789 "$SANDBOX_NAME"
```

If the dashboard URL is only reachable inside the sandbox and the host forward is not active, you can also tunnel with the OpenShell SSH proxy (replace sandbox id, token, and gateway URL from your environment):

```bash
ssh -o ProxyCommand='openshell ssh-proxy --gateway https://127.0.0.1:17670/connect/ssh --sandbox-id <sandbox-id> --token <token> --gateway-name openshell' \
-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR \
-N -L 18789:127.0.0.1:18789 sandbox
```

Then open `http://127.0.0.1:18789/?token=<your-token>` in your local browser.

From the dashboard you can **Chat** with your OpenClaw agent inside the OpenShell sandbox.

# Step 10. Test inference inside the sandbox

Connect to the sandbox terminal:

```bash
openshell sandbox connect "$SANDBOX_NAME"
```

Test connectivity to the local model:

```bash
curl https://inference.local/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "<MODEL_HANDLE>",
"messages": [{"role": "user", "content": "Hello!"}]
}'
```

Replace `<MODEL_HANDLE>` with the same handle from Step 7.

# Step 11. Verify sandbox isolation

Open a second terminal and check live status and logs:

```bash
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 agent can reach `inference.local` and that unauthorized outbound traffic is denied.

> [!TIP]
> Press `f` to follow live output, `s` to filter by source, and `q` to quit.

# Step 12. Reconnect and transfer files

Reconnect at any time:

```bash
openshell sandbox connect "$SANDBOX_NAME"
```

> [!NOTE]
> `openshell sandbox connect` is interactive-only. Use upload/download for file transfers, or `openshell sandbox ssh-config` for scripted SSH.

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

# Step 13. Cleanup

Run gateway-dependent cleanup first, while the gateway is still reachable:

```bash
openshell sandbox delete "$SANDBOX_NAME"
openshell provider delete local-vllm
```

If you use the systemd user service (official installer):

```bash
systemctl --user stop openshell-gateway
systemctl --user disable openshell-gateway
sudo loginctl disable-linger $USER
```

If you started the gateway with the CLI instead:

```bash
openshell gateway stop
```

> [!WARNING]
> The following command permanently removes the gateway cluster and all its data.

```bash
openshell gateway destroy
```

Stop and remove the vLLM container if you started one for this playbook (replace the name/image filter to match your launch):

```bash
docker stop vllm-server 2>/dev/null; docker rm vllm-server 2>/dev/null
```

# Step 14. Next steps

- **Add more providers**: Attach GitHub tokens, GitLab tokens, or cloud API keys with `openshell provider create`, then pass `--provider <name>` when creating a sandbox.
- **Try other community sandboxes**: `openshell sandbox create --from base` or `--from sdg`.
- **Connect VS Code**: Use `openshell sandbox ssh-config <sandbox-name>` and append the output to `~/.ssh/config`.
- **Monitor and audit**: Use `openshell logs <sandbox-name> --tail` or `openshell term` to monitor agent activity and policy decisions.