From 7d50f33e32eab8de0f843bcb0bb722fcc0e3f3fc Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 30 Oct 2026 15:58:23 +0000 Subject: [PATCH] types: leave MachineAuthorized off peer entries SaaS sets it only on a node's own entry, the only one clients read. Updates #3626 --- hscontrol/mapper/builder.go | 5 +++-- hscontrol/mapper/tail_test.go | 20 ++++++++----------- hscontrol/servertest/mapstream_compat_test.go | 6 ++---- hscontrol/types/node.go | 3 +-- 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/hscontrol/mapper/builder.go b/hscontrol/mapper/builder.go index ec701e977..cb0ba829e 100644 --- a/hscontrol/mapper/builder.go +++ b/hscontrol/mapper/builder.go @@ -109,8 +109,9 @@ func (b *MapResponseBuilder) WithSelfNode() *MapResponseBuilder { func(p netip.Prefix) bool { return !b.mapper.cfg.ServesRoute(p) }, ) - // As on Tailscale SaaS, an expired node's own entry stays authorised and - // unmarked; the client reads its expiry from the past KeyExpiry. + // As on Tailscale SaaS, only a node's own entry is authorised, and an + // expired node's stays so and unmarked; the client reads its expiry from + // the past KeyExpiry. tailnode.MachineAuthorized = true tailnode.Expired = false diff --git a/hscontrol/mapper/tail_test.go b/hscontrol/mapper/tail_test.go index 3d65ce1e0..83e97935f 100644 --- a/hscontrol/mapper/tail_test.go +++ b/hscontrol/mapper/tail_test.go @@ -68,11 +68,10 @@ func TestTailNode(t *testing.T) { dnsConfig: &tailcfg.DNSConfig{}, baseDomain: "", want: &tailcfg.Node{ - Name: "empty", - StableID: "0", - HomeDERP: 0, - Hostinfo: hiview(tailcfg.Hostinfo{}), - MachineAuthorized: true, + Name: "empty", + StableID: "0", + HomeDERP: 0, + Hostinfo: hiview(tailcfg.Hostinfo{}), CapMap: tailcfg.NodeCapMap{ nodecap.Admin: []tailcfg.RawMessage{}, @@ -159,8 +158,6 @@ func TestTailNode(t *testing.T) { Tags: []string{}, - MachineAuthorized: true, - CapMap: tailcfg.NodeCapMap{ nodecap.Admin: []tailcfg.RawMessage{}, nodecap.SSH: []tailcfg.RawMessage{}, @@ -181,11 +178,10 @@ func TestTailNode(t *testing.T) { baseDomain: "example.com", want: &tailcfg.Node{ // a node name should have a dot appended - Name: "minimal.example.com.", - StableID: "0", - HomeDERP: 0, - Hostinfo: hiview(tailcfg.Hostinfo{}), - MachineAuthorized: true, + Name: "minimal.example.com.", + StableID: "0", + HomeDERP: 0, + Hostinfo: hiview(tailcfg.Hostinfo{}), CapMap: tailcfg.NodeCapMap{ nodecap.Admin: []tailcfg.RawMessage{}, diff --git a/hscontrol/servertest/mapstream_compat_test.go b/hscontrol/servertest/mapstream_compat_test.go index 3e734dc9d..eb7cb6e04 100644 --- a/hscontrol/servertest/mapstream_compat_test.go +++ b/hscontrol/servertest/mapstream_compat_test.go @@ -60,9 +60,8 @@ var mapStreamSkipReasons = map[string]string{ "map-delivery/S3.5-remove/db1/frames": policyResponseToEveryNode, "map-delivery/S3.5-restore/db1/frames": policyResponseToEveryNode, - "map-delivery/S2.0/peer-entry/MachineAuthorized": peerAuthorizedSent, - "map-delivery/S2.0/own-entry/Cap": ownCapSent, - "map-delivery/S2.0/own-entry/Online": ownOnlineSent, + "map-delivery/S2.0/own-entry/Cap": ownCapSent, + "map-delivery/S2.0/own-entry/Online": ownOnlineSent, "map-delivery/S2.5/laptop/endpoints-gap-bystander": restartEndpointsKept, "map-delivery/S2.5/laptop/endpoints-gap-svc": restartEndpointsKept, @@ -103,7 +102,6 @@ var mapStreamSkipReasons = map[string]string{ const ( policyResponseToEveryNode = "POLICY_RESPONSE_TO_EVERY_NODE: headscale sends every connected node a policy response when the policy, a node's tags or approved routes, or the set of nodes change; SaaS sends only the nodes whose peers or filter change" restartEndpointsKept = "RESTART_ENDPOINTS_KEPT: headscale keeps a restarted node's last endpoints at its peers until it reports new ones; SaaS sends peers the node without endpoints until then" - peerAuthorizedSent = "PEER_AUTHORIZED_SENT: headscale sets MachineAuthorized on peer entries; SaaS only on a node's own" ownCapSent = "OWN_CAP_SENT: headscale sets Cap on a node's own entry; SaaS only on peers" ownOnlineSent = "OWN_ONLINE_SENT: headscale sets Online on a node's own entry; SaaS only on peers" ) diff --git a/hscontrol/types/node.go b/hscontrol/types/node.go index a68a1ed15..69dcdcc14 100644 --- a/hscontrol/types/node.go +++ b/hscontrol/types/node.go @@ -1484,8 +1484,7 @@ func (nv NodeView) TailNode( Tags: nv.Tags().AsSlice(), - MachineAuthorized: !nv.IsExpired(), - Expired: nv.IsExpired(), + Expired: nv.IsExpired(), } // Set LastSeen only for offline nodes to avoid confusing Tailscale clients