Skip to main content

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. /fased)
Capabilities live in Control UI. This page focuses on bind modes, security, and web-facing surfaces.

Normal browser routes

  • /dash: widget dashboard.
  • /chat: browser chat for the selected Agent/session.
  • /agents: normal setup workbench for Models, Channels, Skills, Tools, Memory, Sessions, Services, Tasks (including Coordination), and Files.
  • /wallet, /mining, /federation, /marketplace: focused runtime workflows.
  • /extensions: global extension/plugin lifecycle.
  • /notifications, /usage, /logs: operator monitoring.
  • /config: Advanced surface with Config, Debug, and Nodes tabs.
Older global provider/channel/service/skills/task routes can still exist for compatibility, deep links, or admin views. They are hidden or demoted from the primary navigation because normal setup starts from the selected Agent.

Webhooks

When hooks.enabled=true, the Gateway also exposes a small webhook endpoint on the same HTTP server. See Gateway configurationhooks 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: "/fased" }, // 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:
fased 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):
fased 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 FASED_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