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:
- Is this domain/IP on the allow list? → Let it through.
- Is this domain/IP on the deny list? → Block it, log it.
- 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.
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
| Preset | What it allows | Best for |
|---|---|---|
minimal | Model API only (Anthropic or OpenAI), nothing else | Chat-only use with no integrations |
standard | Model API + Telegram + GitHub | Most users — personal assistant + dev tasks |
full | Model API + all common services (Gmail, Slack, Discord, WhatsApp, GitHub, web search) | Power users — lock down after confirming everything works |
custom | Start with nothing, build your own allow list | Security-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
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.
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