Last updated: 2026-04-06

OpenShell Policy Configuration — Expand Your Sandbox Permissions

OpenShell's policy engine is what separates NemoClaw from a regular OpenClaw install. Every outbound network call, file access, and environment variable your agent touches goes through a deny-by-default rule engine. This guide explains how it works, how to expand it, and how to troubleshoot denials without turning off security to do it.

How the Policy Engine Works

When OpenClaw (running inside the NemoClaw sandbox) makes a network request, OpenShell intercepts it and checks it against your policy file. The decision tree is simple:

  1. Is this domain/IP on the allow list? → Let it through.
  2. Is this domain/IP on the deny list? → Block it, log it.
  3. Neither? → Block it (deny by default), log it.

The same logic applies to filesystem paths and environment variables. The sandbox cannot read a file path or an env var that isn't explicitly granted. This is what makes NemoClaw fundamentally different from plain OpenClaw: even if your agent's code is compromised, it can only reach what you've granted.

Policy changes require a reload — not a restart

You don't need to restart the NemoClaw gateway to apply policy changes. Run openShell policy reload and the new rules take effect within seconds. Active sessions continue uninterrupted.

Policy File Location and Format

Policy files live at ~/.openShell/policies/ on the host (outside the sandbox). There's one main file and an optional directory for modular includes:

~/.openShell/
  policies/
    main.yaml          # primary policy file
    includes/
      gmail.yaml       # modular service policies
      github.yaml
      custom.yaml

YAML Format

# ~/.openShell/policies/main.yaml

version: "1"
sandbox: nemoclaw   # which sandbox these rules apply to

network:
  default: deny     # block everything not listed

  allow:
    # Anthropic API (required for Claude models)
    - host: "api.anthropic.com"
      ports: [443]
      comment: "Claude API"

    # OpenAI API (if you use OpenAI models)
    - host: "api.openai.com"
      ports: [443]
      comment: "OpenAI API"

    # Telegram Bot API (if Telegram channel is enabled)
    - host: "api.telegram.org"
      ports: [443]
      comment: "Telegram Bot API"

  deny:
    # Explicitly block known exfiltration endpoints
    - host: "*.ngrok.io"
      comment: "Block ngrok tunnels"

filesystem:
  default: deny

  allow:
    # The sandbox workspace (read/write)
    - path: "~/.openclaw/workspace"
      mode: "rw"

    # Log directory (write only)
    - path: "~/.openclaw/logs"
      mode: "w"

  deny:
    # Never allow access to SSH keys
    - path: "~/.ssh"
      comment: "Protect SSH keys"

env:
  # Env vars the sandbox can read
  allow:
    - HOME
    - PATH
    - LANG
  # API keys are managed via the provider registry — never exposed directly
  deny:
    - "*_API_KEY"
    - "*_SECRET"
    - "*_TOKEN"

The deny list in env uses shell glob patterns. This ensures no API key or secret variable leaks into the sandbox even if something inside tries to read it — the provider registry handles key injection separately.

Policy Presets

During install, the NemoClaw wizard asks which preset to start with. You can also switch presets at any time:

openShell policy preset list
openShell policy preset apply standard   # apply a preset
PresetWhat it allowsBest for
minimalModel API only (Anthropic or OpenAI), nothing elseChat-only use with no integrations
standardModel API + Telegram + GitHubMost users — personal assistant + dev tasks
fullModel API + all common services (Gmail, Slack, Discord, WhatsApp, GitHub, web search)Power users — lock down after confirming everything works
customStart with nothing, build your own allow listSecurity-conscious users who want exact control

Start with standard and add rules as you need them. Don't use full as your permanent config — it's a convenience preset for testing.

Adding Specific Service Policies

Gmail

Gmail IMAP/SMTP access requires two domains — one for IMAP (reading) and one for SMTP (sending):

# Add to network.allow in main.yaml (or a new includes/gmail.yaml)
- host: "imap.gmail.com"
  ports: [993]
  comment: "Gmail IMAP"
- host: "smtp.gmail.com"
  ports: [587]
  comment: "Gmail SMTP"
- host: "oauth2.googleapis.com"
  ports: [443]
  comment: "Gmail OAuth token refresh"

Then reload: openShell policy reload

WhatsApp

The WhatsApp channel in OpenClaw uses the Meta Business API. You need the Graph API endpoint and the webhook validation domain:

- host: "graph.facebook.com"
  ports: [443]
  comment: "WhatsApp Business API"
- host: "*.fbcdn.net"
  ports: [443]
  comment: "WhatsApp media delivery (optional)"

WhatsApp Business API requires a Meta Business account and approved phone number — see the OpenClaw channels config for setup details.

GitHub

- host: "api.github.com"
  ports: [443]
  comment: "GitHub REST API"
- host: "github.com"
  ports: [443]
  comment: "GitHub main (for git operations)"

Slack

- host: "slack.com"
  ports: [443]
  comment: "Slack API"
- host: "*.slack.com"
  ports: [443]
  comment: "Slack subdomains (files, hooks)"

Web Search

- host: "api.perplexity.ai"
  ports: [443]
  comment: "Perplexity search API"
# Or for Brave Search:
- host: "api.search.brave.com"
  ports: [443]
  comment: "Brave Search API"

Apply the Changes

# Validate syntax before reloading
openShell policy validate

# Apply changes (no restart needed)
openShell policy reload

# Confirm active rules
openShell policy show --active

The Live Dashboard

OpenShell includes a real-time policy dashboard. It's served at your gateway URL + /openShell/dashboard:

# If your Caddy reverse proxy is at:
https://your-sandbox.yourdomain.com

# Dashboard is at:
https://your-sandbox.yourdomain.com/openShell/dashboard

The dashboard shows:

  • Live policy log — every allow/deny decision in real time with domain, port, and which sandbox process triggered it
  • Policy summary — count of active allow and deny rules, last reload timestamp
  • Top blocked domains — sorted by frequency; useful for finding what a skill needs that you haven't granted yet
  • Active sandbox processes — which components are running inside the sandbox

The dashboard is protected by the same gateway auth token as the OpenClaw UI. You don't need a separate login.

Troubleshooting Policy Denials

When a skill or agent action fails unexpectedly, the cause is usually a policy denial. The error from OpenClaw's side is often unhelpful ("connection refused" or a timeout). Check the policy log to see what was actually blocked:

# Show the last 50 policy decisions
openShell logs policy --last 50

# Filter to denials only
openShell logs policy --denied

# Follow live (useful while reproducing a failure)
openShell logs policy --follow

# Example output:
# [DENY] imap.gmail.com:993 — sandbox: nemoclaw — trigger: himalaya-skill — rule: network.default=deny
# [ALLOW] api.anthropic.com:443 — sandbox: nemoclaw — trigger: openclaw-gateway

Once you see the denied domain, add it to your policy file and reload. The agent can retry immediately after reload — no need to re-trigger the full action.

Wildcard host rules — use carefully

Rules like *.amazonaws.com or *.googleapis.com allow access to a very broad set of services. Add the specific subdomain you need rather than wildcarding the whole TLD. Use the dashboard's "Top blocked domains" view to find the exact hostnames before adding rules.

Modular Policy Files with Includes

For large policy sets, split rules into per-service files:

# ~/.openShell/policies/main.yaml
version: "1"
sandbox: nemoclaw

network:
  default: deny
  include:
    - includes/model-providers.yaml
    - includes/telegram.yaml
    - includes/gmail.yaml
    - includes/github.yaml

filesystem:
  default: deny
  allow:
    - path: "~/.openclaw/workspace"
      mode: "rw"
# ~/.openShell/policies/includes/gmail.yaml
allow:
  - host: "imap.gmail.com"
    ports: [993]
  - host: "smtp.gmail.com"
    ports: [587]
  - host: "oauth2.googleapis.com"
    ports: [443]

Each include file only needs the allow/deny arrays — no need to repeat version or sandbox. This makes it easy to enable/disable a whole service by commenting out a single include line.

Policy Versioning

Policy files are plain text — put them in Git. If a policy change breaks something, roll back with:

cd ~/.openShell/policies
git log --oneline -10              # find the last good commit
git checkout abc1234 -- main.yaml  # restore that version
openShell policy reload            # apply immediately

← Back to NemoClaw hub · See also: Skills on NemoClaw · Switching Model Providers · OpenClaw Security Hardening