This guide is the single entry point for secure deployment of ComfyUI-OpenClaw across three deployment profiles:
local: single-user localhostlan: private LAN / trusted subnetpublic: internet-facing behind reverse proxy
Use this guide together with:
- SECURITY.md
docs/deploy/local-only.mddocs/deploy/lan.mddocs/deploy/reverse-proxy.mddocs/security_checklist.md
Before using OpenClaw in any internet-facing setup, you must explicitly accept:
- This project is local-first by design; exposing it to public networks increases attack surface.
- This guide reduces risk but does not guarantee security, compliance, or incident-free operation.
- The operator/deployer is responsible for network isolation, auth boundaries, key management, monitoring, and incident response.
- If you cannot satisfy the
publicprofile baseline and checklist, do not deploy publicly. Uselocalor private/VPN-only access instead. - High-risk capabilities (external tools, registry sync, transforms, remote admin) must remain disabled unless there is a reviewed and time-bounded operational requirement.
OpenClaw runs inside ComfyUI and shares the same HTTP listener/port.
This means:
- Protecting
/openclaw/*endpoints does not automatically protect ComfyUI native endpoints. - If your public edge forwards raw ComfyUI upstream traffic broadly, attackers may still reach native ComfyUI surfaces.
- Public deployment must enforce path-level allow/deny policy at reverse proxy (and network ACL), not just OpenClaw tokens.
High-risk ComfyUI-native paths to explicitly deny on public edges (unless intentionally required):
- direct paths:
/prompt,/history*,/view*,/upload*,/ws - API-shim paths:
/api/prompt,/api/history*,/api/view*,/api/upload*,/api/ws
Notes:
- Exact ComfyUI route shape can vary by version and shim behavior. Use deny rules that cover both direct and
/api/*forms. - If you intentionally expose full ComfyUI UI to users, apply a separate hardened admin/user plane design and do not rely on OpenClaw route auth alone.
| Profile | Intended Use | Minimum Security Baseline |
|---|---|---|
local |
single operator on same machine | no remote admin, no proxy trust, high-risk features disabled unless explicitly needed |
lan |
trusted private network | admin + observability token, webhook auth + replay protection, remote admin opt-in, risky features off |
public |
internet-facing reverse proxy | strict token boundaries, trusted proxy config, remote admin off, control-plane split required, risky features off, webhook auth fail-closed, connector allowlist fail-closed |
Validate current environment variables against a deployment profile:
python scripts/check_deployment_profile.py --profile local
python scripts/check_deployment_profile.py --profile lan
python scripts/check_deployment_profile.py --profile publicMachine-readable output:
python scripts/check_deployment_profile.py --profile public --jsonThe command exits with non-zero status when policy failures are found.
Use --strict-warnings if you want warnings to fail the check in hardened pipelines:
python scripts/check_deployment_profile.py --profile public --strict-warningsOptional operational log hygiene (all profiles):
# Clear active openclaw.log once at startup (useful to avoid stale UI log noise)
OPENCLAW_LOG_TRUNCATE_ON_START=1# Recommended baseline
OPENCLAW_ALLOW_REMOTE_ADMIN=0
OPENCLAW_TRUST_X_FORWARDED_FOR=0
OPENCLAW_ENABLE_EXTERNAL_TOOLS=0
OPENCLAW_ENABLE_REGISTRY_SYNC=0
OPENCLAW_ENABLE_TRANSFORMS=0
OPENCLAW_DEBUG_REASONING_REVEAL=0
OPENCLAW_ALLOW_ANY_PUBLIC_LLM_HOST=0
OPENCLAW_ALLOW_INSECURE_BASE_URL=0
OPENCLAW_SECURITY_DANGEROUS_BIND_OVERRIDE=0
OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=0
# Optional but recommended
OPENCLAW_ADMIN_TOKEN=change-this-local-admin-token
# Optional local CLI compatibility only (do not enable on LAN/public):
# OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=true
# Optional startup log hygiene
# OPENCLAW_LOG_TRUNCATE_ON_START=1- Keep ComfyUI bound to localhost only.
- Keep remote admin disabled.
- Keep external tools/registry sync/transforms disabled unless explicitly needed.
- For local LLM providers (Ollama/LM Studio), use loopback URLs only (
localhost/127.0.0.1/::1); keepOPENCLAW_ALLOW_ANY_PUBLIC_LLM_HOST=0andOPENCLAW_ALLOW_INSECURE_BASE_URL=0. OPENCLAW_LLM_ALLOWED_HOSTSis only for additional exact public hosts; it does not permit RFC1918/private LAN targets.- The same LLM SSRF contract applies consistently to config validation,
/openclaw/llm/models, and outbound provider requests. - Keep
OPENCLAW_DEBUG_REASONING_REVEAL=0unless you are doing short-lived local admin debugging and explicitly need privileged reasoning reveal. - Keep
OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=0unless you explicitly need local CLI/no-origin compatibility. - Run:
python scripts/check_deployment_profile.py --profile local
- If you enable optional high-risk features, document why and time-box the change.
OPENCLAW_ADMIN_TOKEN=change-this-admin-token
OPENCLAW_OBSERVABILITY_TOKEN=change-this-obs-token
# LAN mode allows remote admin intentionally, but only inside trusted network
OPENCLAW_ALLOW_REMOTE_ADMIN=1
# Webhook auth must be explicit
OPENCLAW_WEBHOOK_AUTH_MODE=hmac
OPENCLAW_WEBHOOK_HMAC_SECRET=change-this-hmac-secret
OPENCLAW_WEBHOOK_REQUIRE_REPLAY_PROTECTION=1
# Keep risky expansion surfaces off by default
OPENCLAW_ENABLE_EXTERNAL_TOOLS=0
OPENCLAW_ENABLE_REGISTRY_SYNC=0
OPENCLAW_ENABLE_TRANSFORMS=0
OPENCLAW_DEBUG_REASONING_REVEAL=0
OPENCLAW_ALLOW_ANY_PUBLIC_LLM_HOST=0
OPENCLAW_ALLOW_INSECURE_BASE_URL=0
OPENCLAW_SECURITY_DANGEROUS_BIND_OVERRIDE=0
OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=0
# Optional startup log hygiene
# OPENCLAW_LOG_TRUNCATE_ON_START=1- Restrict host firewall to trusted LAN subnets only.
- Use distinct admin and observability tokens.
- Keep bridge/tools/registry/transforms disabled unless there is a reviewed requirement.
- Keep
OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=0for LAN deployments. - If your LLM is on another LAN/private-IP host, that still counts as an insecure
base_urltarget;OPENCLAW_LLM_ALLOWED_HOSTSalone is not sufficient. - The same LLM SSRF contract applies consistently to config validation,
/openclaw/llm/models, and outbound provider requests. - Run:
python scripts/check_deployment_profile.py --profile lan
- Run the security diagnostics endpoint before production use:
GET /openclaw/security/doctor(admin boundary).
- If using mobile/remote admin UI, expose
/openclaw/adminonly inside trusted LAN/VPN boundaries.
OPENCLAW_ADMIN_TOKEN=change-this-admin-token
OPENCLAW_OBSERVABILITY_TOKEN=change-this-obs-token
# Public baseline: do not expose remote admin directly
OPENCLAW_ALLOW_REMOTE_ADMIN=0
# Public shared-surface boundary acknowledgement (S69).
# Set only after reverse-proxy path allowlist + network ACL deny ComfyUI-native
# high-risk paths and /api equivalents.
OPENCLAW_PUBLIC_SHARED_SURFACE_BOUNDARY_ACK=1
# Public baseline: enforce split control plane (S62/R106)
OPENCLAW_CONTROL_PLANE_MODE=split
OPENCLAW_CONTROL_PLANE_URL=https://control-plane.internal
OPENCLAW_CONTROL_PLANE_TOKEN=change-this-control-plane-token
OPENCLAW_CONTROL_PLANE_TIMEOUT=10
# Trust only known reverse proxy addresses
OPENCLAW_TRUST_X_FORWARDED_FOR=1
OPENCLAW_TRUSTED_PROXIES=127.0.0.1,10.0.0.0/8
# Webhooks must be authenticated and replay-protected
OPENCLAW_WEBHOOK_AUTH_MODE=hmac
OPENCLAW_WEBHOOK_HMAC_SECRET=change-this-hmac-secret
OPENCLAW_WEBHOOK_REQUIRE_REPLAY_PROTECTION=1
# Optional callback path must be tightly allowlisted
OPENCLAW_CALLBACK_ALLOW_HOSTS=example.com,api.example.com
# If connector ingress is enabled in public posture, set platform allowlists.
# Otherwise startup/deployment checks fail closed.
# Example (Telegram):
# OPENCLAW_CONNECTOR_TELEGRAM_TOKEN=...
# OPENCLAW_CONNECTOR_TELEGRAM_ALLOWED_USERS=123456
# Keep risky expansion surfaces off on public user plane
OPENCLAW_ENABLE_EXTERNAL_TOOLS=0
OPENCLAW_ENABLE_REGISTRY_SYNC=0
OPENCLAW_ENABLE_TRANSFORMS=0
OPENCLAW_DEBUG_REASONING_REVEAL=0
OPENCLAW_ALLOW_ANY_PUBLIC_LLM_HOST=0
OPENCLAW_ALLOW_INSECURE_BASE_URL=0
OPENCLAW_SECURITY_DANGEROUS_BIND_OVERRIDE=0
OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=0
# Optional startup log hygiene
# OPENCLAW_LOG_TRUNCATE_ON_START=1- Never expose raw ComfyUI port directly to the internet.
- Enforce authentication at reverse proxy and application layers.
- Enforce path-level boundary controls at reverse proxy:
- allow only required OpenClaw routes
- deny ComfyUI-native high-risk paths (
/prompt,/history*,/view*,/upload*,/ws) and/api/*equivalents.
- Set
OPENCLAW_PUBLIC_SHARED_SURFACE_BOUNDARY_ACK=1only after step 3 and network ACL hardening are in place. - Enforce split control plane in public posture (
OPENCLAW_CONTROL_PLANE_MODE=split+ external URL/TOKEN). - Keep
OPENCLAW_DEBUG_REASONING_REVEAL=0; privileged reasoning reveal is for local debugging only and must not be enabled on public user planes. - If any connector platform token/enable flag is configured, set corresponding platform allowlist vars before startup (
DP-PUBLIC-009fail-closed). - Keep risky features disabled on public user-facing plane.
- Keep
OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=0in public deployments. - Verify split posture from capabilities:
GET /openclaw/capabilitiesand confirmcontrol_plane.mode=split
- Run:
python scripts/check_deployment_profile.py --profile public
- Validate with project test and release gates before rollout:
tests/TEST_SOP.md- RELEASE_CHECKLIST.md
- Ensure
/openclaw/adminis blocked at public edge unless a separately hardened private admin plane is in place.
If bridge must be enabled in public profile, apply all of the following:
OPENCLAW_BRIDGE_ENABLED=1
OPENCLAW_BRIDGE_DEVICE_TOKEN=change-this-bridge-token
OPENCLAW_BRIDGE_MTLS_ENABLED=1
OPENCLAW_BRIDGE_DEVICE_CERT_MAP=device-a:sha256fingerprint
OPENCLAW_BRIDGE_ALLOWED_DEVICE_IDS=device-aAlso run:
python scripts/check_deployment_profile.py --profile publicThe check fails if bridge is enabled without the mTLS/device-binding bundle.
- Do not use localhost convenience mode for shared/LAN/public deployments.
- Do not enable
OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=truein shared/LAN/public deployments. - Do not enable
OPENCLAW_SECURITY_DANGEROUS_BIND_OVERRIDEin production. - Do not enable
OPENCLAW_SECURITY_DANGEROUS_PROFILE_OVERRIDEin production. - Do not enable
OPENCLAW_SPLIT_COMPAT_OVERRIDEin production. - Do not enable external tools/registry sync/transforms on public user-facing plane by default.
- Do not use wildcard-like trust posture for callback destinations.
- Do not treat this as a "set and forget" deployment; re-run profile checks after every config change.
Use this before route registration in hardened deployments:
python scripts/check_deployment_profile.py --profile "${OPENCLAW_DEPLOYMENT_PROFILE:-local}" --strict-warningsIf the command exits non-zero, startup should fail closed. This validates deployment-profile posture (S56 baseline), but does not replace split-prerequisite checks.
Run all three profile checks in CI using fixture env files:
python scripts/check_deployment_profile.py --profile local --strict-warnings
python scripts/check_deployment_profile.py --profile lan --strict-warnings
python scripts/check_deployment_profile.py --profile public --strict-warningsPair this with tests/TEST_SOP.md so deployment posture checks are validated alongside unit/E2E regressions.
For public deployments, also verify control-plane split prerequisites and active mode:
- Confirm startup has no S62 fatal errors (missing
OPENCLAW_CONTROL_PLANE_URL/OPENCLAW_CONTROL_PLANE_TOKEN). - Confirm runtime capability view reports split mode:
GET /openclaw/capabilitiescontrol_plane.modemust besplit
Public MAE enforcement is not only a route-registration rule. It is a startup + CI guarantee:
- Startup gate blocks public/hardened posture violations before serving routes.
- Route-plane classification drift tests fail when new endpoints are not classified.
- CI runs MAE-critical suites as explicit no-skip gates:
tests.test_s60_mae_route_segmentationtests.test_s60_routes_startup_gatetests.security.test_endpoint_drift
Do not remove these suites from CI or skip-policy protection.
Operational procedures for rotation/revocation/disaster recovery are documented in:
docs/security_key_lifecycle_sop.md
Coverage includes trust-root/signer revocation, secrets-at-rest key lifecycle, and bridge token rotation.
This runbook is required for long-running public deployments and incident response readiness.