The operator's public keys reach the node as the file operator-keys, fed by the node-engine's setting operator-signers (ADR 0539 clause 3)
This commit is contained in:
+14
@@ -14,6 +14,13 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"operator-signers": {
|
||||
"type": "string",
|
||||
"description": "The operator's public keys, ed25519 in base64, one a line: the node applies a composition made by hand only when one of these signed it (ADR 0539 clause 3). Public keys, no secret. Empty trusts no operator key.",
|
||||
"default": ""
|
||||
}
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"id": "launcher",
|
||||
@@ -27,6 +34,13 @@
|
||||
"type": "archive",
|
||||
"artifact": "host-arch",
|
||||
"path": "/usr/lib/nox-mesh-host/versions/${version}"
|
||||
},
|
||||
{
|
||||
"id": "operator-keys",
|
||||
"type": "file",
|
||||
"path": "/var/lib/mesh-host/operator-keys",
|
||||
"mode": "0644",
|
||||
"content": "${config:operator-signers}\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package packaging_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
)
|
||||
|
||||
// The operator's public keys reach every node as a file beside the state file, fed by a setting of the node-engine
|
||||
// (novox/hq ADR 0539 clauses 3 and 11): the node agent reads it, and a composition made by hand is applied only when one
|
||||
// of these keys signed it. The setting may be empty, and then no operator key is trusted.
|
||||
func TestTheManifestDeclaresTheOperatorKeysFileFedByASetting(t *testing.T) {
|
||||
raw, err := os.ReadFile("../module.json")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := catalogue.ParseManifest(raw); err != nil {
|
||||
t.Fatalf("the manifest no longer parses: %v", err)
|
||||
}
|
||||
var m struct {
|
||||
Config map[string]struct {
|
||||
Type string `json:"type"`
|
||||
Default any `json:"default"`
|
||||
} `json:"config"`
|
||||
Resources []struct {
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Path string `json:"path"`
|
||||
Mode string `json:"mode"`
|
||||
Content string `json:"content"`
|
||||
} `json:"resources"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &m); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
setting, ok := m.Config["operator-signers"]
|
||||
if !ok || setting.Type != "string" || setting.Default != "" {
|
||||
t.Fatalf("the setting operator-signers is %+v: a string that may be empty", setting)
|
||||
}
|
||||
for _, r := range m.Resources {
|
||||
if r.ID != "operator-keys" {
|
||||
continue
|
||||
}
|
||||
if r.Type != "file" || r.Path != "/var/lib/mesh-host/operator-keys" || r.Mode != "0644" ||
|
||||
!strings.Contains(r.Content, "${config:operator-signers}") {
|
||||
t.Fatalf("the file is %+v: it is declared beside the state file, 0644, its content the setting", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
t.Fatal("module.json declares no operator-keys file")
|
||||
}
|
||||
Reference in New Issue
Block a user