docs/book/src/security/overview.md
An agent that can execute shell commands, open URLs, and write files is a privileged process. ZeroClaw's security model sits on top of every tool call and every channel message, gating what the agent is actually allowed to do at runtime.
There are six layers. From outer to inner:
Before a message from a channel reaches the agent, the channel's pairing and allow-list are checked. allowed_users, allowed_chats, IP allowlists for webhooks — all enforced at the channel adapter, before the runtime sees the event.
Docs: each channel's page under Channels.
The coarse-grained knob. Three settings:
Docs: Autonomy levels.
The agent operates within a configured workspace directory. file_read, file_write, and shell (for commands that touch the filesystem) refuse paths outside it unless workspace_only = false.
Beyond the workspace, a forbidden_paths list (default: /etc, /sys, /boot, ~/.ssh, …) is always blocked regardless of workspace setting.
For shell invocations:
allowed_commands — if non-empty, shell only runs commands whose basename is in this listforbidden_commands — explicit denylist (rm -rf /, shutdown, kernel operations)validate_command_execution — a pattern-matching pass that looks for dangerous flags, pipelines, and argument shapesThe validator runs before the command hits the shell. A blocked command surfaces as a tool error the model sees and can react to.
When a sandbox backend is available, tool invocations run inside it:
| Platform | Default backend |
|---|---|
| Linux | Landlock (kernel) / Bubblewrap / Firejail / Docker — auto-detected |
| macOS | Seatbelt (native) |
| Windows | AppContainer (experimental) |
| Any | Docker (if the daemon is reachable) |
The sandbox confines filesystem access to the workspace, drops network reachability except what the tool explicitly needs, and removes access to the parent process's secrets.
Docs: Sandboxing.
Every tool invocation — whether it executed, was blocked, or required approval — produces a signed receipt in a chain. Each receipt includes the hash of the previous one, so tampering with any receipt invalidates the rest.
Receipts are the source of truth for "what did the agent do yesterday". They're readable, greppable, and durable.
Docs: Tool receipts.
Beyond the six layers:
[security.otp] gated_actions = ["shell", "browser", "file_write"] requires a one-time code before each listed action. Useful for remote-access scenarios.zeroclaw estop halts all in-flight tool calls. With [security.estop] enabled = true, resuming requires an OTP.A blocked tool call doesn't silently fail:
ToolResult::Err and hands it back to the modelrm -rf /" and can retry, apologise, or ask the userIf a channel is in a restricted tool set (tools_allow = [...]), the tool simply isn't advertised to the model for that channel. Model never sees a tool it can't use.
Out of the box:
Supervisedtruefalse (enable explicitly)falsefalseThis is a reasonable middle ground — safe enough for a laptop, permissive enough to not frustrate. Crank it up for production (OTP, audit, restricted tools) or down to YOLO for a dev box.