Ask the vault for a bus process's account only once it is issued, so the vault never makes a random value under an account's name (issue 774)
At 16:36:51 the vault handed own/novox/nats/broker-nats-tools to the controller as a plain random own
secret, and owes the bus-account hashes of it and of the controller's broker-address and
broker-management for good ("holds no account the controller hands (not JSON)"). The controller decided
that: its send asks the vault (`get`) for every own secret of a core module, a bus process's account
among them, before the account is issued; the vault, holding none, makes one.
The send now leaves out of that ask a process's account nobody issued (the same rule as its warning
line); the machine keeps the controller's stand-in until the account is issued and handed to the vault.
The vault side (not minting an account-shaped name, and replacing the random value already held) is
mesh-catalog's mesh-vault, with build-catalog.
Quick fix: this filter on the ask. Thorough fix: process accounts minted by the vault itself (ADR 0113 §6,
research 072 milestone 6), so no part asks for one before it exists. Chose quick: milestone 6 is not
started, and the filter removes the cause on the controller's side now.
Research 072 piece: milestone 6 (identity and bus accounts to the vault): until then the controller asks
the vault only for what exists.
This commit is contained in:
@@ -250,7 +250,7 @@ func prepareSend(ctx context.Context, open *stores, node string) ([]string, erro
|
||||
if n.Stated && n.Contract >= compose.VaultBoxContract {
|
||||
boxes, err := coreBoxesFor(ctx, inv, node, resolved.Plan.Modules, func(m catalogue.Manifest) bool {
|
||||
return handing.Handing(m)
|
||||
}, true)
|
||||
}, true, in.BusMinted)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -69,7 +69,14 @@ type coreBoxes struct {
|
||||
// coreModulesOf is every module of the plan on the core's list whose own secrets this machine's declaration carries,
|
||||
// with their plain own secret names, sorted: one handed to the provisioner has its secrets from the vault through the
|
||||
// client, and one issued outside the mesh is never the vault's to seal here.
|
||||
func coreModulesOf(modules []catalogue.Manifest, handed func(catalogue.Manifest) bool) map[string][]string {
|
||||
//
|
||||
// **Nor a process's bus account nobody issued yet** (sweep 2026-10-30, issue 774). Asked with `get`, the vault holds
|
||||
// none and makes a random value under the account's name: own/novox/nats/broker-nats-tools at 16:36:51, and the
|
||||
// controller's own broker-address and broker-management, which the vault then finds holding no account ("not JSON")
|
||||
// and owes their hashes for good. Until the controller issues the account and hands it to the vault, the machine has
|
||||
// the controller's stand-in (prepareSend), as every module below the vault's contract does.
|
||||
func coreModulesOf(modules []catalogue.Manifest, handed func(catalogue.Manifest) bool, node string,
|
||||
minted []string) map[string][]string {
|
||||
out := map[string][]string{}
|
||||
for _, m := range modules {
|
||||
if !catalogue.CarriesVaultSealed(m.Module) || (handed != nil && handed(m)) {
|
||||
@@ -77,7 +84,7 @@ func coreModulesOf(modules []catalogue.Manifest, handed func(catalogue.Manifest)
|
||||
}
|
||||
var names []string
|
||||
for name, own := range m.OwnSecrets.Plain() {
|
||||
if own.IssuedBy != catalogue.IssuedOutside {
|
||||
if own.IssuedBy != catalogue.IssuedOutside && processAccountWarning(m, node, name, minted) == "" {
|
||||
names = append(names, name)
|
||||
}
|
||||
}
|
||||
@@ -208,8 +215,8 @@ var coreVault = func(ctx context.Context) coreAsk {
|
||||
|
||||
// coreBoxesFor is coreBoxesOf for one machine, read from and kept in the store, and said on a send.
|
||||
func coreBoxesFor(ctx context.Context, inv *inventory.Inventory, node string, modules []catalogue.Manifest,
|
||||
handed func(catalogue.Manifest) bool, allocating bool) (coreBoxes, error) {
|
||||
core := coreModulesOf(modules, handed)
|
||||
handed func(catalogue.Manifest) bool, allocating bool, minted []string) (coreBoxes, error) {
|
||||
core := coreModulesOf(modules, handed, node, minted)
|
||||
if len(core) == 0 {
|
||||
if allocating {
|
||||
settleVaultSilent(ctx, node)
|
||||
|
||||
@@ -124,8 +124,35 @@ func TestTheCoresModulesAreTheListsWithTheirOwnSecrets(t *testing.T) {
|
||||
{Module: "postgres", OwnSecrets: catalogue.OwnSecrets{"superuser": {Path: "/c"}}},
|
||||
{Module: "mesh-provisioner", OwnSecrets: catalogue.OwnSecrets{"broker": {Path: "/d"}}},
|
||||
}
|
||||
got := coreModulesOf(modules, func(m catalogue.Manifest) bool { return m.Module == "mesh-provisioner" })
|
||||
got := coreModulesOf(modules, func(m catalogue.Manifest) bool { return m.Module == "mesh-provisioner" }, "anchor", nil)
|
||||
if want := map[string][]string{"nats": {"broker"}}; !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// Sweep 2026-10-30 (issue 774): a bus process's account is asked of the vault only once it is issued; before, the vault
|
||||
// would make a random value under the account's name.
|
||||
func TestAnUnissuedProcessAccountIsNotAskedOfTheVault(t *testing.T) {
|
||||
nats, err := catalogue.ParseManifest([]byte(`{"module":"nats","version":"1","emits":["x"],
|
||||
"own-secrets":{"broker":{"path":"/a"},"broker-nats-tools":{"path":"/b","owner":"nats-tools"}},
|
||||
"resources":[{"id":"account","type":"user","name":"nats-tools"},
|
||||
{"id":"nats-tools","type":"process","run":["./nats-tools"],"user":"nats-tools","bus":{"emits":["x"]}}]}`))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(nats.ProcessBuses()) == 0 {
|
||||
t.Fatal("the fixture declares no bus process")
|
||||
}
|
||||
for name, c := range map[string]struct {
|
||||
minted []string
|
||||
want []string
|
||||
}{
|
||||
"not issued": {nil, []string{"broker"}},
|
||||
"issued": {[]string{processUser("anchor", "nats", "nats-tools")}, []string{"broker", "broker-nats-tools"}},
|
||||
} {
|
||||
got := coreModulesOf([]catalogue.Manifest{nats}, nil, "anchor", c.minted)
|
||||
if !reflect.DeepEqual(got["nats"], c.want) {
|
||||
t.Errorf("%s: asks %v, want %v", name, got["nats"], c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user