Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions docs/deployment/authentication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
title:
page: "Authentication Configuration"
nav: "Authentication"
description:
main: "Configure device authentication for the OpenClaw gateway, including the NEMOCLAW_DISABLE_DEVICE_AUTH build argument."
agent: "Documents the NEMOCLAW_DISABLE_DEVICE_AUTH build argument and device authentication configuration. Use when configuring gateway authentication, disabling device auth, or reviewing auth security implications."
keywords: ["nemoclaw authentication", "device auth disable build arg"]
topics: ["generative_ai", "ai_agents"]
tags: ["nemoclaw", "security", "authentication", "deployment"]
content:
type: reference
difficulty: intermediate
audience: ["developer", "engineer", "security_engineer"]
status: published
---

<!--
SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: Apache-2.0
-->

# Authentication Configuration

This page documents the device authentication settings for the OpenClaw gateway, including the `NEMOCLAW_DISABLE_DEVICE_AUTH` build argument and related security controls.

## `NEMOCLAW_DISABLE_DEVICE_AUTH`

**Location**: Dockerfile build argument (line 59), propagated to `openclaw.json` as `dangerouslyDisableDeviceAuth`.
**Default**: `0` (device auth enabled — secure by default).

### What It Does

When set to `1`, the OpenClaw gateway skips the OAuth 2.0 Device Authorization Grant flow.
Users are not prompted to authenticate via browser-based device code approval before accessing the gateway API.

The setting is baked into `openclaw.json` at image build time and verified by a SHA256 integrity hash at container startup.
It cannot be changed at runtime.

### When to Disable (Set to `1`)

Disable device auth only when:

- The sandbox runs locally with no network exposure (single-user, localhost only).
- The environment is headless with no browser available to complete the device auth flow.
- The NemoClaw Docker sandbox is the only consumer (the default `nemoclaw onboard` flow handles this automatically).

```console
$ docker build --build-arg NEMOCLAW_DISABLE_DEVICE_AUTH=1 -t nemoclaw-sandbox .
```

### When to Keep Enabled (Default `0`)

Keep device auth enabled when:

- The gateway is network-accessible beyond localhost.
- Multiple users or external clients connect to the same instance.
- The sandbox is exposed via a tunnel (for example, cloudflared) or LAN binding.
- You need per-device audit trails.

### Security Implications

| Setting | Risk | Use Case |
|---------|------|----------|
| `0` (enabled, default) | Requires browser-based approval; gateway generates per-device tokens | Multi-user, external access, production |
| `1` (disabled) | Anyone with network access to the gateway can use it without authentication | Single-user local/Docker, headless development |

:::{warning}
Disabling device auth on a network-accessible gateway creates an unauthenticated endpoint.
Combined with a cloudflared tunnel or LAN-bind changes in remote deployments, this results in a publicly reachable, unauthenticated dashboard.
:::

### Related Settings

`allowInsecureAuth`
: Derived automatically from the `CHAT_UI_URL` scheme at build time.
When the URL uses `http://` (local development), insecure auth is allowed.
When it uses `https://`, insecure auth is blocked.
See [Security Best Practices](../security/best-practices.md) for details.

`auth.token`
: A gateway bearer token generated at build time using `secrets.token_hex(32)`.
Unique per image build.

`trustedProxies`
: IPs allowed to set `X-Forwarded-For` headers.
Defaults to `127.0.0.1` and `::1`.

## Next Steps

- [Security Best Practices](../security/best-practices.md) for the full gateway authentication controls reference.
- [Sandbox Hardening](sandbox-hardening.md) for container-level security measures.
- [Deploy to a Remote GPU Instance](deploy-to-remote-gpu.md) for remote deployment considerations.
2 changes: 2 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ Customize the Network Policy <network-policy/customize-network-policy>
:hidden:

Security Best Practices <security/best-practices>
Credential Storage <security/credential-storage>
```

```{toctree}
Expand All @@ -258,6 +259,7 @@ Security Best Practices <security/best-practices>
Deploy to a Remote GPU Instance <deployment/deploy-to-remote-gpu>
Set Up the Telegram Bridge <deployment/set-up-telegram-bridge>
Sandbox Hardening <deployment/sandbox-hardening>
Authentication <deployment/authentication>
```

```{toctree}
Expand Down
52 changes: 49 additions & 3 deletions docs/network-policy/customize-network-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ status: published
SPDX-License-Identifier: Apache-2.0
-->

# Customize the Sandbox Network Policy
# Customize the NemoClaw Sandbox Network Policy

Add, remove, or modify the endpoints that the sandbox is allowed to reach.

Expand Down Expand Up @@ -51,6 +51,52 @@ Each entry in the `network` section defines an endpoint group with the following
`rules`
: HTTP methods and paths that are permitted.

### Access Modes

Each endpoint supports two access modes that control how OpenShell inspects traffic:

:::{list-table}
:header-rows: 1
:widths: 15 15 70

* - Field
- Value
- Behavior

* - `protocol`
- `rest`
- OpenShell terminates TLS and inspects HTTP method/path against `rules`.
Only matching requests are forwarded.

* - `access`
- `full`
- OpenShell creates a raw CONNECT tunnel.
No HTTP inspection — all traffic to the host:port is allowed.
Use only when protocol-level inspection is not possible, such as `git` SSH-over-HTTPS or WebSocket upgrades.

:::

#### Enforcement and TLS Fields

```yaml
endpoints:
- host: api.example.com
port: 443
protocol: rest # Enable HTTP inspection
enforcement: enforce # Block non-matching requests (vs "audit" = log only)
tls: terminate # OpenShell terminates TLS to inspect HTTP layer
rules:
- allow: { method: GET, path: "/v1/**" }
- allow: { method: POST, path: "/v1/chat/completions" }
```

:::{note}
`access: full` bypasses all HTTP-layer rules.
The `github` policy uses `access: full` because `git` requires CONNECT tunneling.
This means method and path restrictions cannot be enforced on `api.github.com` — the agent has full API access.
See [Security Best Practices](../security/best-practices.md) for hardening options.
:::

### Re-Run Onboard

Apply the updated policy by re-running the onboard wizard:
Expand Down Expand Up @@ -103,7 +149,7 @@ Available presets:

| Preset | Endpoints |
|--------|-----------|
| `discord` | Discord webhook API |
| `discord` | Discord REST API, WebSocket gateway, CDN |
| `docker` | Docker Hub, NVIDIA container registry |
| `huggingface` | Hugging Face model registry |
| `jira` | Atlassian Jira API |
Expand All @@ -121,7 +167,7 @@ $ openshell policy set nemoclaw-blueprint/policies/presets/pypi.yaml

To include a preset in the baseline, merge its entries into `openclaw-sandbox.yaml` and re-run `nemoclaw onboard`.

## Related Topics
## Next Steps

- [Approve or Deny Agent Network Requests](approve-network-requests.md) for real-time operator approval.
- [Network Policies](../reference/network-policies.md) for the full baseline policy reference.
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ NemoClaw keeps its operator-facing state on the host rather than inside the sand

| Path | Purpose |
|---|---|
| `~/.nemoclaw/credentials.json` | Provider credentials saved during onboarding. |
| `~/.nemoclaw/credentials.json` | Provider credentials saved during onboarding (plaintext, mode `0600`). See [Credential Storage](../security/credential-storage.md). |
| `~/.nemoclaw/sandboxes.json` | Registered sandbox metadata, including the default sandbox selection. |
| `~/.openclaw/openclaw.json` | Host OpenClaw configuration that NemoClaw snapshots or restores during migration flows. |

Expand Down
27 changes: 18 additions & 9 deletions docs/reference/network-policies.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,9 @@ The following endpoint groups are allowed by default:
- All methods

* - `github`
- `github.com:443`
- `github.com:443`, `api.github.com:443`
- `/usr/bin/gh`, `/usr/bin/git`
- All methods, all paths

* - `github_rest_api`
- `api.github.com:443`
- `/usr/bin/gh`
- GET, POST, PATCH, PUT, DELETE
- `access: full` (no HTTP inspection — CONNECT tunnel)

* - `clawhub`
- `clawhub.ai:443`
Expand All @@ -91,13 +86,27 @@ The following endpoint groups are allowed by default:
* - `npm_registry`
- `registry.npmjs.org:443`
- `/usr/local/bin/openclaw`, `/usr/local/bin/npm`, `/usr/local/bin/node`
- All methods, all paths
- `access: full` (no HTTP inspection — CONNECT tunnel)

* - `telegram`
- `api.telegram.org:443`
- Any binary
- `/usr/local/bin/node`
- GET, POST on `/bot*/**`

* - `discord`
- `discord.com:443`, `gateway.discord.gg:443`, `cdn.discordapp.com:443`
- `/usr/local/bin/node`
- REST API allows GET and POST.
WebSocket gateway uses `access: full`.
CDN allows GET only.

:::

:::{note}
Endpoints with `access: full` use a raw CONNECT tunnel with no HTTP-layer inspection.
Method and path restrictions cannot be enforced on these endpoints.
The `github` policy uses `access: full` because `git` requires CONNECT tunneling.
See [Security Best Practices](../security/best-practices.md) for details on the L4-only vs L7 inspection trade-off.
:::

All endpoints use TLS termination and are enforced at port 443.
Expand Down
153 changes: 153 additions & 0 deletions docs/security/credential-storage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
---
title:
page: "Credential Storage Security"
nav: "Credential Storage"
description:
main: "Security guidance for the ~/.nemoclaw/credentials.json file, including file permissions, rotation, and best practices."
agent: "Documents security guidance for credential storage at ~/.nemoclaw/credentials.json. Use when reviewing credential security, file permissions, or key rotation practices."
keywords: ["nemoclaw credential storage", "credentials.json security permissions"]
topics: ["generative_ai", "ai_agents"]
tags: ["nemoclaw", "security", "credentials"]
content:
type: reference
difficulty: technical_beginner
audience: ["developer", "engineer", "security_engineer"]
status: published
---

<!--
SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: Apache-2.0
-->

# Credential Storage Security

NemoClaw stores API keys and tokens on disk at `~/.nemoclaw/credentials.json`.
This page covers the file layout, permission model, and best practices for securing, rotating, and auditing stored credentials.

## Location

NemoClaw stores provider API keys and tokens at:

```text
~/.nemoclaw/credentials.json (mode 0600, owner-only read/write)
```

The directory `~/.nemoclaw/` is created with mode `0700` (owner-only access).

## Plaintext Warning

Credentials are stored as plaintext JSON.
The file relies on Unix file permissions (`0600`) for access control.
There is no encryption at rest.

```json
{
"NVIDIA_API_KEY": "nvapi-...",
"GITHUB_TOKEN": "ghp_...",
"ANTHROPIC_API_KEY": "sk-ant-..."
}
```

NemoClaw enforces `0600` permissions on every write (see `bin/lib/credentials.js`).
The CLI also rejects unsafe `HOME` directories (`/tmp`, `/var/tmp`, `/dev/shm`, `/`) to prevent credential storage in world-readable locations.

## Security Recommendations

### File Permissions

Verify that permissions are correct:

```console
$ ls -la ~/.nemoclaw/credentials.json
# Expected: -rw------- 1 <user> <group> ... credentials.json
```

If permissions are wrong, fix them:

```console
$ chmod 700 ~/.nemoclaw && chmod 600 ~/.nemoclaw/credentials.json
```

### Do Not Commit to Version Control

Add `~/.nemoclaw/` to your global gitignore:

```console
$ echo '.nemoclaw/' >> ~/.gitignore_global
$ git config --global core.excludesFile ~/.gitignore_global
```

### Exclude from Backups and Cloud Sync

Prevent credential files from being copied to less-secure locations:

```console
$ echo '.nemoclaw/' >> ~/.backupignore
```

If using Dropbox, iCloud, or similar cloud sync services, exclude the directory from syncing.

### Use Environment Variables in CI/CD

For CI/CD pipelines, prefer environment variables over stored credentials.
NemoClaw checks environment variables first before reading `credentials.json` (see `bin/lib/credentials.js`):

```console
$ export NVIDIA_API_KEY=nvapi-...
$ nemoclaw onboard
```

### Rotate Keys Regularly

Use API keys with expiration where possible.
Rotate long-lived keys quarterly at minimum.

## Credential Rotation

Re-run onboarding to update stored keys:

```console
$ nemoclaw onboard
```

Or edit the file directly (permissions are preserved on save by the CLI):

```console
$ vi ~/.nemoclaw/credentials.json
```

## Deleting Credentials

Remove all stored credentials:

```console
$ rm ~/.nemoclaw/credentials.json
```

Remove all NemoClaw configuration and credentials:

```console
$ rm -rf ~/.nemoclaw/
```

## Audit

Check current file permissions and ownership:

```console
$ ls -la ~/.nemoclaw/
$ ls -la ~/.nemoclaw/credentials.json
```

Expected output:

```text
drwx------ ... .nemoclaw/
-rw------- ... credentials.json
```

## Next Steps

- [Architecture](../reference/architecture.md) for the full host-side state and config reference.
- [Security Best Practices](best-practices.md) for the complete security controls framework.