Genesis can raise a mesh on the new bus, and the carried user list is checked against the composer
The mesh writes its own user list, and at genesis there is no mesh yet to write it. So the installer carries the first one — the controller's own account at a well-known bootstrap password, exactly as the store is reached at `postgres:bootstrap` and the old bus at `guest:guest`, and rotated with them. From the controller's first composition onward the file is the controller's. That left a gap I would not have found by reading: the controller's own account is created before there is a controller to mint one, so nothing recorded a hash for it, and its first composition would have left the writer out of the file it was writing — a bus nothing can connect to, produced by the thing connected to it. It now records a hash of the credential it is actually using, and only if none is recorded, so a restart cannot put the bootstrap password back over a rotated one. The carried list and the derived one are two statements of one fact, so a test compares them: every subject the controller derives must be in the template, and nothing wider. It earned itself immediately — the composer was granting both a role's whole event branch and the one event it actually follows, which is a wider way of saying the same thing, and the wider one wins. Only the submitting half of a role is granted now; what comes back is named exactly. Getting this wrong is the worst kind of silent. A controller whose carried permissions are narrower than the ones it derives comes up, connects, and is refused on the first thing it tries, with an authorisation error naming a subject and not the template that forgot it — and a mesh cannot be raised twice to find out.
This commit is contained in:
@@ -702,6 +702,23 @@ func raiseTheBus(ctx context.Context, inv *inventory.Inventory, address string)
|
||||
}
|
||||
defer js.Close()
|
||||
|
||||
// **Its own user, before anything else.** The controller's account is created by the installer at
|
||||
// a bootstrap password, before there is a controller to mint one — so nothing recorded a hash for
|
||||
// it, and the first composition would leave the writer out of the file it was writing. Recorded
|
||||
// only if absent: a credential the mesh minted since is the one that counts.
|
||||
// **Its own user, before anything else it does here.** The controller's account is created by the
|
||||
// installer at a bootstrap password, before there is a controller to mint one — so nothing
|
||||
// recorded a hash for it, and the first composition would leave the writer out of the file it was
|
||||
// writing: a bus nothing can connect to, produced by the thing connected to it. Recorded only if
|
||||
// absent, so a restart cannot put the bootstrap credential back over a rotated one.
|
||||
if user, password, _ := broker.CredentialIn(address); user != "" && password != "" {
|
||||
if err := inv.SeedBusUser(ctx, inventory.BusUser{
|
||||
Username: user, Kind: inventory.BusController,
|
||||
}, password); err != nil {
|
||||
return fmt.Errorf("cannot record the credential this control plane is using: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
nodes, err := inv.Nodes(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user