Skip to content

Exposing the hub publicly

The hub is built to be reachable on the public internet — agents on NAT’d boxes dial out to it, so a public hub with agents behind home or office NAT is a first-class deployment shape, not a workaround.

  • Login rate limiting. The single admin password is the whole security boundary. Sign-in and sign-up are rate-limited to slow credential-stuffing.
  • Security headers on every response. Sent ahead of every route.
  • A fail-closed HTTPS requirement. In production the hub refuses to boot unless BETTER_AUTH_URL is set to an https:// URL. A missing or plain-HTTP value used to yield a silently insecure cookie and CSRF posture — now it’s a hard failure. See TLS and reverse proxies.

Runaway is single-admin. Once the first account exists, signup is closed — not just hidden in the UI, but refused at the request layer, so hitting the sign-up endpoint directly still fails. The first-signup path is race-safe, which matters on a public hub: a reachable /setup URL is exactly when someone might try to race the operator to create that first account.

The hub holds no Docker socket. All runner compute lives on agent hosts, which sit behind NAT and dial out to the hub. So even a full hub compromise on the public box grants an attacker no Docker root anywhere — there’s no socket on the exposed surface to take. This one-way trust is also why the hub can never push code to an agent: the exposed surface must never be able to reach into a homelab machine.