ZeroClaw enforces security at every layer — not just the sandbox. It passes all items from the community security checklist, covering network exposure, authentication, filesystem access, and inbound message control.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/openagen/zeroclaw/llms.txt
Use this file to discover all available pages before exploring further.
Security checklist
| # | Item | Status | How |
|---|---|---|---|
| 1 | Gateway not publicly exposed | ✅ | Binds 127.0.0.1 by default. Refuses 0.0.0.0 without a tunnel or explicit allow_public_bind = true. |
| 2 | Pairing required | ✅ | 6-digit one-time code on startup. Exchange via POST /pair for a bearer token. All /webhook requests require Authorization: Bearer <token>. |
| 3 | Filesystem scoped (no /) | ✅ | workspace_only = true by default. 14 system dirs + 4 sensitive dotfiles blocked. Null byte injection blocked. Symlink escape detection via canonicalization and resolved-path workspace checks in file read/write tools. |
| 4 | Access via tunnel only | ✅ | Gateway refuses public bind without an active tunnel. Supports Tailscale, Cloudflare, ngrok, or any custom tunnel. |
Channel allowlists
Inbound sender policy is deny-by-default across all channels:- Empty allowlist — deny all inbound messages
"*"— allow all (explicit opt-in)- Any other value — exact-match allowlist
| Channel | Allowlist value |
|---|---|
| Telegram | Your @username (without @) or your numeric user ID |
| Discord | Your Discord user ID |
| Slack | Your Slack member ID (starts with U) |
| Mattermost | Your Mattermost user ID |
| Nostr | Your sender public key (hex or npub) |
Telegram operator-approval flow
Whenallowed_users is empty, unauthorized senders receive a hint with a copyable operator command. The operator runs the command locally, then the user retries.
Start with deny-by-default
Set
[channels_config.telegram].allowed_users = [] before starting the agent.ignoring message from unauthorized user in logs, rerun channel setup only:
Encrypted secrets
API keys and credentials are encrypted at rest using a local key file when[secrets].encrypt = true (the default):
api_key value stored in config is encrypted before being written to disk. The key file never leaves the local machine.
Related pages
- Sandboxing: filesystem scoping and runtime isolation —
workspace_only, blocked paths, Docker runtime, and Linux Landlock - Gateway pairing and bearer token auth — how pairing works, bearer tokens, and the full gateway API reference