Basic Configuration
Minimal secure openclaw.json covering the security baseline (Phase 3), a single WhatsApp channel routing to the main agent (Phase 4), and isolated web search delegation (Phase 5). Two agents only: main + search. Uses JSON5 comments for inline documentation — OpenClaw supports JSON5 natively.
For production deployments with Docker sandboxing, egress allowlisting, multiple channels, and image generation — see Recommended Configuration .
Three deployment postures are covered: Docker isolation (this config), macOS VM isolation (remove sandbox blocks), and Linux VM isolation (keep sandbox blocks). See Phase 3 — Security for the full trade-off analysis.
{
// ============================================================
// OpenClaw Configuration — Basic Setup
// ============================================================
// NOTE: This file uses JSON5 comments (//) for documentation.
// OpenClaw supports JSON5 natively — no need to strip comments.
//
// Minimal secure setup covering:
// - Security baseline (Phase 3)
// - Two agents: main + search (Phases 4-5)
// - Single channel: WhatsApp (Phase 4)
// - Web search delegation (Phase 5)
//
// NOT included (see recommended example for these):
// - Docker sandboxing with egress allowlisting (see recommended example)
// - Dedicated channel agents (defense-in-depth — channels route to main here)
// - Signal / Google Chat channels
// - Image generation plugin
// - Deterministic guard plugins (file-guard, network-guard, command-guard)
// — see hardened-multi-agent.md for the maximum-security configuration
//
// DEPLOYMENT OPTIONS:
// Docker isolation — Dedicated OS user + Docker (this config): stronger
// internal agent isolation via Docker sandboxing.
// VM: macOS VMs — Lume / Parallels: stronger host isolation, no Docker inside VM.
// Remove all "sandbox" blocks; tool policy provides internal isolation.
// VM: Linux VMs — Multipass / KVM: strongest combined posture (VM boundary + Docker).
// Keep "sandbox" blocks — Docker works inside Linux VMs.
// See Phase 3 — Security for the full trade-off analysis.
//
// Replace placeholder values:
// +46XXXXXXXXX → your phone number
// Workspace paths → your actual paths
//
// Environment variables (set in LaunchAgent plist or systemd EnvironmentFile, or LaunchDaemon for hardened setup):
// OPENCLAW_GATEWAY_TOKEN
// ANTHROPIC_API_KEY
// BRAVE_API_KEY (or OPENROUTER_API_KEY for Perplexity)
// OPENROUTER_API_KEY (required for content-guard)
// See Phase 6 — Deployment > Secrets Management for details.
// ============================================================
// --- Chat Commands ---
// Disable dangerous chat commands. These allow users to
// run shell commands, edit config, or restart the gateway
// from within a chat message.
"commands": {
"native": "auto",
"nativeSkills": "auto",
"bash": false, // Blocks !command shell access
"config": false, // Blocks /config writes
"debug": false, // Blocks /debug runtime overrides
"restart": false // Blocks /restart
},
// --- Global Tool Restrictions ---
"tools": {
// Only deny tools globally that NO agent should ever have.
// web_search, web_fetch, browser are denied per-agent (not here) —
// global deny overrides agent-level allow, which would break the search agent.
"deny": ["canvas", "gateway"],
// Disable elevated mode — prevents sandbox escape
"elevated": { "enabled": false },
// Sandbox tool policy — the default allow list excludes message and memory tools.
// WhatsApp DMs and all non-main sessions are sandboxed with mode:"non-main".
// alsoAllow does NOT work with the default policy — must provide the full allow list.
"sandbox": {
"tools": {
"allow": [
"exec", "process", "read", "write", "edit", "apply_patch", "image",
"sessions_list", "sessions_history", "sessions_send", "sessions_spawn",
"subagents", "session_status",
"message",
"memory_search", "memory_get"
]
}
},
// Web search provider config (accessible only to agents that allow the tool)
"web": {
"search": {
"enabled": true,
"provider": "brave",
"apiKey": "${BRAVE_API_KEY}"
// Alternative: Perplexity via OpenRouter
// "provider": "perplexity",
// "perplexity": {
// "apiKey": "${OPENROUTER_API_KEY}",
// "baseUrl": "https://openrouter.ai/api/v1",
// "model": "perplexity/sonar-pro"
// }
}
}
},
// --- Skills ---
// Only allow known-good bundled skills. No skill installer configured
// means no new skills can be added from ClawHub.
"skills": {
"allowBundled": ["coding-agent", "github", "healthcheck", "weather"]
},
// --- Session Isolation ---
"session": {
// Each sender on each channel gets their own isolated session
"dmScope": "per-channel-peer",
// Inter-agent communication settings
"agentToAgent": {
"maxPingPongTurns": 5
}
},
// --- Agents ---
"agents": {
"defaults": {
// Pre-compaction memory flush — saves important context to memory before compacting.
// Without this, the agent forgets everything from the compacted conversation portion.
// Flush triggers silently when token estimate nears the reserve floor.
"compaction": {
"mode": "safeguard",
"reserveTokensFloor": 20000,
"memoryFlush": {
"enabled": true,
"softThresholdTokens": 4000,
"systemPrompt": "Session nearing compaction. Store durable memories now.",
"prompt": "Write any lasting notes to memory/YYYY-MM-DD.md; reply with NO_REPLY if nothing to store."
}
},
// Memory search — semantic + keyword hybrid search across memory files.
// Local provider: no API key, ~600MB disk, full privacy (nothing leaves your machine).
// Remote alternatives: "openai", "gemini", "voyage" (require separate API keys).
// See Phase 2 — Memory for full provider comparison.
"memorySearch": {
"enabled": true,
"provider": "local",
"query": {
"hybrid": {
"enabled": true,
"vectorWeight": 0.7,
"textWeight": 0.3
}
},
"cache": {
"enabled": true,
"maxEntries": 50000
}
},
"maxConcurrent": 4,
"subagents": {
"maxConcurrent": 8,
"model": "anthropic/claude-sonnet-4-5",
"thinking": "low"
},
// Default sandbox (Docker isolation / Linux VMs): non-main sessions run in Docker with no network.
// macOS VM isolation: remove this block — no Docker available inside macOS VM.
// Linux VM isolation: keep this block — Docker works inside Linux VMs.
"sandbox": {
"mode": "non-main",
"scope": "agent",
"workspaceAccess": "rw"
}
},
"list": [
{
// MAIN AGENT — operator access via Control UI / CLI
// Full tool access except web tools. WhatsApp routes here automatically
// (no bindings needed — main is the default agent).
// Web access delegated to search agent via sessions_send.
"id": "main",
"default": true,
"workspace": "/Users/openclaw/.openclaw/workspaces/main",
"tools": {
"deny": ["web_search", "web_fetch", "browser", "nodes"]
},
"subagents": { "allowAgents": ["search"] }
},
{
// SEARCH AGENT — isolated web search + content processing
// Only reachable via sessions_send from main agent.
// No channel binding = can't be messaged directly.
// No filesystem tools — nothing to read or exfiltrate.
// Tool policy provides isolation — no filesystem tools to abuse.
// Unsandboxed — workaround for #9857 (sessions_spawn broken when both agents sandboxed + per-agent tools).
"id": "search",
"workspace": "/Users/openclaw/.openclaw/workspaces/search",
"agentDir": "/Users/openclaw/.openclaw/agents/search/agent",
"model": "anthropic/claude-sonnet-4-5",
"tools": {
"allow": ["web_search", "web_fetch", "sessions_send", "session_status"],
"deny": ["exec", "read", "write", "edit", "apply_patch", "process", "browser", "gateway", "cron"]
},
"subagents": { "allowAgents": [] },
"sandbox": {
"mode": "off"
}
}
]
},
// --- Channel Configuration ---
// No bindings section — unbound channels auto-route to the default agent (main).
// For dedicated channel agents with restricted tools (defense-in-depth),
// see the recommended example.
"channels": {
"whatsapp": {
"dmPolicy": "pairing",
"selfChatMode": false,
"allowFrom": ["+46XXXXXXXXX"], // REPLACE with real number — placeholder causes silent message drops
"groupPolicy": "allowlist",
"groups": { "*": { "requireMention": true } }, // Bug #11758: broken on WhatsApp (LID transition) — use false + mentionPatterns as workaround
"mediaMaxMb": 50,
"debounceMs": 0
}
},
// --- Gateway ---
"gateway": {
"port": 18789,
"mode": "local",
"bind": "loopback",
"auth": {
"mode": "token",
"token": "${OPENCLAW_GATEWAY_TOKEN}"
}
},
// --- Network Discovery ---
"discovery": {
"mdns": { "mode": "minimal" }
},
// --- Logging ---
"logging": {
"redactSensitive": "tools",
"redactPatterns": ["pplx-[A-Za-z0-9]+"]
},
// --- Plugins ---
"plugins": {
// Only allow these plugins to load. Without this, any plugin dropped into
// ~/.openclaw/extensions/ loads automatically at startup.
"allow": ["whatsapp", "content-guard", "channel-guard"],
"entries": {
"whatsapp": { "enabled": true },
"content-guard": {
// LLM-based injection scanning at the sessions_send trust boundary.
// Guards search→main: prevents poisoned web content from compromising main.
// Requires OPENROUTER_API_KEY. Fails closed — no failOpen option.
"enabled": true,
"config": {
"model": "anthropic/claude-haiku-4-5",
"maxContentLength": 50000,
"timeoutMs": 15000
}
},
"channel-guard": {
"enabled": true,
"config": {
"model": "anthropic/claude-haiku-4-5",
"maxContentLength": 10000,
"timeoutMs": 10000,
"failOpen": false,
"warnThreshold": 0.4,
"blockThreshold": 0.8
}
}
}
}
}Last updated on