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.
What protects a public hub
Section titled “What protects a public hub”- 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_URLis set to anhttps://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.
Single-admin, closed at the request layer
Section titled “Single-admin, closed at the request layer”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.
A hub compromise grants no Docker access
Section titled “A hub compromise grants no Docker access”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.