api/v2: show userId on admin-made tagged keys

An admin key's user is recorded as the creator of the tagged keys it
makes. A tagged key re-registers a machine by its tags, whoever made it.
This commit is contained in:
Kristoffer Dalby committed 2026-10-30 14:55:37 +00:00
1 parent 5454da3b34
commit 792a75decc
9 files changed
+224 -68

No files matched your search

+36 -14
View File
@@ -657,8 +657,14 @@ func TestPreAuthKeyCorrectUserLoggedInCommand(t *testing.T) {
listNodes, err = headscale.ListNodes()
assert.NoError(ct, err)
assert.Len(ct, listNodes, 1, "Should have exactly 1 node for user1")
assert.Equal(ct, user1, listNodes[0].User.Name, "Node should belong to user1")
if len(listNodes) == 1 {
assert.Equal(ct, user1, listNodes[0].User.Name, "Node should belong to user1")
}
}, integrationutil.ScaledTimeout(15*time.Second), 1*time.Second)
require.Len(t, listNodes, 1)
userNodeID := listNodes[0].Id
allClients, err := scenario.ListTailscaleClients()
requireNoErrListClients(t, err)
@@ -698,10 +704,15 @@ func TestPreAuthKeyCorrectUserLoggedInCommand(t *testing.T) {
listNodes, err = headscale.ListNodes()
assert.NoError(ct, err)
assert.Len(ct, listNodes, 2, "Should have 2 nodes after re-login")
assert.Equal(ct, user1, listNodes[0].User.Name, "First node should belong to user1")
// Second node is tagged (created with tagged PreAuthKey), so it shows as "tagged-devices"
assert.Equal(ct, "tagged-devices", listNodes[1].User.Name, "Second node should be tagged-devices")
// A tagged key converts the machine's user-owned node in place,
// whoever made the key, so it shows as "tagged-devices".
assert.Len(ct, listNodes, 1, "Should still have 1 node after re-login with a tagged key")
if len(listNodes) == 1 {
assert.Equal(ct, userNodeID, listNodes[0].Id, "The node should be converted, not replaced")
assert.Equal(ct, "tagged-devices", listNodes[0].User.Name, "The node should be tagged-devices")
assert.ElementsMatch(ct, []string{"tag:test1", "tag:test2"}, listNodes[0].Tags)
}
}, integrationutil.ScaledTimeout(20*time.Second), 1*time.Second)
}
@@ -758,6 +769,18 @@ func TestTaggedNodesCLIOutput(t *testing.T) {
assert.NoError(c, err)
}, integrationutil.ScaledTimeout(10*time.Second), integrationutil.FastPoll, "Waiting for user2 tagged preauth key creation")
var userNodeID string
assert.EventuallyWithT(t, func(ct *assert.CollectT) {
nodes, err := headscale.ListNodes()
assert.NoError(ct, err)
assert.Len(ct, nodes, 1, "Should have exactly 1 node for user1")
if len(nodes) == 1 {
userNodeID = nodes[0].Id
}
}, integrationutil.ScaledTimeout(15*time.Second), 1*time.Second)
allClients, err := scenario.ListTailscaleClients()
requireNoErrListClients(t, err)
@@ -791,17 +814,16 @@ func TestTaggedNodesCLIOutput(t *testing.T) {
assert.Equal(ct, "userid:2147455555", status.Self.UserID.String(), "Expected node to be logged in as tagged-devices user")
}, integrationutil.StatusReadyTimeout, 2*time.Second)
// Wait for the second node to appear
var listNodes []*clientv1.Node
// A tagged key converts the machine's user-owned node in place.
assert.EventuallyWithT(t, func(ct *assert.CollectT) {
var err error
listNodes, err = headscale.ListNodes()
listNodes, err := headscale.ListNodes()
assert.NoError(ct, err)
assert.Len(ct, listNodes, 2, "Should have 2 nodes after re-login with tagged key")
assert.Equal(ct, user1, listNodes[0].User.Name, "First node should belong to user1")
assert.Equal(ct, "tagged-devices", listNodes[1].User.Name, "Second node should be tagged-devices")
assert.Len(ct, listNodes, 1, "Should still have 1 node after re-login with tagged key")
if len(listNodes) == 1 {
assert.Equal(ct, userNodeID, listNodes[0].Id, "The node should be converted, not replaced")
assert.Equal(ct, "tagged-devices", listNodes[0].User.Name, "The node should be tagged-devices")
}
}, integrationutil.ScaledTimeout(20*time.Second), 1*time.Second)
// Test: tailscale status output should show "tagged-devices" not "userid:2147455555"