Section

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.

The headscale-admin dashboard

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:

  1. 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).
  2. Owns the config. Generates headscale.yaml under work_dir and keeps owning it - the Settings and DNS pages edit it in place, with a .bak written before each save.
  3. 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.
  4. Fronts everything on one port. A single net/http listener 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 returns 404.

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.