Overview
What headscale-admin is, how it supervises headscale, and what the single binary actually does when you run it.
What it is
headscale-admin is a single Go binary that runs headscale
for you and gives it a modern web console. You don’t install, configure, or run headscale separately - headscale-admin
downloads the pinned headscale release (SHA-256 verified), generates and owns its headscale.yaml, sqlite
database and keys, supervises the headscale serve process, and is the only public listener in front of it.
The UI is a SvelteKit single-page app, prerendered and embedded into the binary at build time, served under /admin.

So a deployment is one process and one data directory:
- one binary to install - no separate headscale package, no container orchestration, no reverse proxy required;
- one port to expose - the binary terminates TLS and routes traffic itself;
- one directory to back up - everything headscale needs (config, DB, keys, the downloaded binary) lives under
work_dir.
What it does
When you run headscale-admin serve it:
- Resolves headscale. Locates the pinned headscale binary in
bin_dir, downloading and checksum-verifying it from GitHub releases on first run (or uses a binary you supply for air-gapped installs). - Owns the config. Generates
headscale.yamlunderwork_dirand keeps owning it - the Settings and DNS pages edit it in place, with a.bakwritten before each save. - Supervises headscale. Starts
headscale serve, dials the unix socket it creates, and restarts/monitors it. The admin UI talks to headscale over that local socket - no API key needed. - Fronts everything on one port. A single
net/httplistener terminates TLS and proxies/admin/*to the UI and a version-pinned allowlist of headscale control-plane paths (/ts2021,/key,/register/…,/derp…,/oidc/…, …) to the supervised headscale. Tailscale clients connect to this same address. Everything outside the allowlist returns404.
The bare root / is configurable (server.root) - by default it redirects to the device-onboarding signup page.
What you can manage
The console covers the whole surface headscale exposes, plus the things headscale-admin adds on top:
- Nodes - approve subnet routes, edit ACL tags, rename, expire, register, or remove machines.
- Users & keys - tailnet identities, pre-auth keys (
tailscale up --auth-key=…), and headscale API keys. - ACL policy - edit visually (groups, tag owners, hosts, auto-approvers, ACL rules, grants, SSH) or as raw HuJSON, with a live Access map graph of who can reach what.
- DNS - MagicDNS, base domain, global nameservers, split DNS, search domains.
- Routes & exit nodes - approve and toggle advertised subnet routes and exit nodes.
- System - an immutable audit log, backups (policy, databases, or everything), one-click version updates for the supervised headscale, and admins/operators with role-based access.
- User sync (optional) - fill the
group:members in your ACL policy from an external identity source (JumpCloud, Authentik, Keycloak, LDAP) via the bundled headscale-pf.
Take the full page-by-page tour in the UI walkthrough.
Access & authentication
Signing in to the console is separate from how your tailnet clients authenticate.
- Local accounts - email + password, with optional TOTP two-factor and passkeys.
- OIDC SSO - sign in through your identity provider; roles follow a configurable group mapping.
- RBAC - admin (full access) vs operator (manages the tailnet - nodes, users, keys, ACL, DNS, user sync - but not the audit log, deployment config, backups, or principal management).
For a zero-setup local trial, auth can be disabled entirely (everyone is admin) - local development only.
Who it is for
- Teams self-hosting headscale who want a real admin UI without standing up and wiring headscale, a database, and a reverse proxy by hand.
- Operators who’d rather pin and upgrade headscale from a dropdown (checksum-verified, auto-reverts on failure) than manage release downloads themselves.
- Setups that need SSO + role separation in front of headscale, or that sync ACL groups from an existing identity provider.
What it is not
- Not a remote/external-headscale UI. headscale-admin only manages the headscale it supervises itself; there is no mode that points it at a headscale you run elsewhere. (The version is pinned because the UI talks to headscale’s gRPC API, which is proto-coupled to a specific release.)
- Not a replacement for headscale. It is headscale, wrapped - your tailnet, nodes, and keys are headscale’s; this is the control surface around them.
- Not a Tailscale coordination server of its own. All networking is headscale; headscale-admin adds the UI, auth/SSO, lifecycle, and tooling.
What’s next
- UI walkthrough - a page-by-page tour of the console, with screenshots.
- Installation - stand it up by hand, with Docker, Docker Compose, or Ansible.