mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-28 22:36:48 +00:00
Summary: - The PR expands security audit, CLI docs, and tests so `hooks.token` reuse of active Gateway token/password auth is reported while password-mode Gateway startup remains compatible. - PR surface: Source +178, Tests +311, Docs +14. Total +503 across 14 files. - Reproducibility: yes. from source inspection: current main forwards a bearer token as both token and passwor ... ecause this review was read-only, but the linked issue and code path make the reproduction high confidence. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(cr-fmi-hook-ingress-token-unlocks-password-mode-gateway-auth): ap… - PR branch already contained follow-up commit before automerge: fix: include trusted proxy password in hooks token reuse check - PR branch already contained follow-up commit before automerge: fix(gateway): audit hooks password reuse without blocking startup - PR branch already contained follow-up commit before automerge: fix: Hook ingress token unlocks password-mode gateway auth Validation: - ClawSweeper review passed for head7c796b22ec. - Required merge gates passed before the squash merge. Prepared head SHA:7c796b22ecReview: https://github.com/openclaw/openclaw/pull/86453#issuecomment-4533831028 Co-authored-by: Coy Geek <65363919+coygeek@users.noreply.github.com> Co-authored-by: jesse-merhi <79823012+jesse-merhi@users.noreply.github.com> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: jesse-merhi
137 lines
7.7 KiB
Markdown
137 lines
7.7 KiB
Markdown
---
|
|
summary: "CLI reference for `openclaw security` (audit and fix common security footguns)"
|
|
read_when:
|
|
- You want to run a quick security audit on config/state
|
|
- You want to apply safe "fix" suggestions (permissions, tighten defaults)
|
|
title: "Security"
|
|
---
|
|
|
|
# `openclaw security`
|
|
|
|
Security tools (audit + optional fixes).
|
|
|
|
Related:
|
|
|
|
- Security guide: [Security](/gateway/security)
|
|
|
|
## Audit
|
|
|
|
```bash
|
|
openclaw security audit
|
|
openclaw security audit --deep
|
|
openclaw security audit --deep --password <password>
|
|
openclaw security audit --deep --token <token>
|
|
openclaw security audit --fix
|
|
openclaw security audit --json
|
|
```
|
|
|
|
Plain `security audit` stays on the cold config/filesystem/read-only path. It does not discover plugin runtime security collectors by default, so routine audits do not load every installed plugin runtime. Use `--deep` to include best-effort live Gateway probes and plugin-owned security audit collectors; explicit internal callers may also opt into those plugin-owned collectors when they already have an appropriate runtime scope.
|
|
|
|
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.token` reuses an active Gateway shared-secret auth value (`gateway.auth.token` / `OPENCLAW_GATEWAY_TOKEN` or `gateway.auth.password` / `OPENCLAW_GATEWAY_PASSWORD`)
|
|
- `hooks.token` is short
|
|
- `hooks.path="/"`
|
|
- `hooks.defaultSessionKey` is unset
|
|
- `hooks.allowedAgentIds` is unrestricted
|
|
- request `sessionKey` overrides are enabled
|
|
- overrides are enabled without `hooks.allowedSessionKeyPrefixes`
|
|
|
|
If Gateway password auth is supplied only at startup, pass the same value to `openclaw security audit --auth password --password <password>` so the audit can check it against `hooks.token`.
|
|
Password-mode reuse is an audit finding for compatibility; rotate one of the secrets instead of expecting Gateway startup to reject that configuration.
|
|
|
|
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 write/edit tools are disabled but `exec` is still available without a constraining sandbox filesystem boundary, when open groups expose runtime/filesystem tools without sandbox/workspace guards, and when installed 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 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, Microsoft Teams, Mattermost, IRC scopes where applicable).
|
|
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).
|
|
|
|
Intentional standing findings can be accepted with `security.audit.suppressions`.
|
|
Each suppression matches an exact `checkId` and can be narrowed with
|
|
`titleIncludes` and/or `detailIncludes` case-insensitive substrings:
|
|
|
|
```json
|
|
{
|
|
"security": {
|
|
"audit": {
|
|
"suppressions": [
|
|
{
|
|
"checkId": "plugins.tools_reachable_permissive_policy",
|
|
"detailIncludes": "Enabled extension plugins: gbrain",
|
|
"reason": "trusted local operator plugin"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Suppressed findings are removed from the active `summary` and `findings` list.
|
|
JSON output keeps them under `suppressedFindings` for auditability.
|
|
When suppressions are configured, active output also keeps an unsuppressible
|
|
`security.audit.suppressions.active` info finding so readers can tell the audit
|
|
was filtered. Dangerous config flags are emitted one flag per finding, so
|
|
accepting one dangerous flag does not hide other enabled flags that share the
|
|
same `config.insecure_or_dangerous_flags` checkId.
|
|
Because suppressions can hide standing risk, adding or removing them through
|
|
agent-run shell commands requires exec approval unless exec is already running
|
|
with `security="full"` and `ask="off"` for trusted local automation.
|
|
|
|
SecretRef behavior:
|
|
|
|
- `security audit` resolves supported SecretRefs in read-only mode for its targeted paths.
|
|
- If a SecretRef is unavailable in the current command path, audit continues and reports `secretDiagnostics` (instead of crashing).
|
|
- `--token` and `--password` only override deep-probe auth for that command invocation; they do not rewrite config or SecretRef mappings.
|
|
|
|
## JSON output
|
|
|
|
Use `--json` for CI/policy checks:
|
|
|
|
```bash
|
|
openclaw security audit --json | jq '.summary'
|
|
openclaw security audit --deep --json | jq '.findings[] | select(.severity=="critical") | .checkId'
|
|
```
|
|
|
|
If `--fix` and `--json` are combined, output includes both fix actions and final report:
|
|
|
|
```bash
|
|
openclaw security audit --fix --json | jq '{fix: .fix.ok, summary: .report.summary}'
|
|
```
|
|
|
|
## What `--fix` changes
|
|
|
|
`--fix` applies safe, deterministic remediations:
|
|
|
|
- flips common `groupPolicy="open"` to `groupPolicy="allowlist"` (including account variants in supported channels)
|
|
- when WhatsApp group policy flips to `allowlist`, seeds `groupAllowFrom` from
|
|
the stored `allowFrom` file when that list exists and config does not already
|
|
define `allowFrom`
|
|
- sets `logging.redactSensitive` from `"off"` to `"tools"`
|
|
- tightens permissions for state/config and common sensitive files
|
|
(`credentials/*.json`, `auth-profiles.json`, `sessions.json`, session
|
|
`*.jsonl`)
|
|
- also tightens config include files referenced from `openclaw.json`
|
|
- uses `chmod` on POSIX hosts and `icacls` resets on Windows
|
|
|
|
`--fix` does **not**:
|
|
|
|
- rotate tokens/passwords/API keys
|
|
- disable tools (`gateway`, `cron`, `exec`, etc.)
|
|
- change gateway bind/auth/network exposure choices
|
|
- remove or rewrite plugins/skills
|
|
|
|
## Related
|
|
|
|
- [CLI reference](/cli)
|
|
- [Security audit](/gateway/security)
|