mirror of
https://github.com/rookiestar28/ComfyUI-OpenClaw.git
synced 2026-08-14 08:52:45 +00:00
317 lines
15 KiB
Markdown
317 lines
15 KiB
Markdown
# Security Policy
|
|
|
|
## Quick Links
|
|
|
|
- Deployment profiles and checklists: [Security Deployment Guide](security_deployment_guide.md)
|
|
- Runtime startup hardening behavior: [Runtime Hardening and Startup](runtime_hardening_and_startup.md)
|
|
- Pre-exposure checklist: [Security Checklist](security_checklist.md)
|
|
- Deployment self-check command:
|
|
- `python scripts/check_deployment_profile.py --profile local|lan|public`
|
|
|
|
## Supported Versions
|
|
|
|
Only the latest version of ComfyUI-OpenClaw is supported for security updates.
|
|
|
|
| Version | Supported |
|
|
| ------------------------ | ------------------ |
|
|
| Latest published release | :white_check_mark: |
|
|
| All earlier releases | :x: |
|
|
|
|
## Reporting a Vulnerability
|
|
|
|
Please report security vulnerabilities by creating a **private** issue on GitHub if possible, or contact the maintainers directly. Do not open public issues for sensitive security flaws.
|
|
|
|
### Disclosure Workflow and SLA
|
|
|
|
Private reporting workflow:
|
|
1. Submit a private report with repro steps, affected version, and impact.
|
|
2. Maintainers triage and confirm impact.
|
|
3. Fix and mitigation guidance are prepared.
|
|
4. Advisory is published with affected-range + fixed-version metadata.
|
|
|
|
Target SLA:
|
|
- initial acknowledgement: within 72 hours
|
|
- triage status update: within 7 calendar days
|
|
- coordinated disclosure target: within 30 days after confirmed impact
|
|
- timeline may be extended for high-complexity fixes; status updates are still required
|
|
|
|
Advisory publication policy:
|
|
- advisories are tracked in `docs/release/security_advisories.json`
|
|
- Security Doctor surfaces advisory applicability (`affected`, `mitigation`) for the running version
|
|
- high-severity affected posture should be treated as priority upgrade work
|
|
|
|
### Telemetry Opt-out Contract (S9)
|
|
|
|
Security anomaly telemetry is minimal and audit-focused by default. If operators must disable this emission path, use:
|
|
|
|
```bash
|
|
export OPENCLAW_TELEMETRY_OPT_OUT=1
|
|
# Legacy compatibility:
|
|
# export MOLTBOT_TELEMETRY_OPT_OUT=1
|
|
```
|
|
|
|
Trade-off:
|
|
- with opt-out enabled, security anomaly audit events are not emitted
|
|
- use only when required by policy/privacy constraints and keep compensating controls in place
|
|
|
|
---
|
|
|
|
# Safe Deployment Guide
|
|
|
|
OpenClaw is a powerful extension that interacts with LLMs and the filesystem (via ComfyUI). **By default, it is designed for local (localhost) use.** Exposing it to the public internet requires careful configuration.
|
|
|
|
## ⚠️ Warning
|
|
|
|
**Do NOT expose your ComfyUI instance directly to the public internet** (for example via direct port-forwarding) without a secure reverse proxy or VPN.
|
|
|
|
## Shared Listener Boundary (Critical)
|
|
|
|
OpenClaw and ComfyUI share the same HTTP listener/port.
|
|
|
|
This means:
|
|
|
|
1. Protecting `/openclaw/*` routes does not automatically protect ComfyUI-native routes.
|
|
2. Public reverse-proxy policy must enforce path-level allow/deny and network ACL boundaries.
|
|
3. Public posture requires explicit operator acknowledgement that these boundaries are in place.
|
|
|
|
High-risk ComfyUI-native routes to deny on public edges unless intentionally required:
|
|
|
|
- `/prompt`, `/history*`, `/view*`, `/upload*`, `/ws`
|
|
- `/api/prompt`, `/api/history*`, `/api/view*`, `/api/upload*`, `/api/ws`
|
|
|
|
## Recommended Deployment
|
|
|
|
1. **Localhost (Default)**: Use on your own machine. No extra config needed.
|
|
2. **VPN / Tailscale**: Best for private remote access.
|
|
3. **SSH Tunnel**: `ssh -L 8188:localhost:8188 user@remote`
|
|
|
|
## Reverse Proxy Setup (Advanced)
|
|
|
|
If you must expose OpenClaw via a reverse proxy (Nginx, Caddy, Cloudflare Tunnel), you MUST configure the following:
|
|
|
|
### 1. Token Boundaries
|
|
|
|
Logs (`/openclaw/logs/tail`) and Config (`/openclaw/config`) are restricted to loopback clients by default. (Legacy `/moltbot/*` endpoints are also supported.) To allow remote access via proxy, set a secure token:
|
|
|
|
```bash
|
|
export OPENCLAW_OBSERVABILITY_TOKEN="your-secure-random-token-here"
|
|
export OPENCLAW_ADMIN_TOKEN="your-secure-random-admin-token-here"
|
|
# Legacy compatibility (optional):
|
|
# export MOLTBOT_OBSERVABILITY_TOKEN="your-secure-random-token-here"
|
|
# export MOLTBOT_ADMIN_TOKEN="your-secure-random-admin-token-here"
|
|
```
|
|
|
|
Then configure your proxy or client to send the header `X-OpenClaw-Obs-Token: your-secure-random-token-here` (legacy: `X-Moltbot-Obs-Token`).
|
|
|
|
### 1.1 Reasoning and Internal Content Redaction Boundary
|
|
|
|
Operator-facing payloads strip provider reasoning / thinking traces and explicitly marked internal maintenance/helper prompt content by default across:
|
|
|
|
- assist responses
|
|
- event / SSE payloads
|
|
- trace responses
|
|
- callback payloads
|
|
- connector trace/debug replies
|
|
- audit event payload/meta fields
|
|
|
|
Internal maintenance/helper prompt content has no public or debug reveal path. Privileged reasoning reveal is limited to provider reasoning / thinking traces only.
|
|
|
|
### 1.2 Reasoning Debug Reveal Boundary (Local-only)
|
|
|
|
There is a privileged local-debug reveal path for troubleshooting, but it is fail-closed unless **all** of the following are true:
|
|
|
|
- request explicitly opts in via `X-OpenClaw-Debug-Reveal-Reasoning: 1` or `?debug_reasoning=1`
|
|
- server-side debug switch is enabled with `OPENCLAW_DEBUG_REASONING_REVEAL=1`
|
|
- request is admin-authorized
|
|
- client IP resolves to loopback
|
|
- deployment profile is `local` or `lan`
|
|
- runtime profile is not hardened
|
|
|
|
Operational rules:
|
|
|
|
- do not enable `OPENCLAW_DEBUG_REASONING_REVEAL` on public deployments
|
|
- treat any successful reveal as privileged debugging activity and review related audit events (`reasoning.debug_reveal`)
|
|
- the reveal path appends debug reasoning payloads only for the privileged request; default operator outputs remain redacted
|
|
|
|
### 2. Trusted Proxy Attribution
|
|
|
|
If using a reverse proxy, OpenClaw needs to know the *real* client IP for rate limiting enforcement.
|
|
|
|
Configure your proxy to send `X-Forwarded-For`, then configure trusted proxy ranges:
|
|
|
|
```bash
|
|
export OPENCLAW_TRUST_X_FORWARDED_FOR=1
|
|
export OPENCLAW_TRUSTED_PROXIES="127.0.0.1,10.0.0.0/8"
|
|
# Legacy compatibility (optional):
|
|
# export MOLTBOT_TRUST_X_FORWARDED_FOR=1
|
|
# export MOLTBOT_TRUSTED_PROXIES="127.0.0.1,10.0.0.0/8"
|
|
```
|
|
|
|
### 3. Public Profile Boundary Acknowledgement
|
|
|
|
For public profile deployments, you must explicitly acknowledge that reverse-proxy path controls and network ACL boundaries are already enforced:
|
|
|
|
```bash
|
|
export OPENCLAW_DEPLOYMENT_PROFILE=public
|
|
export OPENCLAW_PUBLIC_SHARED_SURFACE_BOUNDARY_ACK=1
|
|
# Legacy compatibility (optional):
|
|
# export MOLTBOT_PUBLIC_SHARED_SURFACE_BOUNDARY_ACK=1
|
|
```
|
|
|
|
If this acknowledgement is missing in public profile, deployment profile checks fail with `DP-PUBLIC-008`.
|
|
|
|
### 4. Connector Allowlist Fail-Closed (Public/Hardened)
|
|
|
|
Connector ingress posture is fail-closed in strict profiles:
|
|
|
|
- if connector platform ingress is active (Telegram/Discord/LINE/WhatsApp/WeChat/Kakao/Slack/Feishu)
|
|
- and matching allowlist variables are missing
|
|
- startup/deployment checks fail closed (`DP-PUBLIC-009` for public profile)
|
|
|
|
Operational requirement:
|
|
|
|
- never enable connector platform tokens/enable flags in public or hardened posture without platform allowlist coverage.
|
|
|
|
### 4.1 Interactive Callback Contract Baseline (Connector)
|
|
|
|
For interactive connector callbacks (actions/modals/workflow style payloads), the shared callback contract is fail-closed by default:
|
|
|
|
- signed envelope is required (`signature`, `timestamp`, `request_id`, `workspace_id`, `action_type`, `payload_hash`)
|
|
- stale timestamp, replay/duplicate request ID, payload-hash mismatch, or unknown action type are rejected
|
|
- workspace-to-installation resolution is fail-closed on missing/ambiguous/inactive/stale-token-ref binding
|
|
- policy mapping is explicit (`public`/`run`/`admin`) and untrusted `run` callbacks degrade to approval instead of direct privileged execution
|
|
- duplicate committed connector events are acknowledged without re-running completed actions, while retryable failures before action/delivery commit can be retried
|
|
- reply visibility is policy-driven; text-only silent/internal/tool-only/no-mention replies can be suppressed without suppressing approval cards, action buttons, allowlist checks, or callback replay checks
|
|
|
|
Operational note:
|
|
|
|
- treat callback decision codes/audit trails as security evidence and investigate repeated reject patterns before enabling higher-risk interactive flows.
|
|
|
|
### 4.2 Multi-tenant Boundary Model (Fail-Closed)
|
|
|
|
When `OPENCLAW_MULTI_TENANT_ENABLED=1`, OpenClaw enforces explicit tenant boundaries across API and service paths.
|
|
|
|
Boundary rules:
|
|
|
|
- tenant context is resolved from token context and/or tenant header (`X-OpenClaw-Tenant-Id` by default)
|
|
- token/header mismatch is rejected (`tenant_mismatch`)
|
|
- connector installation diagnostics/resolution, config read/write, approvals, presets, template visibility, and secret lookup are tenant-scoped
|
|
- execution budgets add per-tenant concurrency enforcement (`OPENCLAW_MAX_INFLIGHT_SUBMITS_PER_TENANT`)
|
|
|
|
Compatibility note:
|
|
|
|
- current admin/API handlers default missing tenant context to `default` for backward compatibility; stricter caller paths can enforce explicit tenant presence.
|
|
|
|
Compatibility toggles (use only during migration windows):
|
|
|
|
- `OPENCLAW_MULTI_TENANT_ALLOW_DEFAULT_FALLBACK=1`
|
|
- `OPENCLAW_MULTI_TENANT_ALLOW_CONFIG_FALLBACK=1`
|
|
- `OPENCLAW_MULTI_TENANT_ALLOW_LEGACY_SECRET_FALLBACK=1`
|
|
|
|
Security recommendation:
|
|
|
|
- keep all fallback toggles disabled for steady-state multi-tenant production.
|
|
|
|
### 4.3 Optional Local Secret-manager Path (1Password CLI)
|
|
|
|
If `OPENCLAW_1PASSWORD_ENABLED=1`, provider key lookup can use local 1Password CLI as an optional backend source.
|
|
|
|
Fail-closed requirements:
|
|
|
|
- `OPENCLAW_1PASSWORD_ALLOWED_COMMANDS` must include the command basename in use
|
|
- `OPENCLAW_1PASSWORD_VAULT` and `OPENCLAW_1PASSWORD_FIELD` must be valid
|
|
- `OPENCLAW_1PASSWORD_ITEM_TEMPLATE` must include `{provider}`
|
|
- when multi-tenant mode is enabled, the template must also include `{tenant}`
|
|
|
|
Operational note:
|
|
|
|
- this path remains backend-only; frontend surfaces stay secret-blind.
|
|
|
|
### 5. Startup Gate Behavior
|
|
|
|
Startup security gates are fail-closed. Fatal startup gate/bootstrap failures abort route/worker registration and do not continue in a partial state.
|
|
|
|
Recommended preflight:
|
|
|
|
```bash
|
|
python scripts/check_deployment_profile.py --profile public --strict-warnings
|
|
```
|
|
|
|
### 6. SSRF Protection
|
|
|
|
OpenClaw validates custom LLM `base_url` settings to prevent Server-Side Request Forgery (SSRF).
|
|
|
|
* **Default**: known providers and localhost-safe paths are allowed.
|
|
* **Pinned connect contract**: on supported CPython versions (current baseline: 3.10+), the consolidated `safe_io` outbound executor dials resolved IPs directly for HTTP/HTTPS and keeps TLS `server_hostname` on the original host; the no-skip `tests.test_s70_ssrf_pinning_regression` lane is intended to fail loudly if stdlib connect behavior drifts.
|
|
* **Redirect handling**: redirect targets are revalidated against host allowlists, private/reserved-IP blocking, and pinned-connect rules before any follow-up connection is opened.
|
|
* **Custom base URL**:
|
|
- requires explicit opt-in:
|
|
|
|
```bash
|
|
export OPENCLAW_ALLOW_CUSTOM_BASE_URL=1
|
|
# Legacy compatibility (optional):
|
|
# export MOLTBOT_ALLOW_CUSTOM_BASE_URL=1
|
|
```
|
|
- use strict allowlist:
|
|
```bash
|
|
export OPENCLAW_LLM_ALLOWED_HOSTS="api.example.com,llm.example.com"
|
|
```
|
|
- `OPENCLAW_LLM_ALLOWED_HOSTS` only permits additional exact public hosts; it does not bypass the private/reserved-IP block.
|
|
- `OPENCLAW_ALLOW_ANY_PUBLIC_LLM_HOST=1` widens to any public host only.
|
|
- `allow_private_network=true` on the LLM setting allows only the configured provider `base_url` host to resolve to a private/reserved IP while keeping exact-host allowlists, scheme/port checks, and DNS pinning.
|
|
- `OPENCLAW_ALLOW_INSECURE_BASE_URL=1` is the explicit risk-acceptance override for HTTP or private/reserved IP targets.
|
|
- the same scoped/private or insecure decision is enforced consistently for config validation, `/openclaw/llm/models`, and outbound provider requests.
|
|
- wildcard values such as `OPENCLAW_LLM_ALLOWED_HOSTS="*"` are not supported.
|
|
- avoid broad bypass flags in production (`OPENCLAW_ALLOW_ANY_PUBLIC_LLM_HOST`, `OPENCLAW_ALLOW_INSECURE_BASE_URL`).
|
|
|
|
### 6.1 Audit Chain Verification
|
|
|
|
OpenClaw keeps append-only audit evidence verifiable across restart and retained-log rotation.
|
|
|
|
Recommended operator check:
|
|
|
|
```bash
|
|
python scripts/verify_audit_chain.py --json
|
|
```
|
|
|
|
Notes:
|
|
|
|
- verification covers the active `audit.log` plus retained rotated segments in the state directory
|
|
- when an audit chain key is not supplied externally, OpenClaw persists a local `audit.log.key` sidecar so the retained chain stays verifiable after restart
|
|
- treat any verification failure as an integrity incident and investigate before trusting the retained audit trail
|
|
|
|
### 7. Rate Limiting
|
|
|
|
OpenClaw enforces internal rate limits:
|
|
|
|
* Webhooks: 30/min
|
|
* Logs: 60/min
|
|
* Admin: 20/min
|
|
|
|
### 8. Sidecar Bridge
|
|
|
|
OpenClaw supports a "Sidecar Bridge" for safe interaction with external bots (Discord/Slack).
|
|
|
|
* **Default**: **DISABLED**.
|
|
* **Enable**: Set `OPENCLAW_BRIDGE_ENABLED=1` (legacy `MOLTBOT_BRIDGE_ENABLED=1`).
|
|
* **Authentication**: Requires `OPENCLAW_BRIDGE_DEVICE_TOKEN` (legacy `MOLTBOT_BRIDGE_DEVICE_TOKEN`) (shared secret).
|
|
* **Network**: Bridge endpoints (`/bridge/*`) are sensitive. **Do not expose to public internet.** Use a private network (Tailscale) or restrict access via reverse proxy.
|
|
* **SSRF**: Callback delivery blocks internal IPs. To allow specific external callback hosts, set `OPENCLAW_BRIDGE_CALLBACK_HOST_ALLOWLIST` (legacy: `MOLTBOT_BRIDGE_CALLBACK_HOST_ALLOWLIST`).
|
|
|
|
## Security Checklist
|
|
|
|
* [ ] **HTTPS + Edge Auth**: reverse proxy enforces TLS and an additional auth boundary (SSO/Basic/IP ACL).
|
|
* [ ] **No direct public bind**: never expose raw ComfyUI/OpenClaw listener directly.
|
|
* [ ] **Token boundaries**: set `OPENCLAW_ADMIN_TOKEN` and `OPENCLAW_OBSERVABILITY_TOKEN` (legacy aliases acceptable).
|
|
* [ ] **Trusted proxy config**: set `OPENCLAW_TRUST_X_FORWARDED_FOR=1` and exact `OPENCLAW_TRUSTED_PROXIES`.
|
|
* [ ] **Public shared-surface ack**: for `OPENCLAW_DEPLOYMENT_PROFILE=public`, set `OPENCLAW_PUBLIC_SHARED_SURFACE_BOUNDARY_ACK=1` only after proxy path allowlist + ACL are verified.
|
|
* [ ] **Public path deny rules**: block ComfyUI-native high-risk routes and `/api/*` equivalents unless explicitly required.
|
|
* [ ] **Connector strict-posture allowlists**: if connector ingress is active in `public` or `hardened`, ensure platform allowlists are set before startup (`DP-PUBLIC-009` for public profile).
|
|
* [ ] **External tools disabled by default**: keep `OPENCLAW_ENABLE_EXTERNAL_TOOLS=0` unless there is a reviewed need; if enabled, verify the tool allowlist, sandbox policy, and deterministic sandbox/interpreter/timeout/workspace diagnostics.
|
|
* [ ] **Multi-tenant boundary (if enabled)**: enforce one canonical tenant header path through proxy/app, keep fallback toggles disabled unless a migration window is actively in progress.
|
|
* [ ] **Audit integrity check**: run `python scripts/verify_audit_chain.py --json` after restart/rotation-sensitive maintenance and confirm retained audit logs still verify cleanly.
|
|
* [ ] **1Password guardrails (if enabled)**: require command allowlist + vault/template validation; in multi-tenant mode, include `{tenant}` in item template.
|
|
* [ ] **Startup gate preflight**: run `python scripts/check_deployment_profile.py --profile public --strict-warnings`.
|
|
* [ ] **Runtime diagnostics**: review `GET /openclaw/security/doctor` before exposure.
|
|
* [ ] **Least privilege host posture**: do not run as root/Administrator.
|