Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 4 additions & 2 deletions docs/reference/commands.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -528,13 +528,14 @@ It then prompts for optional web search and messaging channels, builds and start
<AgentOnly variant="deepagents">
It then prompts for optional web search, builds and starts the sandbox, and asks for a **policy tier** that controls the default set of network policy presets applied to the sandbox.
</AgentOnly>
Three tiers are available:
Four tiers are available:

| Tier | Description |
|------|-------------|
| Restricted | No tier defaults. Web search or other integrations selected earlier can still add their required presets; deselect them during policy review for baseline-only access. |
| Balanced (default) | Full dev tooling and a selected, supported web search provider. Package installs, model downloads, and inference. No messaging platform access by default. |
| Open | Broad access across third-party services including supported messaging and productivity presets. Agent-specific unsupported presets are filtered out. |
| Personal | Lets every sandbox binary open TCP connections to public and private address ranges on destination ports 80 and 443. Unspecified, loopback, and link-local ranges remain blocked. Also selects every maintained preset supported by the active agent. Intended only for trusted personal-use workloads. |

After selecting a tier, the wizard shows a combined preset and access-mode screen where you can include or exclude individual presets and toggle each between read and read-write access.
For details on tiers and the presets each includes, refer to [Network Policies](network-policies#policy-tiers).
Expand All @@ -549,7 +550,7 @@ NEMOCLAW_POLICY_TIER=restricted $$nemoclaw onboard --non-interactive --yes-i-acc
```

Unset, blank, or whitespace-only `NEMOCLAW_POLICY_TIER` values use the `balanced` default.
In non-interactive mode, any non-blank value must be one of `restricted`, `balanced`, or `open`; otherwise onboarding exits before preflight, gateway, or inference side effects with an error listing the valid options.
In non-interactive mode, any non-blank value must be one of `restricted`, `balanced`, `open`, or `personal`; otherwise onboarding exits before preflight, gateway, or inference side effects with an error listing the valid options.
Interactive onboarding ignores an invalid environment value and shows the normal tier prompt.

`NEMOCLAW_POLICY_MODE` controls how non-interactive onboarding reconciles the tier-derived suggestions against the sandbox's currently-applied presets.
Expand All @@ -560,6 +561,7 @@ Onboarding removes any preset that is not in the list.
`skip` leaves the applied set untouched and does not apply tier defaults.
NemoClaw filters tier suggestions and resume selections by active agent support and the selected web search provider.
During automatic suggestion and resume reconciliation, it removes stale web-search selections when they conflict with the active agent or selected provider.
The Personal tier is the exception: it preserves every applicable maintained web-search preset even when onboarding did not configure that provider.
<AgentOnly variant="hermes">
For Hermes, this includes replacing stale `nous-web` when Tavily is selected.
</AgentOnly>
Expand Down
27 changes: 23 additions & 4 deletions docs/reference/network-policies.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,26 @@ This is the supported registry-backed way to replay a live exact-key removal dur
| Restricted | No tier defaults | Starts from the baseline policy. Web search or messaging integrations selected earlier can still suggest their required presets; deselect them during policy review for baseline-only access. Restricted suppresses other agent-required additions; reapply them later with `policy add` only after reviewing the additional egress. |
| Balanced (default) | `npm`, `pypi`, `huggingface`, `brew`, selected `brave` or `tavily` web search preset | Full dev tooling and web search when you select a provider the active agent supports. No messaging platform access. Apply the `weather` preset explicitly if your agent needs read-only weather lookups. |
| Open | `npm`, `pypi`, `huggingface`, `brew`, selected `brave` or `tavily` web search preset, `weather`, `public-reference`, `slack`, `discord`, `telegram`, `wechat` (experimental), `whatsapp` (experimental), `jira`, `outlook` | Broad access across third-party services including messaging, productivity, weather, and public-reference APIs. |
| Personal | `personal-open-internet` and every maintained preset supported by the active agent | Lets every sandbox binary open TCP connections to public and private address ranges on destination ports `80` and `443`. Unspecified, loopback, and link-local ranges remain blocked. Also selects every maintained preset applicable to the active agent. |

<Warning title="Personal Tier Network Access">
The Personal tier applies the `personal-open-internet` policy preset with a hostless L4 endpoint on destination ports `80` and `443`.
The policy matches any requested host on either port, then permits the connection only when every resolved address is in the preset's allowed ranges.
The rule does not inspect the application protocol or payload, so traffic on these ports is not limited to HTTP or HTTPS.
OpenShell does not restrict the hostname, HTTP method, path, or body after the rule permits the connection.
An agent can send workspace data or sandbox-visible credentials to an arbitrary reachable service on either port without an operator approval prompt.

The preset excludes unspecified, loopback, and link-local address ranges, including the common cloud metadata range.
OpenShell also keeps its hard blocks for those destinations.
Other destination ports remain denied unless another policy entry permits them.
The sandbox's filesystem, process, gateway authentication, and managed credential controls remain active.
Use this tier only for trusted personal workloads with trusted prompts and data.
</Warning>

After selecting a tier, a combined preset and access-mode screen lets you include or exclude individual presets and toggle each between read (GET only) and read-write (GET + POST/PUT/PATCH) access.
Tier-default presets are pre-selected; additional presets can be added from the built-in preset list available to the sandbox's active agent.
NemoClaw filters tier defaults and built-in preset choices by the active agent's supported integrations.
The `personal-open-internet` preset uses L4 passthrough, so its read-write label does not add HTTP method or path inspection.
<AgentOnly variant="openclaw">
OpenClaw can select `brave` or `tavily`, while Hermes can select `tavily` only.
</AgentOnly>
Expand All @@ -150,25 +166,27 @@ Hermes can select `tavily` only.
Deep Agents can use the maintained `tavily` opt-in path, but messaging channel presets are omitted because the terminal harness does not run a NemoClaw messaging bridge today.
</AgentOnly>
NemoClaw automatically suggests the preset that matches the selected provider and removes stale web search presets during resume reconciliation when you switch providers or disable web search.
The Personal tier instead keeps every applicable maintained web-search preset selected by default.
Explicit custom preset lists and manual interactive selections remain operator-controlled.
<AgentOnly variant="hermes">
Hermes managed-tool gateway selections can add Hermes-specific presets, such as Nous-hosted web, image, audio, browser, or code tools, without applying unsupported OpenClaw-only presets.
When Hermes uses Tavily, NemoClaw removes `nous-web` from the effective managed-tool selection while preserving other selected Nous tool presets.
</AgentOnly>
<AgentOnly variant="openclaw">
OpenClaw onboarding also adds the `openclaw-pricing` preset on top of tier defaults so session-cost records can populate from LiteLLM and OpenRouter without manual configuration.
When the OpenClaw OTEL diagnostics feature is enabled with a local endpoint, NemoClaw adds the `openclaw-diagnostics-otel-local` preset on the same basis.
On the Balanced and Open tiers, enabling OpenClaw OTEL diagnostics with a local endpoint adds the `openclaw-diagnostics-otel-local` preset.
The Personal tier selects that preset by default, while Restricted suppresses it during reconciliation.
</AgentOnly>
<AgentOnly variant="deepagents">
When LangChain Deep Agents Code is onboarded with `--observability`, NemoClaw adds the `observability-otlp-local` preset on Balanced and Open tiers.
When LangChain Deep Agents Code is onboarded with `--observability`, NemoClaw adds the `observability-otlp-local` preset on Balanced, Open, and Personal tiers.
The Restricted tier suppresses this agent-required preset during onboarding and rebuild reconciliation.
An operator can add it manually after reviewing the additional egress, but the next Restricted reconciliation removes it.
</AgentOnly>
The applied set therefore reflects the chosen tier *plus* any agent-required presets, so `policy list` may show one or more presets that do not appear in the tier table above.
The `policy list` provenance tags are inferred from the current tier YAML and the active agent at display time and are not persisted per preset.
A preset whose name matches an entry in the sandbox's current tier definition is labelled `[from <tier> tier]` even when an operator added it manually with `policy add` after onboarding; agent-specific preset names are only labelled `[from <agent> agent]` when the active agent matches.
Claude Code direct egress is not included in any policy tier.
If you install and run the Claude Code CLI inside the sandbox with its own credentials, apply the `claude-code` preset explicitly.
Claude Code direct egress is not included in the Restricted, Balanced, or Open tiers.
The Personal tier selects the `claude-code` preset by default; on other tiers, apply it explicitly if you install and run the Claude Code CLI inside the sandbox with its own credentials.
Normal NemoClaw Anthropic inference still routes through the OpenShell gateway.

Tier definitions are stored in `nemoclaw-blueprint/policies/tiers.yaml`.
Expand Down Expand Up @@ -217,6 +235,7 @@ For a safe host binding, policy recovery commands, and a runnable collector, ref
## Operator Approval Flow

When the agent attempts to reach an endpoint not listed in the policy, OpenShell intercepts the request and presents it in the TUI for operator review.
The Personal tier does not prompt for matching TCP connections on destination ports `80` or `443` because `personal-open-internet` already permits them.
The flow has these steps:

1. The agent makes a network request to an unlisted host.
Expand Down
23 changes: 22 additions & 1 deletion docs/security/best-practices.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ flowchart TB
## Network Controls

NemoClaw controls which hosts, ports, and HTTP methods the sandbox can reach, and lets you approve or deny requests in real time.
Network policy allowlists do not disable OpenShell's SSRF guard, so internal-address blocking remains active even when an endpoint matches an egress rule.
OpenShell hard-blocks unspecified, loopback, and link-local destinations, including the common cloud metadata range.
An endpoint with `allowed_ips` can explicitly permit other private ranges, so treat that field as a server-side request forgery (SSRF) boundary change.

OpenShell provides additional network enforcement mechanisms not covered here, including network namespace isolation, SSRF protection, TLS auto-detection and termination, and audit-vs-enforce modes.
Refer to the [Network Controls](https://docs.nvidia.com/openshell/latest/security/best-practices.html#network-controls) section of the OpenShell Security Best Practices.
Expand Down Expand Up @@ -222,6 +223,7 @@ NemoClaw ships preset policy files in `nemoclaw-blueprint/policies/presets/` for
| `local-inference` | Local Ollama and vLLM through the host gateway. | Allows sandbox access to host-side local inference ports covered by the preset. |
| `npm` | npm and Yarn registries via L4 pass-through. | Allows installing arbitrary npm packages, which may contain malicious code. OpenShell still gates by host, port, and binary, but does not inspect HTTP method, path, or body for this preset. |
| `outlook` | Microsoft 365, Outlook. | Gives agent access to email. |
| `personal-open-internet` | TCP connections to public and private address ranges on destination ports `80` and `443` from every sandbox binary. | Removes hostname, binary, application protocol, HTTP method, path, and request-body restrictions for matching connections. An agent can send sandbox-visible data to an arbitrary reachable service on either port without another approval prompt. |
| `pypi` | Python Package Index (GET and HEAD only). | Allows installing arbitrary Python packages, which may contain malicious code. Publishing is blocked. |
| `slack` | Slack API, Socket Mode, webhooks. | WebSocket uses `access: full`. Agent can post to any channel the bot token has access to. |
| `tavily` | Tavily Search API. | Agent can submit search queries and extraction targets to Tavily. The preset allows only `POST /search` and `POST /extract` from the maintained agent runtimes and enables request-body credential rewriting when the agent sends the placeholder in JSON. |
Expand All @@ -230,6 +232,16 @@ NemoClaw ships preset policy files in `nemoclaw-blueprint/policies/presets/` for
Apply presets only when the agent's task requires the integration.
Review the preset's YAML file before applying to understand the endpoints, methods, and binary restrictions it adds.

<Warning title="Personal Tier">
The Personal tier selects `personal-open-internet` and every maintained preset supported by the active agent.
The open-internet preset allows every sandbox binary to reach public and private address ranges on destination ports `80` and `443` through L4 passthrough.
Traffic on those ports is not limited to HTTP or HTTPS.
OpenShell does not inspect the hostname, application protocol, HTTP method, path, or body for those connections.
The preset excludes unspecified, loopback, and link-local ranges, and other ports remain denied unless another entry permits them.
Use it only for trusted personal workloads with trusted prompts and data.
The sandbox's filesystem, process, gateway authentication, and managed credential controls remain active.
</Warning>

### Web Search Credential Rewriting

NemoClaw registers each selected web search credential in a sandbox-scoped OpenShell provider and writes a resolver placeholder into the agent configuration.
Expand Down Expand Up @@ -898,6 +910,15 @@ Use when the agent needs package registries, Docker Hub, or broader GitHub acces
- Review the agent's network activity periodically with `openshell term`.
- Use operator approval for any endpoint not covered by a preset.

### Personal

Use only for a trusted single-user sandbox that needs arbitrary TCP egress on destination ports `80` and `443`.

- Select the Personal tier during onboarding.
- Treat every prompt, downloaded package, webpage, and workspace file as able to trigger external TCP traffic on destination ports `80` and `443`.
- Do not place raw credentials or sensitive data in the sandbox unless the agent must use them.
- Return to Balanced or Restricted and recreate the sandbox when this broad egress is no longer required.

### Integration Testing

Use when the agent talks to internal APIs or third-party services during testing.
Expand Down
49 changes: 49 additions & 0 deletions nemoclaw-blueprint/policies/presets/personal-open-internet.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

preset:
name: personal-open-internet
description: "Broad TCP egress on destination ports 80 and 443 for trusted personal sandboxes"

network_policies:
personal_open_internet:
name: personal_open_internet
endpoints:
# OpenShell treats a hostless endpoint with allowed_ips as matching any
# requested host on these ports. It resolves the requested host and checks
# every address against the listed ranges. Omitting protocol keeps the
# connection at L4, without application protocol, HTTP method, or path
# inspection.
- ports: [80, 443]
allowed_ips:
- 1.0.0.0/8
- 2.0.0.0/7
- 4.0.0.0/6
- 8.0.0.0/5
- 16.0.0.0/4
- 32.0.0.0/3
- 64.0.0.0/3
- 96.0.0.0/4
- 112.0.0.0/5
- 120.0.0.0/6
- 124.0.0.0/7
- 126.0.0.0/8
- 128.0.0.0/3
- 160.0.0.0/5
- 168.0.0.0/8
- 169.0.0.0/9
- 169.128.0.0/10
- 169.192.0.0/11
- 169.224.0.0/12
- 169.240.0.0/13
- 169.248.0.0/14
- 169.252.0.0/15
- 169.255.0.0/16
- 170.0.0.0/7
- 172.0.0.0/6
- 176.0.0.0/4
- 192.0.0.0/2
- 2000::/3
- fc00::/7
binaries:
- { path: "/**" }
40 changes: 39 additions & 1 deletion nemoclaw-blueprint/policies/tiers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
#
# access values:
# read — GET only (or equivalent read-only rules for that service)
# read-write — GET + POST/PUT/PATCH (explicitly opt-in; never the default)
# read-write — GET + POST/PUT/PATCH (must be explicit in the tier definition)
#
# A preset can define stricter or broader native OpenShell behavior than this
# display-level access label. The Personal internet preset uses L4 passthrough.

tiers:
- name: restricted
Expand Down Expand Up @@ -46,3 +49,38 @@ tiers:
- { name: teams, access: read-write }
- { name: jira, access: read-write }
- { name: outlook, access: read-write }

- name: personal
label: Personal
description: Trusted personal-use posture. Lets every sandbox binary open TCP connections to public and private address ranges on destination ports 80 and 443. Unspecified, loopback, and link-local ranges remain blocked. Also enables every maintained preset that applies to the selected agent. Do not use with untrusted prompts or data.
presets:
- { name: personal-open-internet, access: read-write }
Comment thread
coderabbitai[bot] marked this conversation as resolved.
- { name: npm, access: read-write }
- { name: pypi, access: read-write }
- { name: huggingface, access: read-write }
- { name: brew, access: read-write }
- { name: brave, access: read-write }
- { name: tavily, access: read-write }
- { name: weather, access: read-write }
- { name: public-reference, access: read-write }
- { name: github, access: read-write }
- { name: gmail, access: read-write }
- { name: jira, access: read-write }
- { name: outlook, access: read-write }
- { name: claude-code, access: read-write }
- { name: local-inference, access: read-write }
- { name: openclaw-pricing, access: read-write }
- { name: openclaw-diagnostics-otel-local, access: read-write }
- { name: observability-otlp-local, access: read-write }
- { name: nous-web, access: read-write }
- { name: nous-image, access: read-write }
- { name: nous-audio, access: read-write }
- { name: nous-browser, access: read-write }
- { name: nous-code, access: read-write }
- { name: slack, access: read-write }
- { name: discord, access: read-write }
- { name: telegram, access: read-write }
- { name: googlechat, access: read-write }
- { name: wechat, access: read-write }
- { name: whatsapp, access: read-write }
- { name: teams, access: read-write }
Loading
Loading