The node agent finds a drifted own secret's running file by its id as the node runs it, its module's name first (issue 1126, cause C4; review round 2)
Pins mesh-sdk 3028c7e (delivery.OwnNeedName). The fixtures carry the id shape captured from novox's shadow answer.
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.20261028084903-1062b33d32c5
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261028090029-3028c7ec4ed2
|
||||||
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,5 @@
|
|||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261028084903-1062b33d32c5 h1:FRNW0kjmm2SYVbEAeG9IsMWALE/qRKt8IMKNnMn2p90=
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261028090029-3028c7ec4ed2 h1:eSwObLdxs3jxPrlcwdaMo9hzIDTUz2ogWw8cjX8To7I=
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261028084903-1062b33d32c5/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261028090029-3028c7ec4ed2/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=
|
||||||
|
|||||||
@@ -223,13 +223,17 @@ func (r *Resync) running(ctx context.Context, o delivery.OwnValueDiffers) (strin
|
|||||||
return "", fmt.Sprintf("what runs (%s, %s) is not yet the composition its want names (%s)", have.Composed,
|
return "", fmt.Sprintf("what runs (%s, %s) is not yet the composition its want names (%s)", have.Composed,
|
||||||
have.Phase, want.Composed)
|
have.Phase, want.Composed)
|
||||||
}
|
}
|
||||||
id := catalogue.NeedID(o.Name)
|
// On a node the resource's id carries its module's name (`only-office.needs-jwt`); delivery.OwnNeedName reads it.
|
||||||
|
id := o.Module + "." + catalogue.NeedID(o.Name)
|
||||||
for _, res := range comp.Resources {
|
for _, res := range comp.Resources {
|
||||||
var body struct {
|
var body struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Sealed any `json:"sealed"`
|
Sealed any `json:"sealed"`
|
||||||
}
|
}
|
||||||
if json.Unmarshal(res, &body) != nil || body.ID != id {
|
if json.Unmarshal(res, &body) != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if name, own := delivery.OwnNeedName(o.Module, body.ID); !own || name != o.Name {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if s, ok := body.Sealed.(string); ok && s != "" {
|
if s, ok := body.Sealed.(string); ok && s != "" {
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ func TestTheNodeHandsTheVaultWhatRunsOfADriftedOwnSecret(t *testing.T) {
|
|||||||
fp := "src2:" + strings.Repeat("b", 64)
|
fp := "src2:" + strings.Repeat("b", 64)
|
||||||
sum := sha256.Sum256([]byte(running))
|
sum := sha256.Sum256([]byte(running))
|
||||||
answers := map[string]delivery.CandidateAnswer{"g": {Head: "h", Verdict: delivery.CandidateDiffers,
|
answers := map[string]delivery.CandidateAnswer{"g": {Head: "h", Verdict: delivery.CandidateDiffers,
|
||||||
Differs: []delivery.ModuleDiffers{{Module: "onlyoffice", Why: "the resource differs", Bodies: []delivery.ResourceBodies{
|
Differs: []delivery.ModuleDiffers{{Module: "only-office", Why: "the resource differs", Bodies: []delivery.ResourceBodies{
|
||||||
{ID: "needs-jwt", Composed: `{"sealed":"` + delivery.MaskedAnotherValue + `"}`, Running: `{"sealed":"` + delivery.MaskedAnotherValue + `"}`},
|
{ID: "only-office.needs-jwt", Composed: `{"sealed":"` + delivery.MaskedAnotherValue + `"}`, Running: `{"sealed":"` + delivery.MaskedAnotherValue + `"}`},
|
||||||
{ID: "needs-salt", Composed: `{"sealed":"<masked: another seal of the same value>"}`}}}}}}
|
{ID: "only-office.needs-salt", Composed: `{"sealed":"<masked: another seal of the same value>"}`}}}}}}
|
||||||
for name, row := range map[string]struct {
|
for name, row := range map[string]struct {
|
||||||
composes string
|
composes string
|
||||||
runs string // the have's composition digest
|
runs string // the have's composition digest
|
||||||
@@ -43,14 +43,16 @@ func TestTheNodeHandsTheVaultWhatRunsOfADriftedOwnSecret(t *testing.T) {
|
|||||||
have, _ := delivery.EncodeHave(delivery.Have{FP: fp, Composed: row.runs, Phase: delivery.PhaseRunning, Health: delivery.HealthOK})
|
have, _ := delivery.EncodeHave(delivery.Have{FP: fp, Composed: row.runs, Phase: delivery.PhaseRunning, Health: delivery.HealthOK})
|
||||||
r := New(Env{Node: "novox", Composes: func() string { return row.composes },
|
r := New(Env{Node: "novox", Composes: func() string { return row.composes },
|
||||||
Running: func() []delivery.Composed {
|
Running: func() []delivery.Composed {
|
||||||
return []delivery.Composed{{Node: "novox", Module: "onlyoffice", FP: fp, Resources: []json.RawMessage{
|
return []delivery.Composed{{Node: "novox", Module: "only-office", FP: fp, Resources: []json.RawMessage{
|
||||||
json.RawMessage(`{"id":"needs-jwt","type":"file","path":"/etc/jwt","sealed":"box-of-the-running-value"}`)}}}
|
// As novox runs it (its shadow answer, 2026-10-28): the id carries the module's name.
|
||||||
|
json.RawMessage(`{"id":"only-office.needs-jwt","module":"only-office","type":"file",` +
|
||||||
|
`"path":"/var/lib/only-office/jwt.secret","sealed":"box-of-the-running-value"}`)}}}
|
||||||
},
|
},
|
||||||
Get: func(_ context.Context, bucket, key string) ([]byte, error) {
|
Get: func(_ context.Context, bucket, key string) ([]byte, error) {
|
||||||
switch {
|
switch {
|
||||||
case bucket == delivery.AssignerWantsBucket && key == "want.novox.onlyoffice":
|
case bucket == delivery.AssignerWantsBucket && key == "want.novox.only-office":
|
||||||
return want, nil
|
return want, nil
|
||||||
case bucket == delivery.HaveBucket && key == "novox.onlyoffice":
|
case bucket == delivery.HaveBucket && key == "novox.only-office":
|
||||||
return have, nil
|
return have, nil
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@@ -71,15 +73,15 @@ func TestTheNodeHandsTheVaultWhatRunsOfADriftedOwnSecret(t *testing.T) {
|
|||||||
return nil, errors.New(row.refuse)
|
return nil, errors.New(row.refuse)
|
||||||
}
|
}
|
||||||
if args["call"] == nil {
|
if args["call"] == nil {
|
||||||
if args["module"] != "onlyoffice" || args["name"] != "jwt" || args["node"] != nil {
|
if args["module"] != "only-office" || args["name"] != "jwt" || args["node"] != nil {
|
||||||
t.Errorf("%s: the first step names %v", name, args)
|
t.Errorf("%s: the first step names %v", name, args)
|
||||||
}
|
}
|
||||||
return json.RawMessage(`{"call":"c1","seal_to":"key","secret":"own/novox/onlyoffice/jwt"}`), nil
|
return json.RawMessage(`{"call":"c1","seal_to":"key","secret":"own/novox/only-office/jwt"}`), nil
|
||||||
}
|
}
|
||||||
if args["sealed"] != "key("+running+")" {
|
if args["sealed"] != "key("+running+")" {
|
||||||
t.Errorf("%s: handed %v, not what runs sealed to the call's key", name, args["sealed"])
|
t.Errorf("%s: handed %v, not what runs sealed to the call's key", name, args["sealed"])
|
||||||
}
|
}
|
||||||
return json.RawMessage(`{"secret":"own/novox/onlyoffice/jwt","from_generation":1,"to_generation":2,` +
|
return json.RawMessage(`{"secret":"own/novox/only-office/jwt","from_generation":1,"to_generation":2,` +
|
||||||
`"fingerprint":"sha256:` + hex.EncodeToString(sum[:]) + `"}`), nil
|
`"fingerprint":"sha256:` + hex.EncodeToString(sum[:]) + `"}`), nil
|
||||||
},
|
},
|
||||||
Say: func(s string) { said = append(said, s) }})
|
Say: func(s string) { said = append(said, s) }})
|
||||||
|
|||||||
Reference in New Issue
Block a user