Skip to content
Guides

OpenClaw behind Cloudflare Tunnel and Access

A public HTTPS URL without an open port, trusted-proxy auth, how nodes get in, and what the JWT check is not

5 min read

One of the three supported remote-access topologies in the docs, beside Tailscale and an SSH tunnel, is a Cloudflare Tunnel with Cloudflare Access in front: the Gateway keeps its loopback bind, no port is exposed and no inbound firewall rule is needed because the tunnel daemon dials out from the host, and Access authenticates every request with your identity provider before it reaches OpenClaw. Choose it when you want a stable public HTTPS URL and single sign-on in front of the Control UI. Here are the pieces, the caveat the docs state plainly, the five steps, the node question, and the production rules.

The pieces and the caveat

  • Browser, CLI or node reaches Cloudflare Access, which authenticates and injects identity headers, then the tunnel carries the request to the loopback port.
  • The Gateway does not re-authenticate the person or verify the Access token signature: it checks the trusted proxy source and the configured header presence, then trusts the user header.
  • Because the loopback allowance also lets other local processes present those headers, the docs say to keep the Gateway port private to the host and run only trusted workloads there; the security boundary is the locked-down loopback port plus Access and the tunnel being the only external path.
  • You need a Cloudflare account with the zone and Zero Trust enabled, the tunnel daemon on the Gateway host and on any machine that will use the CLI, a running loopback Gateway, and the trusted-proxy auth mode this topology relies on.
Binding wider re-exposes the Gateway beside the tunnel and bypasses Access entirely.

The five steps

Route the tunnel to loopback with an ingress rule mapping your hostname to the Gateway port and run the daemon as a service. Protect the hostname with an Access application whose policy allows your users, noting the two headers Access adds, the authenticated email and the signed assertion, of which OpenClaw checks only presence. Trust those headers in the Gateway: auth mode trusted-proxy, the user header and the required header named, loopback allowed because the daemon connects from the local address, and the trusted proxies limited to loopback; requiring the assertion header is a second presence check, not cryptographic verification. Decide how nodes get in, below. Connect each client: the Control UI signs in through Access and the Gateway maps the identity to an operator session; the CLI and TUI carry no browser cookies, so they present an Access token on the WebSocket upgrade through the edge-auth config after a one-time login with the daemon; nodes follow the node decision.

Nodes, verification, production

  • Recommended: give the node an Access service token through a Service Auth policy, export the client id and secret on the node host, and join with the service flag; the connect command persists them as environment-backed references, at the cost that a join link is no longer paste-and-go on its own.
  • Alternative: exempt the join route and the worker route from Access identity, since both enforce their own short-lived credentials, a single-use join code with a TTL, per-IP rate limits and an opaque not-found on failure; this keeps join links paste-and-go at the cost of making two routes publicly reachable. Do neither and the connect command fails against the tunnel even though the browser works, because the join request is redirected to the login page.
  • Verify with the TUI, which should reach the secure URL and show connected; a first connection may ask for device pairing, approved in the Control UI or with the devices command on the host, and reaching the Gateway’s own pairing prompt is the proof that Access was satisfied. In production keep the loopback bind, keep the trusted proxies limited to loopback, enable automatic device approval only if anyone who passes Access should get a paired device with the listed scopes, and expect CLI users to log in again when their token lapses.

OpenClaw remote access is the page this topology sits beside, with the client-side edge-auth config it points to, and OpenClaw and Tailscale the tailnet alternative.

Troubleshooting

A 302 on the WebSocket upgrade from the CLI or TUI means Access intercepted it, so configure the edge-auth headers. A working browser with a failing connect command means the node routes are still behind Access. An exec provider exiting with code one means the scrubbed environment hid the home directory the daemon needs to read its cached token. A symlink error means the command must point at the resolved binary. And a Gateway where every request is anonymous means the loopback allowance is unset, so headers from the local daemon are ignored. OpenClaw on Cloudflare Containers is the other Cloudflare page in the docs, running the Gateway itself on Cloudflare, and OpenClaw Gateway security controls the server-side auth modes trusted-proxy belongs to.

On Diali

On Diali the identity in front of the Gateway is your dashboard session at our edge, and the instance itself is never reachable any other way, which is the same shape as this topology with the tunnel and the policy run for you. Hosted OpenClaw on Diali is the assistant and Diali security describes the boundary.

  • Loopback in, tunnel out, Access in front.
  • Presence of the headers is trusted, not the signature.
  • Nodes need a service token or two exempt routes.
Get started

Stop reading about it, build one

Set up an agent, pick a channel, and have it working inside the app you already keep open.