/Release/v0.28.0
同步自上游最新正式版 Release。
Minimum supported Tailscale client version: v1.74.0
Tags are now implemented following the Tailscale model where tags and user ownership are mutually exclusive. Devices can be either
user-owned (authenticated via web/OIDC) or tagged (authenticated via tagged PreAuthKeys). Tagged devices receive their identity from
tags rather than users, making them suitable for servers and infrastructure. Applying a tag to a device removes user-based
ownership. See the Tailscale tags documentation for details on how tags work.
User-owned nodes can now request tags during registration using --advertise-tags. Tags are validated against the tagOwners policy
and applied at registration time. Tags can be managed via the CLI or API after registration. Tagged nodes can return to user-owned
by re-authenticating with tailscale up --advertise-tags= --force-reauth.
A one-time migration will validate and migrate any RequestTags (stored in hostinfo) to the tags column. Tags are validated against
your policy's tagOwners rules during migration. #3011
The map update system has been rewritten to send smaller, partial updates instead of full network maps whenever possible. This reduces bandwidth usage and improves performance, especially for large networks. The system now properly tracks peer
changes and can send removal notifications when nodes are removed due to policy changes.
#2856 #2961
Pre-authentication keys now use bcrypt hashing for improved security #2853. Keys
are stored as a prefix and bcrypt hash instead of plaintext. The full key is only displayed once at creation time. When listing keys,
only the prefix is shown (e.g., hskey-auth-{prefix}-***). All new keys use the format hskey-auth-{prefix}-{secret}. Legacy plaintext keys in the format {secret} will continue to work for backwards compatibility.
The OIDC callback and device registration web pages have been updated to use the Material for MkDocs design system from the official
documentation. The templates now use consistent typography, spacing, and colours across all registration flows.
Headscale no longer supports direct upgrades from databases created before version 0.25.0. Users on older versions must upgrade
sequentially through each stable release, selecting the latest patch version available for each minor release.
API: The Node message in the gRPC/REST API has been simplified - the ForcedTags, InvalidTags, and ValidTags fields have been removed and replaced with a single Tags field that contains the node's applied tags #2993
Tags field instead of ValidTagsheadscale nodes list CLI command now always shows a Tags column and the --tags flag has been removedPreAuthKey CLI: Commands now use ID-based operations instead of user+key combinations #2992
headscale preauthkeys create no longer requires --user flag (optional for tracking creation)headscale preauthkeys list lists all keys (no longer filtered by user)headscale preauthkeys expire --id <ID> replaces --user <USER> <KEY>headscale preauthkeys delete --id <ID> replaces --user <USER> <KEY>Before:
headscale preauthkeys create --user 1 --reusable --tags tag:server
headscale preauthkeys list --user 1
headscale preauthkeys expire --user 1 <KEY>
headscale preauthkeys delete --user 1 <KEY>
After:
headscale preauthkeys create --reusable --tags tag:server
headscale preauthkeys list
headscale preauthkeys expire --id 123
headscale preauthkeys delete --id 123
Tags: The gRPC SetTags endpoint now allows converting user-owned nodes to tagged nodes by setting tags. #2885
Tags: Tags are now resolved from the node's stored Tags field only #2931
--advertise-tags is processed during registration, not on every policy evaluation--advertise-tags from clients--advertise-tags if authorized by tagOwners policyheadscale nodes tag) or the SetTags API after registrationDatabase migration support removed for pre-0.25.0 databases #2883
Remove ability to move nodes between users #2922
headscale nodes move CLI command has been removedMoveNode API endpoint has been removedAdd oidc.email_verified_required config option to control email verification requirement #2860
true (default), only verified emails can authenticate via OIDC in conjunction with oidc.allowed_domains oroidc.allowed_users. Previous versions allowed to authenticate with an unverified email but did not store the emailunverified email error.false, unverified emails are allowed for OIDC authentication and the email address is stored in the userSSH Policy: Wildcard (*) is no longer supported as an SSH destination #3009
autogroup:member for user-owned devicesautogroup:tagged for tagged devicestag:server) for targeted accessBefore:
{ "action": "accept", "src": ["group:admins"], "dst": ["*"], "users": ["root"] }
After:
{ "action": "accept", "src": ["group:admins"], "dst": ["autogroup:member", "autogroup:tagged"], "users": ["root"] }
SSH Policy: SSH source/destination validation now enforces Tailscale's security model #3010
Per Tailscale SSH documentation, the following rules are now enforced:
tag:* or autogroup:tagged as source cannot have username destinations (e.g., alice@) or autogroup:member/autogroup:self as destinationalice@), the source must be that exact same user only. Use autogroup:self for same-user SSH access insteadInvalid policies now rejected at load time:
// INVALID: tag source to user destination
{"src": ["tag:server"], "dst": ["alice@"], ...}
// INVALID: autogroup:tagged to autogroup:member
{"src": ["autogroup:tagged"], "dst": ["autogroup:member"], ...}
// INVALID: group to specific user (use autogroup:self instead)
{"src": ["group:admins"], "dst": ["alice@"], ...}
Valid patterns:
// Users/groups can SSH to their own devices via autogroup:self
{"src": ["group:admins"], "dst": ["autogroup:self"], ...}
// Users/groups can SSH to tagged devices
{"src": ["group:admins"], "dst": ["autogroup:tagged"], ...}
// Tagged devices can SSH to other tagged devices
{"src": ["autogroup:tagged"], "dst": ["autogroup:tagged"], ...}
// Same user can SSH to their own devices
{"src": ["alice@"], "dst": ["alice@"], ...}
hskey-api-{prefix}-{secret}) #2853hskey-reg-{random}) #2853taildrop.enabled configuration option to enable/disable Taildrop file sharing #2955metrics_listen_addr #2914--id flag to expire/delete commands as alternative to --prefix for API Keys #3016Please follow the steps outlined in the upgrade guide to update your existing Headscale installation.
It's best to update from one stable version to the next (e.g., 0.24.0 → 0.25.1 → 0.26.1) in case you are multiple releases behind. You should always pick the latest available patch release.
Be sure to check the changelog above for version-specific upgrade instructions and breaking changes.
Always backup your database before upgrading. Here's how to backup a SQLite database:
# Stop headscale
systemctl stop headscale
# Backup sqlite database
cp /var/lib/headscale/db.sqlite /var/lib/headscale/db.sqlite.backup
# Backup sqlite WAL/SHM files (if they exist)
cp /var/lib/headscale/db.sqlite-wal /var/lib/headscale/db.sqlite-wal.backup
cp /var/lib/headscale/db.sqlite-shm /var/lib/headscale/db.sqlite-shm.backup
# Start headscale (migration will run automatically)
systemctl start headscale
7f003eca Add a page to describe supported registration methods5d300273 Add a tags page and describe a few common operationsd32f6707 Add missing words89e436f0 Bump year/version for mkdocs49b70db7 Conversion from personal to tagged node is reversible04b40718 Fix node expiration success messageee127edb Remove trace log for preauthkeys create2695d152 Use registration key instead of machine key44af0461 all: update Go module dependencies4a744f42 changelog: change api key format97fa117c changelog: set 0.28 dateb5329ff0 flake.lock: update nixpkgs to 2026-02-03eac8a57b flake.nix: update hashes for dependency changesca75e096 integration: add test for tagged→user-owned conversion panica09b0d1d policy/v2: add Caller() to log statements in compileACLWithAutogroupSelf1f32c8bf policy/v2: add IsTagged() guards to prevent panics on tagged nodesc2f28efb policy/v2: add test for issue #2990 same-user tagged device11f0d4cf policy/v2: include nodes with empty filters in BuildPeerMap362696a5 policy/v2: keep partial IPSet on SSH destination resolution errorsfb137a8f policy/v2: use partial IPSet on group resolution errors in autogroup:self pathdf184e52 state: fix expiry handling during node tag conversion306aabbb state: fix nil pointer panic when re-registering tagged node without user4912ceaa state: inline reauthExistingNode and convertTaggedNodeToUser46daa659 state: omit AuthKeyID/AuthKey in node Updates to prevent FK errors0630fd32 state: refactor HandleNodeFromAuthPath for clarityce7c256d state: set User pointer during tagged→user-owned conversiond7f7f2c8 state: validate tags before UpdateNode to ensure consistency