โ† All guides

ZeroClaw Web UI, Gateway and Tunnel: Setup and Safe Exposure

ZeroClaw.net ยท Updated 2026-08-18

ZeroClaw Web UI, Gateway and Tunnel: Setup and Safe Exposure

The terminal is a fine way to talk to an agent until you want to see what it has been doing, check its memory, or reach it from a device that is not the machine it runs on. That is what the gateway and web dashboard are for.

This guide covers running it locally, what the security-relevant settings actually mean, and how to reach it remotely without turning your agent into an open endpoint.

Gateway, dashboard, tunnel

Three terms that get used loosely:

  • The gateway is the HTTP server built into ZeroClaw. It serves the dashboard, exposes the API, and receives webhooks from messaging channels.
  • The web dashboard (or web UI) is the browser interface the gateway serves โ€” chat, history, memory inspection, agent status.
  • A tunnel is how you reach the gateway from outside the network it runs on, without opening a firewall port.

One process provides all of this. Starting the gateway starts the dashboard.

Starting it

zeroclaw gateway

By default this binds to localhost. Current builds serve the dashboard at http://127.0.0.1:3000/; older builds used port 8080, and some documentation still references 42617. If the port you expected is wrong, zeroclaw status reports what your build is actually using โ€” trust that over any guide, including this one.

To choose the port explicitly:

zeroclaw gateway --port 8080

Or let the OS assign a random free one, which is the hardened option for a gateway you only reach through a tunnel:

zeroclaw gateway --port 0

A random high port is not a security control on its own โ€” anything scanning the host will find it โ€” but it does remove the class of accident where something else on the network connects to a predictable port because it assumed what was listening there.

The equivalent configuration in config.toml:

[channels.web]
enabled = true
bind = "127.0.0.1"
port = 3000

The bind address is the setting that matters

Of everything on this page, bind is the one to get right.

127.0.0.1 accepts connections from the machine itself and nothing else. Another computer on your network cannot reach it, and neither can anything on the internet. This is the default and it is correct for almost every setup.

0.0.0.0 accepts connections on every network interface. Every device on your LAN can now reach the dashboard. If the host has a public IP, or your router forwards a port to it, so can the entire internet.

People change this to 0.0.0.0 because they want to reach the dashboard from their laptop, and it works immediately, which is exactly the problem โ€” nothing about the outcome signals that the agent is now reachable by everything else on the network too. If you want remote access, use a tunnel. It solves the same problem without the exposure.

If you have a genuine reason to bind to a LAN interface, bind to that specific address rather than 0.0.0.0:

[channels.web]
bind = "192.168.1.50"
port = 3000

Pairing

The first connection to the gateway must present a pairing code before it is trusted. This is what stands between "someone found the endpoint" and "someone controls the agent".

The flow: start the gateway, retrieve the pairing code from the terminal output, open the dashboard, enter the code. That browser is now a trusted client.

Practical notes:

  • Pair over a channel that is already private. A pairing code pasted into a shared chat is not a control.
  • Re-pair after rotating credentials, moving hosts, or clearing browser storage.
  • A pairing prompt you did not initiate means something is attempting to connect. Investigate rather than dismissing it.

Pairing authenticates the client, once. It does not authenticate each subsequent request independently, and it does not help if the paired device is itself compromised.

Reaching it remotely

You want the dashboard from your phone. There are four ways, in descending order of how much I would recommend them.

1. A VPN or overlay network (best)

Tailscale, WireGuard or similar puts your phone and your agent host on the same private network. The gateway stays bound to a private address, nothing is exposed publicly, and the connection is authenticated and encrypted by the VPN.

This is the correct answer for personal use. It is not more difficult than the alternatives โ€” a modern overlay network is a five-minute setup โ€” and it is the only option on this list that does not create a publicly reachable endpoint at all.

2. An SSH tunnel (good, zero extra software)

If you can already SSH to the host:

ssh -L 3000:127.0.0.1:3000 user@agent-host

Now http://localhost:3000 on your laptop reaches the gateway on the remote machine. The gateway stays bound to localhost; SSH provides the authentication and encryption. Nothing new is exposed.

Add -N to skip the remote shell, and -f to background it.

3. A reverse proxy with authentication (acceptable, more work)

If you need a permanent public URL โ€” a webhook from a service that cannot reach a private network, for example โ€” put a reverse proxy in front:

server {
    listen 443 ssl;
    server_name agent.example.com;

    ssl_certificate     /etc/letsencrypt/live/agent.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/agent.example.com/privkey.pem;

    location / {
        auth_basic           "Restricted";
        auth_basic_user_file /etc/nginx/.htpasswd;

        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

The gateway still binds to 127.0.0.1 โ€” only the proxy talks to it. TLS terminates at the proxy, and the proxy enforces its own authentication in front of ZeroClaw's pairing. Two independent layers is the point; if either fails, the other still holds.

Restrict by source IP as well where you can:

allow 203.0.113.0/24;
deny  all;

4. Binding to 0.0.0.0 and forwarding a port (don't)

This works, and it exposes an agent that can execute commands to anything that finds the port. Scanning for open ports is continuous and automated across the entire IPv4 space; "nobody knows my IP" has not been true for a long time. Use one of the three options above.

Running it as a service

For a gateway that should survive reboots:

zeroclaw service install
zeroclaw service status

This registers ZeroClaw with the platform's service manager โ€” systemd on most Linux systems, launchd on macOS. Run the service as a dedicated unprivileged user that owns the workspace and nothing else. If the agent is ever compromised, the OS user boundary is what limits the damage, and it is the one boundary the agent cannot reason its way around.

Troubleshooting

The dashboard will not load. Confirm the gateway is running and check which port it actually chose:

zeroclaw status
zeroclaw doctor

On Linux, confirm something is listening:

ss -tlnp | grep zeroclaw

Address already in use. Another process holds the port. Pick a different one with --port, or find the occupant with lsof -i :3000.

Reachable locally but not from another machine. Working as intended if bind is 127.0.0.1. Set up a tunnel rather than changing the bind address.

Pairing code not appearing. It is printed on gateway startup. If you missed it, restart the gateway. If the agent is running as a service, check the service logs โ€” journalctl -u zeroclaw on systemd.

Webhooks are not arriving. The channel needs a reachable URL. Check channel health specifically:

zeroclaw channel doctor
zeroclaw integrations info Telegram

A sensible default

For a personal agent:

[channels.web]
enabled = true
bind = "127.0.0.1"
port = 3000

Bound to localhost, reached remotely over Tailscale or SSH, running as a dedicated service user, with pairing required. That configuration gives you the dashboard from anywhere and exposes nothing to the public internet.

Related reading

ZeroClaw.net is an independent community resource. It is not the official ZeroClaw project and is not affiliated with ZeroClaw Labs, OpenClaw or PicoClaw. Always check the official project repository before installing software.