Trust the vault's key alone and write the grants part's user list alone
The controller ended by its unassignment and its lease is never handed, so the engine's lease gate kept trusting the controller's key and the bus node kept the controller's list as a fallback nobody writes (issue 1126, A6). The engine now trusts no controller signature, its hand-over line names the node seat's hand-over, and the user-list follower writes only the grants part's list: a key unreadable or deleted keeps the list loaded, and with no key heard nothing is written. Compositions in the node's bucket name the file's place alone. The guard no longer asks for the controller's user. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
+11
-10
@@ -380,10 +380,11 @@ func resourcesOf(cs []delivery.Composed) []declaration.Resource {
|
||||
// controller's key the node was enrolled with (novox/hq ADR 0539 §3, §11); a node adopted later has it at its adoption.
|
||||
const operatorKeysFile = "operator-keys"
|
||||
|
||||
// trustedKeys are the keys a composition may be signed by: the controller's, which the node was enrolled with, while the
|
||||
// controller holds its lease (ADR 0550 §2: trusted no more once it is handed away), and the operator's, read from
|
||||
// operatorKeysFile each time it is asked, so a key that arrives while the agent runs is trusted at the next composition.
|
||||
// A file that cannot be read trusts the controller's alone, and says so.
|
||||
// trustedKeys are the keys a composition in the node's composition bucket may be signed by: the one given (none for the
|
||||
// agent; the enrolment's signer for the user-list follower, which reads only where the bus's user-list file is from
|
||||
// such a composition, never its list) and the operator's, read from operatorKeysFile each time it is asked, so a key
|
||||
// that arrives while the agent runs is trusted at the next composition. A file that cannot be read trusts the one given
|
||||
// alone, and says so.
|
||||
func trustedKeys(opts options, controllerNow func() ed25519.PublicKey) func() []ed25519.PublicKey {
|
||||
return func() []ed25519.PublicKey {
|
||||
keys := []ed25519.PublicKey{}
|
||||
@@ -509,9 +510,11 @@ func nodeAgent(ctx context.Context, opts options, signer ed25519.PublicKey, trus
|
||||
}
|
||||
}
|
||||
}
|
||||
// The bus's user list, written alone from the newest composition of the bus module (ADR 0547 §8): on every
|
||||
// node, and a node whose compositions carry no list writes nothing.
|
||||
users := userListFollower(opts, session, composedBucket, trustedKeys(opts, trust.Controller), say, func() {
|
||||
// The bus's user list, the grants part's alone (ADR 0547 §8, clause 11; issue 1126), written into the file the
|
||||
// bus module's composition in the node's bucket declares: on every node, and a node whose compositions carry no
|
||||
// list writes nothing. Those compositions were signed with the enrolment's signer and nobody writes them now; they
|
||||
// are read for the file's place alone, never for a list, until the place is read elsewhere (milestone B17).
|
||||
users := userListFollower(opts, session, composedBucket, trustedKeys(opts, func() ed25519.PublicKey { return signer }), say, func() {
|
||||
// This engine wrote the list, so the bus reloads its accounts and answers no JetStream request for a few
|
||||
// seconds: what failed in them is tried again once that is over, not at its next wait.
|
||||
time.AfterFunc(reloadSettles, func() {
|
||||
@@ -520,8 +523,6 @@ func nodeAgent(ctx context.Context, opts options, signer ed25519.PublicKey, trus
|
||||
}
|
||||
})
|
||||
})
|
||||
// A vault key heard (or heard again changed) looks at the list again, so its hashes are handed (ADR 0547 §9).
|
||||
vaultKey.following(users.Again)
|
||||
go func() {
|
||||
if err := users.Run(linked); err != nil && linked.Err() == nil {
|
||||
say("the bus's user list is not followed on this link: " + err.Error())
|
||||
@@ -551,7 +552,7 @@ func nodeAgent(ctx context.Context, opts options, signer ed25519.PublicKey, trus
|
||||
}
|
||||
return out, nil
|
||||
},
|
||||
Trusted: trustedKeys(opts, trust.Controller),
|
||||
Trusted: trustedKeys(opts, noControllerKey),
|
||||
Backup: backupNode(session),
|
||||
// What the filling refused before this apply may be named now: the provisioner's client is told to fill
|
||||
// again (ace, 2026-10-25 21:17).
|
||||
|
||||
Reference in New Issue
Block a user