headscale/hscontrol
Kristoffer Dalby 75e56df9e4 hscontrol: enforce that tagged nodes never have user_id
Tagged nodes are owned by their tags, not a user. Enforce this
invariant at every write path:

- createAndSaveNewNode: do not set UserID for tagged PreAuthKey
  registration; clear UserID when advertise-tags are applied
  during OIDC/CLI registration
- SetNodeTags: clear UserID/User when tags are assigned
- processReauthTags: clear UserID/User when tags are applied
  during re-authentication
- validateNodeOwnership: reject tagged nodes with non-nil UserID
- NodeStore: skip nodesByUser indexing for tagged nodes since
  they have no owning user
- HandleNodeFromPreAuthKey: add fallback lookup for tagged PAK
  re-registration (tagged nodes indexed under UserID(0)); guard
  against nil User deref for tagged nodes in different-user check

Since tagged nodes now have user_id = NULL, ListNodesByUser
will not return them and DestroyUser naturally allows deleting
users whose nodes have all been tagged. The ON DELETE CASCADE
FK cannot reach tagged nodes through a NULL foreign key.

Also tone down shouty comments throughout state.go.

Fixes #3077
2026-02-20 21:51:00 +01:00
..
assets editorconfig: add basic editor config 2025-12-16 10:12:36 +01:00
capver capver: regenerate from docker tags 2026-02-07 08:23:51 +01:00
db hscontrol: enforce that tagged nodes never have user_id 2026-02-20 21:51:00 +01:00
derp all: fix golangci-lint issues (#3064) 2026-02-06 21:45:32 +01:00
dns all: fix golangci-lint issues (#3064) 2026-02-06 21:45:32 +01:00
mapper all: upgrade to Go 1.26rc2 and modernize codebase 2026-02-08 12:35:23 +01:00
policy policy/v2: add policy unmarshal tests for bracketed IPv6 2026-02-20 21:49:21 +01:00
routes all: upgrade to Go 1.26rc2 and modernize codebase 2026-02-08 12:35:23 +01:00
state hscontrol: enforce that tagged nodes never have user_id 2026-02-20 21:51:00 +01:00
templates Link to headscale.net for docs 2026-01-16 14:54:04 +01:00
types hscontrol: enforce that tagged nodes never have user_id 2026-02-20 21:51:00 +01:00
util all: apply golangci-lint 2.9.0 fixes 2026-02-19 08:21:23 +01:00
app.go all: fix golangci-lint issues (#3064) 2026-02-06 21:45:32 +01:00
auth.go node: implement disable key expiry via CLI and API 2026-02-20 21:49:55 +01:00
auth_tags_test.go state: fix expiry handling during node tag conversion 2026-02-04 15:44:55 +01:00
auth_test.go node: implement disable key expiry via CLI and API 2026-02-20 21:49:55 +01:00
debug.go all: fix golangci-lint issues (#3064) 2026-02-06 21:45:32 +01:00
grpcv1.go node: implement disable key expiry via CLI and API 2026-02-20 21:49:55 +01:00
grpcv1_test.go all: fix golangci-lint issues (#3064) 2026-02-06 21:45:32 +01:00
handlers.go all: upgrade to Go 1.26rc2 and modernize codebase 2026-02-08 12:35:23 +01:00
metrics.go all: fix golangci-lint issues (#3064) 2026-02-06 21:45:32 +01:00
noise.go all: upgrade to Go 1.26rc2 and modernize codebase 2026-02-08 12:35:23 +01:00
oidc.go all: fix golangci-lint issues (#3064) 2026-02-06 21:45:32 +01:00
oidc_template_test.go make tags first class node owner (#2885) 2025-12-02 12:01:25 +01:00
oidc_test.go oidc: make email verification configurable 2025-12-18 11:42:32 +00:00
platform_config.go all: fix golangci-lint issues (#3064) 2026-02-06 21:45:32 +01:00
poll.go all: fix golangci-lint issues (#3064) 2026-02-06 21:45:32 +01:00
tailsql.go all: fix golangci-lint issues (#3064) 2026-02-06 21:45:32 +01:00
templates_consistency_test.go Link to headscale.net for docs 2026-01-16 14:54:04 +01:00