Files
bot/docs/web/index.md
zeekay 4bdc9ee3e4 chore: rebrand openclaw → hanzo-bot for bridge merge
Comprehensive rename of all openclaw references to hanzo-bot equivalents:
- Package: openclaw → @hanzo/bot
- Binary: openclaw → hanzo-bot
- Types: OpenClaw* → Bot*
- Env vars: OPENCLAW_* → BOT_*
- Android: ai.openclaw.android → ai.hanzo.bot.android
- iOS/macOS: ai.openclaw.* → ai.hanzo.*
- Swift modules: OpenClaw* → Bot*
- Plugins: openclaw.plugin.json → bot.plugin.json
- Paths: .openclaw/ → .hanzo/bot/
- URLs: github.com/openclaw → github.com/hanzoai
2026-02-26 22:36:01 -08:00

3.1 KiB

summary, read_when, title
summary read_when title
Gateway web surfaces: Control UI, bind modes, and security
You want to access the Gateway over Tailscale
You want the browser Control UI and config editing
Web

Web (Gateway)

The Gateway serves a small browser Control UI (Vite + Lit) from the same port as the Gateway WebSocket:

  • default: http://<host>:18789/
  • optional prefix: set gateway.controlUi.basePath (e.g. /bot)

Capabilities live in Control UI. This page focuses on bind modes, security, and web-facing surfaces.

Webhooks

When hooks.enabled=true, the Gateway also exposes a small webhook endpoint on the same HTTP server. See Gateway configuration → hooks for auth + payloads.

Config (default-on)

The Control UI is enabled by default when assets are present (dist/control-ui). You can control it via config:

{
  gateway: {
    controlUi: { enabled: true, basePath: "/bot" }, // basePath optional
  },
}

Tailscale access

Keep the Gateway on loopback and let Tailscale Serve proxy it:

{
  gateway: {
    bind: "loopback",
    tailscale: { mode: "serve" },
  },
}

Then start the gateway:

hanzo-bot gateway

Open:

  • https://<magicdns>/ (or your configured gateway.controlUi.basePath)

Tailnet bind + token

{
  gateway: {
    bind: "tailnet",
    controlUi: { enabled: true },
    auth: { mode: "token", token: "your-token" },
  },
}

Then start the gateway (token required for non-loopback binds):

hanzo-bot gateway

Open:

  • http://<tailscale-ip>:18789/ (or your configured gateway.controlUi.basePath)

Public internet (Funnel)

{
  gateway: {
    bind: "loopback",
    tailscale: { mode: "funnel" },
    auth: { mode: "password" }, // or BOT_GATEWAY_PASSWORD
  },
}

Security notes

  • Gateway auth is required by default (token/password or Tailscale identity headers).
  • Non-loopback binds still require a shared token/password (gateway.auth or env).
  • The wizard generates a gateway token by default (even on loopback).
  • The UI sends connect.params.auth.token or connect.params.auth.password.
  • For non-loopback Control UI deployments, set gateway.controlUi.allowedOrigins explicitly (full origins). Without it, gateway startup is refused by default.
  • gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true enables Host-header origin fallback mode, but is a dangerous security downgrade.
  • With Serve, Tailscale identity headers can satisfy Control UI/WebSocket auth when gateway.auth.allowTailscale is true (no token/password required). HTTP API endpoints still require token/password. Set gateway.auth.allowTailscale: false to require explicit credentials. See Tailscale and Security. This tokenless flow assumes the gateway host is trusted.
  • gateway.tailscale.mode: "funnel" requires gateway.auth.mode: "password" (shared password).

Building the UI

The Gateway serves static files from dist/control-ui. Build them with:

pnpm ui:build # auto-installs UI deps on first run