The node-engine carries a module's own secrets sealed by the vault when its manifest says they are the core's credentials, pinned at mesh-sdk 4f141ff (issue 774, the operator 2026-11-03)
This commit is contained in:
@@ -3,7 +3,7 @@ module github.com/novox/mesh-host
|
|||||||
go 1.26.0
|
go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102191058-f02f142af128
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103103643-4f141ff08892
|
||||||
github.com/nats-io/nats-server/v2 v2.11.17
|
github.com/nats-io/nats-server/v2 v2.11.17
|
||||||
github.com/nats-io/nats.go v1.54.0
|
github.com/nats-io/nats.go v1.54.0
|
||||||
golang.org/x/crypto v0.57.0
|
golang.org/x/crypto v0.57.0
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102191058-f02f142af128 h1:aI1DhZAuqVBXbybSqhLNOGX5rUOrn9T0cHNCDUQF7IQ=
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102191058-f02f142af128 h1:aI1DhZAuqVBXbybSqhLNOGX5rUOrn9T0cHNCDUQF7IQ=
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102191058-f02f142af128/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261102191058-f02f142af128/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
||||||
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103103643-4f141ff08892 h1:XWorhIHDVECRCYzGbkaexEpJ7v03B9LrZ8IVy7vkUKs=
|
||||||
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261103103643-4f141ff08892/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
||||||
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ func TestCompositionsAreTheDeclarationSplitByModule(t *testing.T) {
|
|||||||
// 1943/AC1: the upgrade policies and sources a composition's value may name are the catalogue's own words.
|
// 1943/AC1: the upgrade policies and sources a composition's value may name are the catalogue's own words.
|
||||||
func TestTheComposedPoliciesAreTheCatalogues(t *testing.T) {
|
func TestTheComposedPoliciesAreTheCatalogues(t *testing.T) {
|
||||||
for _, p := range []string{catalogue.PolicyRoll, catalogue.PolicyTogether, catalogue.PolicyRecord} {
|
for _, p := range []string{catalogue.PolicyRoll, catalogue.PolicyTogether, catalogue.PolicyRecord} {
|
||||||
for _, from := range []string{catalogue.FromPerson, catalogue.FromModule, catalogue.FromBus, catalogue.FromData, catalogue.FromDefault} {
|
for _, from := range []string{catalogue.FromPerson, catalogue.FromModule, "the bus", catalogue.FromData, catalogue.FromDefault} { // "the bus": an older reader's word, still read
|
||||||
v := delivery.ComposedDigest{Digest: "sha256:" + strings.Repeat("a", 64), Judgement: delivery.JudgedNeither, Policy: p, PolicyFrom: from}
|
v := delivery.ComposedDigest{Digest: "sha256:" + strings.Repeat("a", 64), Judgement: delivery.JudgedNeither, Policy: p, PolicyFrom: from}
|
||||||
if _, err := delivery.EncodeComposedDigest(v); err != nil {
|
if _, err := delivery.EncodeComposedDigest(v); err != nil {
|
||||||
t.Errorf("%s from %s: %v", p, from, err)
|
t.Errorf("%s from %s: %v", p, from, err)
|
||||||
|
|||||||
@@ -386,13 +386,13 @@ type CoreBoxWanted struct {
|
|||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
// coreModulesOf is every module of the plan on the core's list whose own secrets this machine's declaration carries, with their
|
// coreModulesOf is every module of the plan whose manifest says its own secrets are the core's credentials, 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
|
// 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.
|
// outside the mesh is never the vault's to seal here.
|
||||||
func coreModulesOf(modules []catalogue.Manifest, handed func(catalogue.Manifest) bool) map[string][]string {
|
func coreModulesOf(modules []catalogue.Manifest, handed func(catalogue.Manifest) bool) map[string][]string {
|
||||||
out := map[string][]string{}
|
out := map[string][]string{}
|
||||||
for _, m := range modules {
|
for _, m := range modules {
|
||||||
if !resolution.CarriesVaultSealed(m.Module) || (handed != nil && handed(m)) {
|
if !resolution.CarriesVaultSealed(m) || (handed != nil && handed(m)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var names []string
|
var names []string
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ func aValidKey(t *testing.T, name string) string { return keyOf(t, name) }
|
|||||||
func TestACoreBoxTheInputHoldsNoneOfIsReturnedToKeepAndNothingIsWritten(t *testing.T) {
|
func TestACoreBoxTheInputHoldsNoneOfIsReturnedToKeepAndNothingIsWritten(t *testing.T) {
|
||||||
mk := func() Input {
|
mk := func() Input {
|
||||||
in := aMesh(t)
|
in := aMesh(t)
|
||||||
in.Catalogue["nats"] = catalogue.Manifest{Module: "nats", Version: "1",
|
in.Catalogue["nats"] = catalogue.Manifest{Module: "nats", Version: "1", CoreCredentials: true,
|
||||||
OwnSecrets: catalogue.OwnSecrets{"broker": {Path: "/var/lib/mesh/nats/broker", Taken: catalogue.TakenAtStart}}}
|
OwnSecrets: catalogue.OwnSecrets{"broker": {Path: "/var/lib/mesh/nats/broker", Taken: catalogue.TakenAtStart}}}
|
||||||
laptop := nodeOf(t, &in, "laptop")
|
laptop := nodeOf(t, &in, "laptop")
|
||||||
laptop.Assigned = append(laptop.Assigned, "nats")
|
laptop.Assigned = append(laptop.Assigned, "nats")
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ func TestWhatASendWouldMakeIsNamedAsForeseenAndNeverInvented(t *testing.T) {
|
|||||||
in.Issued[0].ForProvider = ""
|
in.Issued[0].ForProvider = ""
|
||||||
in.Catalogue["assistant"] = anAssistant()
|
in.Catalogue["assistant"] = anAssistant()
|
||||||
in.Catalogue["web"] = aWebModule()
|
in.Catalogue["web"] = aWebModule()
|
||||||
in.Catalogue["nats"] = catalogue.Manifest{Module: "nats", Version: "1",
|
in.Catalogue["nats"] = catalogue.Manifest{Module: "nats", Version: "1", CoreCredentials: true,
|
||||||
OwnSecrets: catalogue.OwnSecrets{"broker": {Path: "/var/lib/mesh/nats/broker", Taken: catalogue.TakenAtStart}}}
|
OwnSecrets: catalogue.OwnSecrets{"broker": {Path: "/var/lib/mesh/nats/broker", Taken: catalogue.TakenAtStart}}}
|
||||||
anchor := nodeOf(t, &in, "anchor")
|
anchor := nodeOf(t, &in, "anchor")
|
||||||
anchor.Assigned = append(anchor.Assigned, "assistant", "web", "nats")
|
anchor.Assigned = append(anchor.Assigned, "assistant", "web", "nats")
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ package resolution
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"slices"
|
|
||||||
|
|
||||||
mcat "git.novox.be/novox/mesh-sdk/go/catalogue"
|
mcat "git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CarriesVaultSealed says whether module's own secrets are the core's credentials.
|
// CarriesVaultSealed says whether a module's own secrets are the core's credentials, as its manifest says
|
||||||
func CarriesVaultSealed(module string) bool {
|
// (core-credentials): no list of modules is kept here.
|
||||||
return slices.Contains(mcat.CoreCredentialModules, module)
|
func CarriesVaultSealed(m mcat.Manifest) bool {
|
||||||
|
return mcat.CarriesCoreCredentials(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// vaultSealedOf is the vault's box for one of module's own secrets, if the rendering was given one.
|
// vaultSealedOf is the vault's box for one of module's own secrets, if the rendering was given one.
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
package resolution
|
package resolution
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
mcat "git.novox.be/novox/mesh-sdk/go/catalogue"
|
mcat "git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// The core's own credentials are what a module's manifest says (core-credentials, issue 774): no module is on a list.
|
||||||
func TestTheCoresOwnCredentialsAreTheBusTheProvisionerAndItsClient(t *testing.T) {
|
func TestTheCoresOwnCredentialsAreTheBusTheProvisionerAndItsClient(t *testing.T) {
|
||||||
if want := []string{"mesh-provisioner", "mesh-provisioner-client", "nats"}; !reflect.DeepEqual(mcat.CoreCredentialModules, want) {
|
for raw, core := range map[string]bool{
|
||||||
t.Fatalf("the core's modules are %v, want %v (mesh-vault's CoreModules is the same list)", mcat.CoreCredentialModules, want)
|
`{"module":"nats","version":"1","core-credentials":true}`: true,
|
||||||
}
|
`{"module":"nats","version":"1"}`: false,
|
||||||
for _, m := range []string{"nats", "mesh-provisioner", "mesh-provisioner-client"} {
|
`{"module":"postgres","version":"1"}`: false,
|
||||||
if !CarriesVaultSealed(m) {
|
} {
|
||||||
t.Errorf("%s is not on the list", m)
|
m, err := mcat.Decode([]byte(raw))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
if CarriesVaultSealed(m) != core {
|
||||||
for _, m := range []string{"postgres", "mesh-vault", "mesh-controller", ""} {
|
t.Errorf("%s: carries the core's credentials %v", raw, !core)
|
||||||
if CarriesVaultSealed(m) {
|
|
||||||
t.Errorf("%s is on the list", m)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user