15 KiB
Security Policy
Quick Links
- Deployment profiles and checklists: Security Deployment Guide
- Runtime startup hardening behavior: Runtime Hardening and Startup
- Pre-exposure checklist: Security Checklist
- 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 | ✅ |
| All earlier releases | ❌ |
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:
- Submit a private report with repro steps, affected version, and impact.
- Maintainers triage and confirm impact.
- Fix and mitigation guidance are prepared.
- 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:
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:
- Protecting
/openclaw/*routes does not automatically protect ComfyUI-native routes. - Public reverse-proxy policy must enforce path-level allow/deny and network ACL boundaries.
- 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
- Localhost (Default): Use on your own machine. No extra config needed.
- VPN / Tailscale: Best for private remote access.
- 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:
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: 1or?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
localorlan - runtime profile is not hardened
Operational rules:
- do not enable
OPENCLAW_DEBUG_REASONING_REVEALon 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:
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:
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-009for 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 untrustedruncallbacks 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-Idby 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
defaultfor backward compatibility; stricter caller paths can enforce explicit tenant presence.
Compatibility toggles (use only during migration windows):
OPENCLAW_MULTI_TENANT_ALLOW_DEFAULT_FALLBACK=1OPENCLAW_MULTI_TENANT_ALLOW_CONFIG_FALLBACK=1OPENCLAW_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_COMMANDSmust include the command basename in useOPENCLAW_1PASSWORD_VAULTandOPENCLAW_1PASSWORD_FIELDmust be validOPENCLAW_1PASSWORD_ITEM_TEMPLATEmust 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:
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_iooutbound executor dials resolved IPs directly for HTTP/HTTPS and keeps TLSserver_hostnameon the original host; the no-skiptests.test_s70_ssrf_pinning_regressionlane 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:
export OPENCLAW_ALLOW_CUSTOM_BASE_URL=1 # Legacy compatibility (optional): # export MOLTBOT_ALLOW_CUSTOM_BASE_URL=1 -
use strict allowlist:
export OPENCLAW_LLM_ALLOWED_HOSTS="api.example.com,llm.example.com" -
OPENCLAW_LLM_ALLOWED_HOSTSonly permits additional exact public hosts; it does not bypass the private/reserved-IP block. -
OPENCLAW_ALLOW_ANY_PUBLIC_LLM_HOST=1widens to any public host only. -
allow_private_network=trueon the LLM setting allows only the configured providerbase_urlhost to resolve to a private/reserved IP while keeping exact-host allowlists, scheme/port checks, and DNS pinning. -
OPENCLAW_ALLOW_INSECURE_BASE_URL=1is 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:
python scripts/verify_audit_chain.py --json
Notes:
- verification covers the active
audit.logplus retained rotated segments in the state directory - when an audit chain key is not supplied externally, OpenClaw persists a local
audit.log.keysidecar 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(legacyMOLTBOT_BRIDGE_ENABLED=1). - Authentication: Requires
OPENCLAW_BRIDGE_DEVICE_TOKEN(legacyMOLTBOT_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_TOKENandOPENCLAW_OBSERVABILITY_TOKEN(legacy aliases acceptable). - Trusted proxy config: set
OPENCLAW_TRUST_X_FORWARDED_FOR=1and exactOPENCLAW_TRUSTED_PROXIES. - Public shared-surface ack: for
OPENCLAW_DEPLOYMENT_PROFILE=public, setOPENCLAW_PUBLIC_SHARED_SURFACE_BOUNDARY_ACK=1only 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
publicorhardened, ensure platform allowlists are set before startup (DP-PUBLIC-009for public profile). - External tools disabled by default: keep
OPENCLAW_ENABLE_EXTERNAL_TOOLS=0unless 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 --jsonafter 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/doctorbefore exposure. - Least privilege host posture: do not run as root/Administrator.