Skip to content
CAI
Software that uses CAICheck a score

juanfont/headscale

63.9

Adequate · 6 August 2026

53.9k

lines of production code

Go

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

Headscale is an open-source implementation of the Tailscale control plane, providing a self-hosted alternative for managing headless devices and network access. The system exposes v1 and v2 APIs, supports OAuth and API key authentication, and enforces network policies and routing rules. It includes a CLI for administration, a web interface, and comprehensive tooling for testing and deployment.

How it got here

2020–2023 — v2 API and authentication overhaul

17 changes.

This period focused on modernizing the Headscale codebase by introducing a new v2 API with gRPC support and robust CLI capabilities. Significant work was done to implement secure API key and OAuth authentication flows, alongside a comprehensive integration test suite to validate these new features.

2024–2025 — Policy v2 and UI modernization

15 changes.

This period focused on upgrading the policy engine to support Tailscale's v2 format, including grants and auto-approval logic, while simultaneously modernizing the web interface with a consistent Go-based templating system and dark mode support. The release also introduced dynamic DNS record management, stricter client version enforcement, and improved infrastructure through hardened packaging and a new integration test runner.

2026 — API v2 and v1 modernization

17 changes.

This period focused on modernizing the Headscale API surface by implementing a code-first Huma-based v1 API and introducing a Tailscale-compatible v2 API for managing ACLs, devices, and keys. The work included generating typed HTTP clients and OpenAPI specifications, while also establishing robust testing harnesses and safe logging utilities to support these new interfaces.

Features

Add NixOS module and integration tests for Headscale

Users can now install and configure Headscale on NixOS via a dedicated NixOS module. The module provides options for enabling the service, configuring the listen address and port, and setting up the Headscale configuration (including DNS, DERP, and database settings) through a structured Nix attribute set. An example configuration file is provided to demonstrate all major features. Additionally, an integration test is included to verify that Headscale starts correctly, accepts client connections, and supports DNS resolution within the tailnet.

nix · high confidence

Add OAuth scope enforcement and vocabulary

Added a new \hscontrol/scope\ package that defines the OAuth capability scopes (e.g., \auth\_keys\, \devices:core\, \policy\_file\) and the logic for checking if a set of granted scopes satisfies a required one. This includes support for read/write distinctions, super-scopes (\all\, \all:read\), and tag requirements for specific scopes. The change includes comprehensive property-based and hand-picked tests to verify the grant logic.

hscontrol/scope · high confidence

Add OpenAPI spec generation tool for v1 and v2 APIs

A new command-line tool at cmd/gen-openapi has been added to generate OpenAPI specifications for both the v1 and v2 APIs. The tool reads from the Huma-based API definitions and outputs the OpenAPI 3.1 specification by default, or a downgraded 3.0.3 version for typed client generation. This supports the code-first API implementation by providing the necessary API documentation files.

cmd/gen-openapi · high confidence

Add SQLite configuration and validation for database pragmas

The hscontrol/db/sqliteconfig package introduces type-safe configuration for SQLite database connections, allowing users to control performance and durability settings such as journal mode (WAL, DELETE, etc.), auto-vacuum strategy, synchronous mode, and transaction locking. The new code validates these settings and generates the appropriate URL parameters for the modernc.org/sqlite driver, ensuring that database pragmas are applied correctly during connection. Tests verify that these configurations are correctly applied to the database.

hscontrol/db/sqliteconfig · high confidence

Add Tailscale-compatible v2 API endpoints for ACLs, devices, keys, and users

The v2 API surface now exposes endpoints for managing access control lists, devices, authentication keys, and users, all using Tailscale's wire shapes and error formats. This enables the Terraform/OpenTofu provider, tscli, and the official Go client to drive Headscale unchanged. The API supports both API key and OAuth 2.0 client-credentials authentication, with scope enforcement for OAuth tokens. A read-only tailnet settings endpoint is also added.

hscontrol/api/v2 · high confidence

Add TailscaleRustInContainer integration test helper

Added the \tsric\ package in \integration/tsric/tsric.go\, which provides a \TailscaleRustInContainer\ struct and associated options to run the \tailscale-rs\ axum example inside a Docker container for integration testing with headscale. This new component allows tests to spin up a Rust-based Tailscale node, configuring it with CA certificates, auth keys, and network settings, and manages the container lifecycle and entrypoint setup.

integration/tsric · high confidence

Add generated HTTP clients for the v1 and v2 APIs

Added new Go packages, clientv1 and clientv2, which provide generated HTTP clients for interacting with the v1 and v2 API endpoints respectively. These clients, generated from OpenAPI specifications, expose typed structs and methods for making API calls, enabling programmatic access to the service's functionality.

gen · high confidence

Add local development server tool (cmd/dev)

A new \cmd/dev\ command has been added to the codebase, providing a local development environment for headscale. This tool automatically builds the headscale binary, generates a minimal configuration (using SQLite and public DERP), starts the headscale server as a subprocess, and creates a pre-authenticated user with a reusable 24-hour key. It also validates that the specified \--port\ argument fits within the derived port range to prevent port overflow for the metrics endpoint.

cmd/dev · high confidence

Add mapresponses CLI tool for inspecting map response states

A new command-line utility named 'mapresponses' has been added to the codebase. This tool allows users to inspect and compare map responses from a specified directory, specifically supporting an 'online' subcommand that reads map responses, builds an expected online map state, and outputs the result as formatted JSON to the standard error stream.

cmd/mapresponses · high confidence

Add tsic integration test client abstraction

The integration test suite now includes a new \tsic\ package that provides a \TailscaleInContainer\ abstraction for running Tailscale instances inside Docker containers. This new client allows integration tests to configure and control Tailscale nodes with options for CA certificates, network settings, tags, SSH, and WebSocket/HTTP-based DERP connections, enabling more robust and isolated end-to-end testing scenarios.

integration/tsic · high confidence

Add typed testcapture package for policy v2 compatibility tests

A new \testcapture\ package has been added to \hscontrol/types/testcapture\ to define the on-disk format for Headscale's policy v2 compatibility tests. The package provides types and functions to read and write HuJSON files containing captured state (ACLs, SSH rules, netmaps) from a SaaS control plane. It includes a schema versioning system (currently v1) to handle format changes, a comment header for human-readable metadata, and atomic file writes. The package also includes tests to verify the read/write round-trip for both ACL and SSH capture scenarios.

hscontrol/types/testcapture · high confidence

Add vendorhash tool to track vendor SRI in flakehashes.json

A new \vendorhash\ command-line tool has been added to maintain and verify the Nix SRI hash for the Go module vendor tree. It provides \check\ and \update\ subcommands to detect when the vendor tree has drifted from the recorded hash in \flakehashes.json\, helping ensure reproducible builds by validating that the vendor directory matches the expected state.

cmd/vendorhash · high confidence

Automate capability version detection from container tags

A new Go tool in the tools/capver directory now fetches container image tags from GitHub Container Registry, parses semantic versions, and generates Go source files that map capability versions. This automates the process of keeping capability versioning in sync with released container images.

tools · high confidence

Introduce API key and OAuth token storage with improved security and validation

The database layer now supports storing and validating API keys and OAuth client/secret pairs. API keys are generated with a 12-character public prefix and a 64-character secret, with the secret hashed using bcrypt. The system enforces strict validation of key formats, including legacy 7-character prefixes, and ensures that lookups by ID use explicit primary-key clauses to prevent accidental full-table scans. Additionally, OAuth client secrets and access tokens are stored with Argon2id hashing and include expiration and revocation checks. Tests verify that zero-ID lookups correctly return not-found errors, preventing unintended data retrieval.

hscontrol/db · high confidence

Introduce Policy v2 with support for grants, via-routes, and autogroup:self

The policy engine has been replaced with a new v2 implementation that supports the Tailscale SaaS policy format, including grants, via-routes, and autogroup:self. This update brings Headscale's access control and routing behavior into closer alignment with Tailscale, allowing for more granular network segmentation and exit-node routing through tags. The new engine also introduces a pre-computed peer map for optimized route calculation and validates policies at load time to prevent ambiguous user references.

hscontrol/policy/v2 · high confidence

Introduce \`hi\` integration test runner CLI

The \cmd/hi\ directory now contains a new CLI tool that wraps Docker container orchestration for the \integration\ test suite. Users can run tests via \hi run\, verify system requirements with \hi doctor\, and manage resources with \hi clean\ subcommands. The runner supports concurrent test execution by generating unique run IDs, isolating container cleanup, and managing debugging artefacts (logs, database snapshots, MapResponse captures) in \control\_logs/\. It also provides a \list-versions\ subcommand to enumerate Tailscale versions used by the integration tests.

cmd/hi · high confidence

Introduce hsic integration test framework

Added a new integration test helper package (hsic) that provides a containerized Headscale instance for integration testing. The package includes configuration defaults for database, DNS, and DERP settings, along with options to customize TLS, ACL policies, and environment variables for the test container.

integration/hsic · high confidence

Introduces new types for API keys, OAuth clients, and authentication flows

The hscontrol/types package now includes dedicated types for API keys (APIKey), OAuth clients and access tokens (OAuthClient, OAuthAccessToken), and authentication request handling (AuthRequest, RegistrationData, SSHCheckBinding). These additions support the new v2 API authentication mechanisms, secure logging of sensitive identifiers, and the OIDC/SSH check-mode authentication flows. Tests have been added to verify the behavior of these new types.

hscontrol/types · high confidence

Major CLI overhaul: new commands, JSON output, and v2 API support

The CLI has been refactored to use the v2 API and gRPC, introducing new subcommands for managing OAuth clients, API keys, pre-auth keys, and nodes. Users can now output results in JSON, YAML, or JSON-line formats, and access new capabilities like the \configtest\ and \health\ commands. The \nodes\ and \preauthkeys\ commands have been expanded with new flags and options, and the \auth\ command allows registering and approving node authentication requests.

cmd/headscale/cli · high confidence

New Change type for efficient MapResponse construction

The hscontrol/types/change package introduces a new Change type that serves as a compact, structured description of what must be included in a tailcfg.MapResponse. This change replaces the previous approach where the mapper had to inspect state to build responses, instead allowing the mapper to read Change values directly. The Change struct includes fields for boolean flags (IncludeSelf, IncludeDERPMap, IncludeDNS, IncludeDomain, IncludePolicy), peer change lists (PeersChanged, PeersRemoved, PeerPatches), and a PingRequest for connectivity checks. The Change.Merge method combines multiple pending changes for a single tick, with specific handling for each field: boolean flags are ORed together, peer lists are concatenated and deduplicated, and PingRequest follows a first-wins strategy. The implementation also includes helper methods like IsEmpty, IsSelfOnly, IsTargetedToNode, IsFull, and Type for categorization. Tests verify field synchronization and merge behavior.

hscontrol/types/change · high confidence

New code-first Huma implementation for the Headscale v1 API

The v1 API has been rewritten using the Huma framework, replacing the previous implementation. This change introduces a code-first approach where the API is defined via Go structs and annotations, which automatically generates the OpenAPI 3.1 specification. The new implementation includes handlers for users, nodes, API keys, pre-auth keys, authentication, and policy management, all wired through a central registration system. Authentication is enforced via a bearer token middleware, and error mapping is standardized to return appropriate HTTP status codes.

hscontrol/api/v1 · high confidence

New utility functions for IP, DNS, and logging

Added new utility functions in the hscontrol/util package to handle IP address parsing and set operations, generate MagicDNS root domains for IPv4 and IPv6, validate usernames and parse CLI login URLs, manage file and directory creation, and integrate GORM logging with Zerolog.

hscontrol/util · high confidence

Repository-wide development tooling and configuration scaffolding

The repository now includes a comprehensive set of configuration files to standardize development workflows and code quality. A \.golangci.yaml\ file configures the Go linter with specific rules, exclusions, and settings. A \.pre-commit-config.yaml\ file sets up git hooks for formatting and linting, while \.editorconfig\ enforces consistent file formatting across editors. Additionally, \.dockerignore\ is added to optimize Docker builds, and \.prettierignore\ is configured to exclude specific paths from formatting. These changes establish a consistent, automated quality gate for all contributors.

(repo-wide) · high confidence

Safe logging wrappers for sensitive data

A new \hscontrol/util/zlog\ package provides safe logging wrappers for \tailcfg.Hostinfo\ and \tailcfg.MapRequest\. These wrappers implement \zerolog.LogObjectMarshaler\ to intentionally redact sensitive information such as device fingerprinting data, client endpoints, and full authentication keys, ensuring that only safe fields (like hostname, OS family, and node key prefixes) are logged. The \zf\ subpackage exports constants for field names to ensure consistency across the codebase.

hscontrol/util/zlog · high confidence

Support for dynamic DNS records via external file

The DNS control plane now supports loading extra DNS records from an external JSON file. A new file watcher monitors the specified path for changes, automatically updating the DNS state when the file is modified, created, or restored after deletion. This allows administrators to manage DNS records outside of the standard control plane API, with the system handling file system events and background retries to ensure reliability.

hscontrol/dns · high confidence

Behavioural changes

Centralize static assets and introduce dark mode support

The hscontrol/assets package now embeds the favicon, CSS stylesheet, and SVG logo directly into the binary, consolidating static file management. The new style.css implements the Material for MkDocs design system, which includes CSS variables for both light and dark color schemes, enabling automatic dark mode support in the web interface.

hscontrol/assets · high confidence

Consolidated Docker test utilities with improved reliability and diagnostics

The integration test helpers in the dockertestutil package have been reorganized into a dedicated, modular package. This introduces robust, retry-backed operations for Docker network management (including custom subnet support and stable disconnection/reconnection handling), authenticated Docker Hub image pulling with exponential backoff, and enhanced diagnostic logging for failed builds and container execution. These changes improve the stability of integration tests by handling transient Docker API errors and providing more detailed output for debugging failures.

integration/dockertestutil · high confidence

Hardened headscale systemd service and packaging scripts

The headscale systemd service unit and Debian packaging scripts have been updated to improve security and reliability. The service now enforces strict sandboxing and privilege restrictions, including MemoryDenyWriteExecute, NoNewPrivileges, PrivateDevices, and various Protect\* directives. System call filtering is tightened to exclude @privileged and @resources, and the service no longer requires CAP\_CHOWN or triggers on syslog.target. The Debian package now includes postinst, postrm, and prerm scripts to manage the headscale user, group, and service state during install, remove, and upgrade operations.

packaging · high confidence

Headscale CLI and configuration loading restructured

The Headscale CLI has been restructured to use a new entry point in cmd/headscale/headscale.go, which initializes logging and delegates to the cli.Execute() function. A new test suite (headscale\_test.go) validates that the application correctly loads and interprets the example configuration file, verifying settings for the server URL, listen address, metrics port, database type, and TLS options.

cmd/headscale · high confidence

Headscale now enforces a minimum Tailscale client version

The \hscontrol/capver\ package has been introduced to manage Tailscale capability versions. This change establishes a minimum supported capability version (currently corresponding to Tailscale v1.80), meaning Headscale will refuse to serve clients with older versions. The system also provides a list of the latest 10 major.minor Tailscale versions, enabling Headscale to inform clients about supported versions. This ensures Headscale only interacts with sufficiently recent Tailscale clients.

hscontrol/capver · high confidence

Improved determinism and safety in DERP map handling

The DERP map loading and merging logic has been refactored to ensure deterministic node shuffling and prevent data races. The \GetDERPMap\ function now explicitly clones regions when merging multiple DERP map sources (from config, URLs, or local paths), preventing shared pointers that could cause concurrent modification issues. Additionally, the node shuffle operation is made deterministic by sorting region IDs before iteration, ensuring consistent behavior across runs and fixing flaky tests.

hscontrol/derp · high confidence

Improved filter rule reduction for subnet routers and exit nodes

The policy utility now more accurately reduces global filter rules for individual nodes. Subnet routers now receive filter rules for destinations their subnets cover, and exit nodes are correctly provided with rules targeting the public internet to accept traffic forwarded by autogroup:internet sources. Additionally, CapGrant rules are now properly filtered to only include entries relevant to each node's specific IPs or approved subnet routes.

hscontrol/policy/policyutil · high confidence

Improved map response batching and concurrency handling

The mapper's batcher now serializes per-node work to prevent out-of-order delivery and coalesces duplicate policy recomputes per tick. It also ensures that unready connections do not receive broadcast deltas before their initial map, and fixes race conditions in cleanup and lookups. Additionally, the batcher tracks worker goroutines and stops the ticker on Close to avoid leaks.

hscontrol/mapper · high confidence

Matcher now includes CapGrant destinations in policy matching

The policy matcher in hscontrol/policy/matcher has been refactored to explicitly include CapGrant.Dsts when constructing match rules. Previously, cap-grant-only rules (such as tailscale.com/cap/relay) would not contribute to peer-visibility derivation, potentially hiding the cap target from the source. This change ensures that destinations specified in CapGrant.Dsts are correctly matched, fixing a bug where such rules were effectively ignored in the matching logic.

hscontrol/policy/matcher · high confidence

Migrate all HTML templates to Go's elem-go library

The \hscontrol/templates\ package has been refactored to use the \elem-go\ library for generating HTML, replacing the previous templating approach. This change introduces a new, consistent design system for all Headscale web pages, including authentication success/error pages, the node registration confirmation, the debug ping page, and the Apple/Windows configuration guides. The templates now share common components like \successBox\, \errorBox\, and \page\ wrappers, ensuring a uniform look and feel across the application.

hscontrol/templates · high confidence

Migrate embedded DERP server to the tailscale/derpserver package

The embedded DERP server implementation in hscontrol/derp/server has been refactored to use the tailscale.com/derp/derpserver package API. This change updates the server's internal structure to wrap the upstream DERP server, enabling features such as client verification (via the SetVerifyClientURL configuration) and WebSocket-based connection handling. The new implementation also includes a debug mode (HEADSCALE\_DEBUG\_DERP\_USE\_IP) to resolve hostnames to IP addresses for integration testing.

hscontrol/derp/server · high confidence

Policy manager introduces route auto-approval and peer reduction logic

The \hscontrol/policy\ package now implements a \PolicyManager\ interface that manages ACL filters, peer maps, and SSH policies. A key behavioral change is the introduction of \ApproveRoutesWithPolicy\, which automatically approves announced routes based on policy rules, ensuring that previously approved routes are never removed even if they are no longer advertised. Additionally, the \ReduceNodes\ and \ReduceRoutes\ functions now use matchers to determine which nodes and routes are accessible, supporting features like \autogroup:self\ and tag-based approvals.

hscontrol/policy · high confidence

Standardize test infrastructure with CI-scaled timeouts and certificate helpers

The integration test suite now uses standardized, CI-scaled timeouts for operations like HA convergence, policy propagation, and auth flows, with durations automatically doubled in CI environments to account for resource contention. Additionally, new utility functions have been added to the integration test helpers to generate CA certificates and server certificates for testing TLS and client verification scenarios.

integration/integrationutil · high confidence

Test coverage

Add node attribute test cases for SaaS compatibility, relay server control, and IPv4 disabling; Added SSH policy validation test data; Added policy test captures from Tailscale SaaS; Added test data for SSH policy validation scenarios; Contract tests for the v1 and v2 API implementations; Expanded in-process control plane testing harness; Improved state management and testing for node registration and HA health probing; Integration test suite for Headscale's API, CLI, and authentication flows; Updated ACL test data for policy v2 scenarios; Updated route filtering test data for policy v2.

Dependencies

Updated Go dependencies and documentation requirements

The project's Go module dependencies (go.mod, go.sum) and documentation requirements (docs/requirements.txt) have been updated. This includes upgrading the Go version to 1.26.5 and updating various libraries such as tailscale.com to v1.101.0-pre, golang.org/x/net to v0.56.0, and several other direct and indirect dependencies. Additionally, new dependencies for documentation generation (mike, mkdocs-materialx, etc.) have been added to docs/requirements.txt.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 64 → 64 (-0.5)
  • Rubric changed (rubric-2026.08.18 → rubric-2026.08.19) — scores are not directly comparable.

Lenses

  • Code Health 65 → 65 (+0.0)
  • Architecture 100 → 100 (+0.0)
  • Maturity 63 → 63 (+0.1)
  • Readiness 63 → 63 (+0.0)
  • Security 62 → 61 (-1.2)
  • Domain Modelling 82 → 82 (+0.0)

Resolved (1)

  • Off-boarding risk: anonymized user #1

New (7)

  • Medium IaC: CKV_DOCKER_3 (Dockerfile.derper)
  • Medium IaC: CKV_DOCKER_3 (Dockerfile.integration)
  • Medium IaC: CKV_DOCKER_3 (Dockerfile.integration-ci)
  • Medium IaC: CKV_DOCKER_3 (Dockerfile.tailscale-HEAD)
  • Medium IaC: CKV_DOCKER_3 (Dockerfile.tailscale-rs)
  • Medium IaC: CKV_DOCKER_3 (Dockerfile.wasmclient)
  • Off-boarding risk: anonymized user #1

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

juanfont/headscale was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 6 August 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 565fd254d06c4c7f9a8cad1714a43445c79ba420 — the exact code this score is about.
  • Scored under rubric-2026.08.19 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer latest.