Genesis makes the root secrets, the operator key, and installs the vault
The template raises the store with the password 'bootstrap' and the broker with its image's default administrator, and the installer carried both into the mesh as accepted secrets — permanent, and not secret (novox/hq issue 071). Now the installer makes both credentials, once, at the paths the postgres and lavinmq modules declare as their own secrets, rewrites the produced bundle to use them (the store reads its password from a file; the broker's default account is given the new password by an action before anything dials it), and writes the bundle at 0600 since it now carries them. Before the first secret is accepted it makes the operator's sealing key beside the bundle and gives the mesh the public half, so everything minted from there is sealed to it too (ADR 0085, amended). Phase three adopts the broker as the lavinmq module beside the store and installs mesh-vault as a foundation module; the run ends by writing the operator-sealed export beside the key.
This commit is contained in:
@@ -48,6 +48,7 @@ const (
|
||||
StepApply Step = "apply"
|
||||
StepVerify Step = "verify"
|
||||
StepEnrol Step = "enrol"
|
||||
StepOperator Step = "operator"
|
||||
StepRegistry Step = "registry"
|
||||
StepPublish Step = "publish"
|
||||
StepControlPlane Step = "control-plane"
|
||||
@@ -57,6 +58,8 @@ const (
|
||||
StepSDK Step = "sdk"
|
||||
StepBase Step = "base"
|
||||
StepStore Step = "store"
|
||||
StepBroker Step = "broker"
|
||||
StepVault Step = "vault"
|
||||
StepCatalogue Step = "catalogue"
|
||||
StepNetwork Step = "network"
|
||||
StepFilter Step = "filter"
|
||||
@@ -76,12 +79,12 @@ const (
|
||||
// mesh made, out of a repository and a commit it can name, and can therefore make again.
|
||||
var Steps = []Step{
|
||||
StepPreflight, StepLoad, StepBuild, StepBundle, StepApply, StepVerify,
|
||||
StepEnrol, StepRegistry, StepPublish, StepControlPlane, StepRetire, StepBuilder,
|
||||
StepEnrol, StepOperator, StepRegistry, StepPublish, StepControlPlane, StepRetire, StepBuilder,
|
||||
StepPackages, StepSDK,
|
||||
// Phase two. The twelve above make a mesh that RUNS; these make one that WORKS — able to
|
||||
// build, to say what it holds, on its network, filtering. They used to be things somebody
|
||||
// typed afterwards, which is how they went missing without anything complaining.
|
||||
StepBase, StepStore, StepCatalogue, StepNetwork, StepFilter, StepExtras,
|
||||
StepBase, StepStore, StepBroker, StepVault, StepCatalogue, StepNetwork, StepFilter, StepExtras,
|
||||
}
|
||||
|
||||
// Error is a failure, named by the step it happened in.
|
||||
@@ -201,8 +204,13 @@ type Deps struct {
|
||||
|
||||
// Result is what the bootstrap did, in the shape `--json` prints.
|
||||
type Result struct {
|
||||
System string `json:"system"`
|
||||
DryRun bool `json:"dry-run,omitempty"`
|
||||
// OperatorKey is where the operator's private key was written; OperatorKeyMade whether this
|
||||
// run made it. RootExport is where the operator-sealed export landed.
|
||||
OperatorKey string
|
||||
OperatorKeyMade bool
|
||||
RootExport string
|
||||
System string `json:"system"`
|
||||
DryRun bool `json:"dry-run,omitempty"`
|
||||
|
||||
// Image is what THIS MACHINE'S RUNTIME holds the control plane as, read back from it — and
|
||||
// what the produced bundle names it by.
|
||||
@@ -380,6 +388,31 @@ func Run(ctx context.Context, o Options, d Deps, say func(string)) (Result, erro
|
||||
}
|
||||
result.BundleWas, result.BundlePlaces, result.Bundle = rewritten.Was, rewritten.Places, o.Out
|
||||
result.Temporary = rewritten.TempName
|
||||
// The mesh's root credentials: made here, never the template's (novox/hq issue 071).
|
||||
creds, err := RootSecrets(o.DryRun)
|
||||
if err != nil {
|
||||
return result, failed(StepBundle, err)
|
||||
}
|
||||
root, err := RewriteRoot(&rewritten, creds)
|
||||
if err != nil {
|
||||
return result, failed(StepBundle, err)
|
||||
}
|
||||
for _, c := range []struct {
|
||||
what, path string
|
||||
made bool
|
||||
}{{"store superuser", StoreSuperuserFile, creds.StoreMade}, {"broker admin", BrokerAdminFile, creds.BrokerMade}} {
|
||||
switch {
|
||||
case c.made && o.DryRun:
|
||||
say(fmt.Sprintf(" %-17s would be made and kept at %s (0600)", c.what, c.path))
|
||||
case c.made:
|
||||
say(fmt.Sprintf(" %-17s made, kept at %s (0600)", c.what, c.path))
|
||||
default:
|
||||
say(fmt.Sprintf(" %-17s already at %s — kept", c.what, c.path))
|
||||
}
|
||||
}
|
||||
say(fmt.Sprintf(" credentials the template's bootstrap and guest are gone: %d store and %d broker "+
|
||||
"connection(s) rewritten, the store reads its password from a file, the broker's admin is changed once it answers",
|
||||
root.StoreURLs, root.BrokerURLs))
|
||||
if rewritten.Renamed {
|
||||
say(fmt.Sprintf(" control plane %s, renamed from %s",
|
||||
rewritten.TempName, rewritten.WasCalled))
|
||||
@@ -509,6 +542,18 @@ func Run(ctx context.Context, o Options, d Deps, say func(string)) (Result, erro
|
||||
return result, failed(StepEnrol, err)
|
||||
}
|
||||
|
||||
// ---- operator — the key the mesh's root secrets are also sealed to, held by a person ------
|
||||
//
|
||||
// Before anything is accepted into the mesh: the store's and broker's credentials go in during
|
||||
// the control-plane step, and they must be sealed to this key as well as to the node, or they
|
||||
// are as unrecoverable as the constants they replaced (novox/hq ADR 0085, amended).
|
||||
say("operator — a key the mesh seals its root secrets to, held by a person and never by the mesh")
|
||||
operator, err := MakeOperatorKey(ctx, o, temporary, say)
|
||||
result.OperatorKey, result.OperatorKeyMade = operator.Path, operator.Made
|
||||
if err != nil {
|
||||
return result, failed(StepOperator, err)
|
||||
}
|
||||
|
||||
// ---- 7. registry ----------------------------------------------------------------------
|
||||
say("registry — somewhere for this mesh to keep its own images")
|
||||
registry, err := InstallRegistry(ctx, o, d, temporary, say)
|
||||
@@ -598,6 +643,20 @@ func Run(ctx context.Context, o Options, d Deps, say func(string)) (Result, erro
|
||||
return result, failed(StepStore, err)
|
||||
}
|
||||
|
||||
// ---- 14b. broker ----------------------------------------------------------------------
|
||||
say("broker — the foundation's broker, adopted as the lavinmq module: one bus, not two")
|
||||
if err := InstallBroker(ctx, o, permanentControl, rewritten.Declaration, say); err != nil {
|
||||
return result, failed(StepBroker, err)
|
||||
}
|
||||
|
||||
// ---- 14c. vault -----------------------------------------------------------------------
|
||||
// A foundation module (novox/hq ADR 0085, amended): it keeps every operator-sealed secret on
|
||||
// its own disk, outside the store, from the first push that carries one.
|
||||
say("vault — the mesh's secrets get an owner, and their operator-sealed copies a place to live")
|
||||
if err := InstallVault(ctx, o, permanentControl, say); err != nil {
|
||||
return result, failed(StepVault, err)
|
||||
}
|
||||
|
||||
// ---- 15. catalogue --------------------------------------------------------------------
|
||||
say("catalogue — the module graph: what is held, what a change reaches, what to rebuild")
|
||||
if err := InstallFromCatalogue(ctx, o, permanentControl, "mesh-catalog", say); err != nil {
|
||||
@@ -622,6 +681,14 @@ func Run(ctx context.Context, o Options, d Deps, say func(string)) (Result, erro
|
||||
return result, failed(StepExtras, err)
|
||||
}
|
||||
|
||||
// ---- export — what the operator keeps beside the key ---------------------------------
|
||||
say("export — every root secret, sealed to the operator key, written beside it")
|
||||
exported, err := ExportRootSecrets(ctx, o, permanentControl, say)
|
||||
result.RootExport = exported
|
||||
if err != nil {
|
||||
return result, failed(StepExtras, err)
|
||||
}
|
||||
|
||||
say("\nthis machine is a mesh of one node: it builds its own software, holds its graph, " +
|
||||
"sits on its private network, and filters what modules declared.")
|
||||
say("what remains is somebody else's: adding nodes, and assigning what they should run.")
|
||||
|
||||
Reference in New Issue
Block a user