v0.29.4
microsoft/agent-host-protocolv0.29.4Sep 23, 2026by github-actions[bot]
Upgrading?
AI Summary
Focuses on hardening the OpenID Connect (OIDC) authentication flow, optimizing map update efficiency to reduce unnecessary network traffic, and resolving compatibility issues with mobile and TV clients.
Key Highlights
- Hardens OIDC callback security, preventing state reuse and improving issuer configuration validation
- Fixes Android app crash caused by nodes incorrectly listing themselves as peers
- Optimizes map updates to only send changes for minor updates (e.g., LastSeen) instead of full maps
- Fixes exit nodes not being offered to viewers whose only matching rule is a `via` grant
- Allows `#`-prefixed metadata fields to be used in policy rules, grants, and nodeAttrs
Full Release Notes
**Minimum supported Tailscale client version: v1.80.0** ### Changes - Fix a node being listed among its own peers in an incremental map update, which crashes the Tailscale Android app on the device list [#3459](https://github.com/juanfont/headscale/pull/3459) - Fix deleting a node leaving its long poll open, so the client stayed connected instead of asking for a new login [#3449](https://github.com/juanfont/headscale/pull/3449) - Fix interactive OIDC login when the confirmation page is reloaded by an ad blocker, back navigation, or pull-to-refresh; the confirmation page now has its own URL, keeping single-use authorization codes out of reloads [#3448](https://github.com/juanfont/headscale/pull/3448) - Harden the OIDC callback: state and nonce cookies take their Secure flag from `server_url` so they survive a TLS-terminating proxy, a callback state is single-use, and an invalid `oidc.issuer` or a missing `oidc.client_id`/`oidc.client_secret` now fails at startup [#3334](https://github.com/juanfont/headscale/pull/3334) - Fix HTTP metrics only counting `OPTIONS` requests, so `http_requests_total` and `http_request_duration_seconds` now cover regular traffic [#3414](https://github.com/juanfont/headscale/pull/3414) - Fix extra-records filewatcher hanging on shutdown after the watched file is deleted, and leaking the watcher when setup fails [#3437](https://github.com/juanfont/headscale/pull/3437) - Lowercase DNS extra record names so mixed-case records resolve [#3366](https://github.com/juanfont/headscale/pull/3366) - Fix `headscale users rename` sending the raw `--identifier` flag value instead of the matched user's identifier, so renaming by name works again [#3442](https://github.com/juanfont/headscale/pull/3442) - Fix tailsql not shutting down with headscale, leaving the process hanging on graceful shutdown [#3400](https://github.com/juanfont/headscale/pull/3400) - Fix tvOS setup instructions: install the VPN configuration before setting the coordination server URL [#3431](https://github.com/juanfont/headscale/pull/3431) - Map requests that only bump LastSeen, endpoints or DERP region no longer resend the whole node to every peer, and health probes that change nothing no longer write. Adds `headscale_mapper_changes_dropped_total` and `headscale_ha_health_updates_total` [#3417](https://github.com/juanfont/headscale/issues/3417) [#3450](https://github.com/juanfont/headscale/pull/3450) - The peer map is keyed by node ID and reused for writes that cannot change peer visibility, so a routine map request no longer rebuilds it. Adds `headscale_nodestore_snapshot_builds_total` [#3417](https://github.com/juanfont/headscale/issues/3417) [#3450](https://github.com/juanfont/headscale/pull/3450) - Fix an expired node staying online forever, because expiring it updated the key deadline without ending its map session [#3472](https://github.com/juanfont/headscale/pull/3472) - Fix ACME renewal stopping permanently after a `badNonce` reply, because the error logging middleware drained the response body the acme client needs to detect it [#3461](https://github.com/juanfont/headscale/pull/3461) - Fix `#`-prefixed metadata fields being rejected outside `acls`, so policy editors can store metadata in grants, SSH rules and `nodeAttrs` [#3481](https://github.com/juanfont/headscale/pull/3481) - Fix exit nodes not offered by recent macOS and iOS clients, which read the `suggest-exit-node` peer attribute rather than the advertised `0.0.0.0/0` routes [#3487](https://github.com/juanfont/headscale/pull/3487) - Fix exit node not offered to viewers whose only matching rule is a `via` grant; peer visibility now comes from the peer map alone [#3409](https://github.com/juanfont/headscale/pull/3409) ## Upgrade Please follow the steps outlined in the [upgrade guide](https://headscale.net/stable/setup/upgrade/) to update your existing Headscale installation. ## Changelog * 3a2b133a418d008e73b627b404c2b2465d10d4da .github/workflows: regenerate the integration test matrix * bdfa3401ff40af2ccd4ad8e1e96069640907460c AGENTS.md: drop stale line numbers * 8106636c7f8d0cf8c9d4fb0beae94415069b768b CHANGELOG: add 0.29.4 * b9b2beb78167888d3859eaf2f8dba942f6aec257 Update AppleTV configuration steps * 2a76860bdb9dcc575e694448c14a50588b2846e7 build: bump test image Go to 1.27.1 * 974becf658e09cef54f243b1407f5008ba77a270 change, mapper: distinguish deleted nodes * b3b55cc472959113d457ca99aca06cd4cd0a401b cli: fix users rename when resolved by name * 46a80ea8f915a8f27c870fe8a2c2ed8d97cf68b1 dns: cancel extra-records retry on shutdown and close watcher on setup error * 33db8c6b2940b716fb2e7bc5c848f98e8ba06b51 fix(metrics): collect metrics for non-OPTIONS requests * 032470a5d3ef04dd866f15a5f493b13e42a88e84 hscontrol: cancel tailsql on graceful shutdown * ebe18cebffb528efc53247054aa42994ece40fe5 hscontrol: keep the ACME error body readable in acmeLogger * c7d9d035006d3b44b05e8545022d4e62067a0319 hscontrol: replace tailscale line refs with doc links * 1e528f7f52c208b666d8884a1f24046fa148c324 integration: cover deletion across client versions * b9c7b4c44beec953f15c92a8feadcbe8964807ce integration: cover node deletion ending the long poll * 7783e7f679e6de1b5e28c13807e3276681725d39 integration: cover node expiry and recovery for every client * 625fa86e1ac5129903765ec0bd2fcf664022b73e integration: pin docker client to daemon API version * cc41593d9d48d99d5249f5a7bc4889a333faf7ba integration: pin which Hostinfo changes reach peers * fc894aa9da6c63f38a4b2bcea402c44f769110d2 linting issue fix * 2b8dbea41278ce5e22d35400f55f30307f557b49 mapper: assert no map response lists the recipient as its own peer * b8da1c2d6f2ccb71812d3b095d9b9b50495c28df mapper: drop empty changes before fan-out * 397149e9be086424447eb731593f6c49d2696132 mapper: stop a deleted node's map session * 9fbf7b9b6010f74c84598ac3dd973a1970b0a905 mapper: take peer visibility from the peer map only * d3882440258b0dd4742b0209ed3fcfb722f2f565 noise: make deleted-node expiry clock independent * 2b28f5756b3b5b293568b1e03f5babc21f230079 oidc: harden callback CSRF cookies, state reuse, and issuer config * cbb9357d1cb4ef43df37c7884a5fe4e826efad7b oidc: harden reloadable confirmation flow * 2da47a77d66de2e5bd52a17b7be7fab5601578ea oidc: serve the registration confirmation page from a reloadable URL * 938c2bd75303cd3f4b2c8cd3462c3a72b8e6cb8e policy,state: key the peer map by node ID * bc5b9d56b26178dee7ce9660b76fa44f9eef792c policy,types: skip recompile when the user list is unchanged * 8490631f06226a719f4106689be9e43e96a16706 policy/v2: add via exit node capture * 694bafee0a254a87e4dac629efc64d5d7b999bab policy/v2: compare peer CapMap against SaaS route captures * 5aded15bf2e53f21892decc702370346dd39876e policy/v2: suggest approved exit nodes by default * aa4c952bca9c8d55e79a930d474099b5674e4845 policy: ignore '#' metadata fields across the whole policy * fb197db16386ede870dad8d0cfb738940334fb5c poll, noise: tell a deleted node to re-authenticate * 83eff4000a97faae552b908fd08280e26e918a97 poll: interrupt blocked map writes * a7f7e6a4016b3c1e8877e60a0eae2277811105b2 servertest: compare user-owned nodes in via compat tests * 8973347d228fbf92efc86af05c4cc2be95fc7b54 state: classify map requests before broadcasting * d4b073e830f5782ebc3d637338e07e767bdc9598 state: exclude self from peers on the named peer-ID path * a91f708adc70c4fa615e8b10b82c58d086599ba5 state: mark expired nodes offline without ending the session * 0fca2bb646bb89736443344468c7fa4e8d56d941 state: preserve committed node deletion changes * fdb782daa5974b78868ae156cc81a5da9fce7870 state: rename persist helpers to say what they do * 6a0f67d56e2d031ac4f0a2cc23b644c2563a00ab state: resolve changed peers through adjacency * 237dc74e73c5aca4716da9b11f0b462eb5ec007f state: reuse peer adjacency for payload-only writes * 8f7ee375e9a608614e43925017f7164b57015587 state: skip node health writes that change nothing * b972da3fe98e17338ad6dd01f64f10fb30a3c624 state: stop broadcasting a whole peer on disconnect * e3dba1fdf9a8e88bfdd7a58fc2d318c2cd7e2d3b templates: apply the tvOS setup reorder to the served /apple page * 2b6cb3a2cceb08bed82d533c060d033e5540e330 types/change: drop unused VisibilityChange * 4411264ef992d69735e41469f51a098e778636f4 types: detect policy change on user identity and exit routes * b4f991b3814144702371213b01152cb91b22a5b1 types: lowercase DNS extra record names * e6c0a8adeeee30665c130e5c5c5468e5f4a82d6c types: regenerate node view
Related Repositories
openclaw/openclaw★ 392,689
The AI that really does things. Any OS. Any Platform. The lobster way. 🦞
nilbuild/developer-roadmap★ 370,064
Interactive roadmaps, guides and other educational content to help developers grow in their careers.
morluto/rea★ 357,472
Reverse engineer anything with agents, from app behavior down to native binaries.
anomalyco/opencode★ 219,654
The open source coding agent.
n8n-io/n8n★ 208,248
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.