The token carries the node's name

Found by raising a mesh end to end. The broker account a joining node
authenticates as is named after the node, and exists before that machine
has been told anything — so the node has to know its name before the mesh
can tell it. Without it, enrolment fails at the broker with an empty
username, which says nothing about why.

Not a secret, and the issuer already knows it. The wire-format test now
covers it, so a rename on either side fails in both repositories rather
than at enrolment on a real machine.
This commit is contained in:
2026-08-30 02:36:57 +02:00
parent b9aac2b700
commit 02d1020bce
3 changed files with 38 additions and 8 deletions
+15 -1
View File
@@ -19,7 +19,7 @@ import (
"strings"
)
// Token is the four things, and it is assembled by whatever holds all four.
// Token is everything a joining node needs, assembled by whatever holds all of it.
//
// Two contexts contribute: `inventory` owns the node record and mints the secret, `identity` owns
// the signing key. Neither reads the other's store — the process holding both grants asks each
@@ -27,6 +27,17 @@ import (
type Token struct {
Version int `json:"v"`
// Node is what the mesh calls this machine.
//
// Not a secret and not the node's to choose — the record was created before the token was
// issued, and the broker account the node must authenticate as is named after it. So the node
// has to know it *before* the mesh can tell it anything, which is why it travels here.
//
// It was not here at first, and enrolment then needed a separate flag while its own help said
// the token was the only thing required. The failure that produced was a connection refused
// with an empty username, which says nothing about the cause.
Node string `json:"node,omitempty"`
// Broker is an address and not a name. There is no resolution before joining, which is why
// this is the one place in the mesh where an address is carried deliberately.
Broker string `json:"broker,omitempty"`
@@ -50,6 +61,9 @@ type Token struct {
// a compromised broker could then forge declarations, and that is the whole machine.
func (t Token) Missing() []string {
var missing []string
if strings.TrimSpace(t.Node) == "" {
missing = append(missing, "the node's name — the broker account is named after it")
}
if strings.TrimSpace(t.Broker) == "" {
missing = append(missing, "the broker's address — there is nowhere to connect to")
}