From bc4e32140cea1d1383c4a1a8380db3849f7d0716 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 27 Feb 2026 08:55:37 -0800 Subject: [PATCH] docs(cli): add skill capability security guidance --- docs/cli/security.md | 64 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 8 deletions(-) diff --git a/docs/cli/security.md b/docs/cli/security.md index cc705b31a30..ba903ce347e 100644 --- a/docs/cli/security.md +++ b/docs/cli/security.md @@ -25,20 +25,68 @@ openclaw security audit --json The audit warns when multiple DM senders share the main session and recommends **secure DM mode**: `session.dmScope="per-channel-peer"` (or `per-account-channel-peer` for multi-account channels) for shared inboxes. This is for cooperative/shared inbox hardening. A single Gateway shared by mutually untrusted/adversarial operators is not a recommended setup; split trust boundaries with separate gateways (or separate OS users/hosts). -It also emits `security.trust_model.multi_user_heuristic` when config suggests likely shared-user ingress (for example open DM/group policy, configured group targets, or wildcard sender rules), and reminds you that OpenClaw is a personal-assistant trust model by default. -For intentional shared-user setups, the audit guidance is to sandbox all sessions, keep filesystem access workspace-scoped, and keep personal/private identities or credentials off that runtime. It also warns when small models (`<=300B`) are used without sandboxing and with web/browser tools enabled. For webhook ingress, it warns when `hooks.defaultSessionKey` is unset, when request `sessionKey` overrides are enabled, and when overrides are enabled without `hooks.allowedSessionKeyPrefixes`. -It also warns when sandbox Docker settings are configured while sandbox mode is off, when `gateway.nodes.denyCommands` uses ineffective pattern-like/unknown entries (exact node command-name matching only, not shell-text filtering), when `gateway.nodes.allowCommands` explicitly enables dangerous node commands, when global `tools.profile="minimal"` is overridden by agent tool profiles, when open groups expose runtime/filesystem tools without sandbox/workspace guards, and when installed extension plugin tools may be reachable under permissive tool policy. -It also flags `gateway.allowRealIpFallback=true` (header-spoofing risk if proxies are misconfigured) and `discovery.mdns.mode="full"` (metadata leakage via mDNS TXT records). +It also warns when sandbox Docker settings are configured while sandbox mode is off, when `gateway.nodes.denyCommands` uses ineffective pattern-like/unknown entries, when `gateway.nodes.allowCommands` explicitly enables dangerous node commands, when global `tools.profile="minimal"` is overridden by agent tool profiles, when open groups expose runtime/filesystem tools without sandbox/workspace guards, and when installed extension plugin tools may be reachable under permissive tool policy. It also warns when sandbox browser uses Docker `bridge` network without `sandbox.browser.cdpSourceRange`. -It also flags dangerous sandbox Docker network modes (including `host` and `container:*` namespace joins). It also warns when existing sandbox browser Docker containers have missing/stale hash labels (for example pre-migration containers missing `openclaw.browserConfigEpoch`) and recommends `openclaw sandbox recreate --browser --all`. It also warns when npm-based plugin/hook install records are unpinned, missing integrity metadata, or drift from currently installed package versions. -It warns when channel allowlists rely on mutable names/emails/tags instead of stable IDs (Discord, Slack, Google Chat, MS Teams, Mattermost, IRC scopes where applicable). +It warns when Discord allowlists (`channels.discord.allowFrom`, `channels.discord.guilds.*.users`, pairing store) use name or tag entries instead of stable IDs. It warns when `gateway.auth.mode="none"` leaves Gateway HTTP APIs reachable without a shared secret (`/tools/invoke` plus any enabled `/v1/*` endpoint). -Settings prefixed with `dangerous`/`dangerously` are explicit break-glass operator overrides; enabling one is not, by itself, a security vulnerability report. -For the complete dangerous-parameter inventory, see the "Insecure or dangerous flags summary" section in [Security](/gateway/security). + +## Skill security + +Community skills (installed from ClawHub) are subject to additional security enforcement: + +- **SKILL.md scanning**: content is scanned for prompt injection patterns, capability inflation, and boundary spoofing before entering the system prompt. Skills with critical findings are blocked from loading. +- **Capability enforcement**: community skills must declare `capabilities` (e.g., `shell`, `network`) in frontmatter. Undeclared dangerous tool usage is blocked at runtime by the before-tool-call hook — a hard code gate that prompt injection cannot bypass. +- **Command dispatch gating**: community skills using `command-dispatch: tool` can't dispatch to dangerous tools without the matching capability. +- **Audit logging**: all security events are tagged with `category: "security"` and include session context for forensics. View in the web UI Logs tab using the Security filter. + +See `openclaw skills check` for a runtime security overview, `openclaw skills info ` for per-skill details, and [Skills — Tool enforcement matrix](/tools/skills#tool-enforcement-matrix) for the complete tool-by-tool breakdown. + +### Tool enforcement matrix + +Every tool falls into one of three tiers when community skills are loaded: + +**Always denied** — blocked unconditionally, no capability can override: + +| Tool | Reason | +| --------- | --------------------------------------------------------------- | +| `gateway` | Control-plane reconfiguration (restart, shutdown, auth changes) | +| `nodes` | Cluster node management (add/remove compute, redirect traffic) | + +**Capability-gated** — blocked by default, allowed if the skill declares the matching capability: + +| Capability | Tools | What it unlocks | +| ------------ | ---------------------------------------------- | --------------------------------------- | +| `shell` | `exec`, `process`, `lobster` | Run shell commands and manage processes | +| `filesystem` | `write`, `edit`, `apply_patch` | File mutations (read is always allowed) | +| `network` | `web_fetch`, `web_search` | Outbound HTTP requests | +| `browser` | `browser` | Browser automation | +| `sessions` | `sessions_spawn`, `sessions_send`, `subagents` | Cross-session orchestration | +| `messaging` | `message` | Send messages to configured channels | +| `scheduling` | `cron` | Schedule recurring jobs | + +**Always allowed** — safe read-only or output-only tools, no capability required: + +| Tool | Why safe | +| ----------------------------------------------------- | --------------------------------- | +| `read` | Read-only file access | +| `memory_search`, `memory_get` | Read-only memory access | +| `agents_list` | List agents (read-only) | +| `sessions_list`, `sessions_history`, `session_status` | Session introspection (read-only) | +| `canvas` | UI rendering (output-only) | +| `image` | Image generation (output-only) | +| `tts` | Text-to-speech (output-only) | + +A community skill with no capabilities declared gets access only to the always-allowed tier. Declare capabilities in SKILL.md frontmatter: + +```yaml +metadata: + openclaw: + capabilities: [shell, filesystem, network] +``` ## JSON output