One runtime principal per node carries every assigned module's tools (hq ADR 0175, to-be 38 WP2.1)
Where the node-tools module is assigned, the machine's bus user list gains one principal of kind node-tools in place of that module's own: it may subscribe every carried module's tool namespace and every held seat's verbs on its node, read and follow every membership on its node, call any tool anywhere, answer what it is asked — and consume nothing, because tools are what it runs. Every other module keeps its own principal, so a module still serving tools from its container holds its own credential until it moves. Named exactly as the module it stands for, so `module issue` and `rollout mint` deliver its credential through the path a module's already takes, into node-tools' own `broker` secret. The runtime module's name is one constant in each of the broker and catalogue packages, held to one string by the agreement test, because a rule turns on it.
This commit is contained in:
@@ -371,3 +371,73 @@ func TestAModulePullsItsOwnConsumerAndNoOthers(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The runtime's authority is the union of what the modules it carries would have been granted for
|
||||
// their tools (novox/hq ADR 0175): every carried module's tool namespace, every held seat's verbs
|
||||
// on this node, every module's membership on this node, and a call to anything. Nothing it
|
||||
// consumes, because it reacts to nothing.
|
||||
func TestTheRuntimeServesTheUnionAndConsumesNothing(t *testing.T) {
|
||||
filter := Seat{Name: "node-packet-filter", Scope: "node", Serves: []string{"rules", "reload"}}
|
||||
p := Principal{Kind: KindNodeTools, Node: "anchor", Module: RuntimeModule, Carries: []Declared{
|
||||
{Module: "nftables", Holds: []Seat{filter}, Serves: []string{"firewall_rules"}},
|
||||
{Module: "zsh", Emits: []string{"shell.opened"}, Consumes: []string{"shop.order.placed"}},
|
||||
{Module: RuntimeModule},
|
||||
}}
|
||||
perms, err := PermissionsFor(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, want := range []string{
|
||||
"mesh.mod.nftables.tool.>", "mesh.mod.zsh.tool.>", "mesh.mod." + RuntimeModule + ".tool.>",
|
||||
"mesh.seat.node-packet-filter.tool.rules.anchor", "mesh.seat.node-packet-filter.tool.reload.anchor",
|
||||
"mesh.assignment.anchor.*",
|
||||
"_INBOX.anchor." + RuntimeModule + ".>",
|
||||
} {
|
||||
if !contains(perms.Subscribe, want) {
|
||||
t.Errorf("the runtime may not subscribe %s: %v", want, perms.Subscribe)
|
||||
}
|
||||
}
|
||||
for _, want := range []string{
|
||||
"mesh.mod.*.tool.>", "mesh.seat.*.tool.>",
|
||||
"$JS.API.DIRECT.GET.ASSIGNMENTS.mesh.assignment.anchor.*",
|
||||
"mesh.mod.zsh.event.shell.opened",
|
||||
} {
|
||||
if !contains(perms.Publish, want) {
|
||||
t.Errorf("the runtime may not publish %s: %v", want, perms.Publish)
|
||||
}
|
||||
}
|
||||
// Nothing of what a carried module consumes, and no consumer of its own to ack.
|
||||
for _, s := range perms.Subscribe {
|
||||
if strings.Contains(s, ".event.") || strings.HasPrefix(s, "_DELIVER.") {
|
||||
t.Errorf("the runtime was granted a delivery it has no consumer for: %s", s)
|
||||
}
|
||||
}
|
||||
for _, s := range perms.Publish {
|
||||
if strings.HasPrefix(s, "$JS.ACK.") || strings.Contains(s, "CONSUMER") {
|
||||
t.Errorf("the runtime was granted a consumer's subject and has no consumer: %s", s)
|
||||
}
|
||||
}
|
||||
if !perms.AllowResponses {
|
||||
t.Error("the runtime answers what it is asked, and may not reply")
|
||||
}
|
||||
if _, needed := ConsumerFor(p); needed {
|
||||
t.Error("a consumer would be made for the runtime, which consumes nothing")
|
||||
}
|
||||
// Each subject once: the file is read as the mesh's authority model.
|
||||
seen := map[string]bool{}
|
||||
for _, s := range append(append([]string{}, perms.Subscribe...), perms.Publish...) {
|
||||
if seen[s] {
|
||||
t.Errorf("%s is granted twice", s)
|
||||
}
|
||||
seen[s] = true
|
||||
}
|
||||
}
|
||||
|
||||
func contains(list []string, want string) bool {
|
||||
for _, s := range list {
|
||||
if s == want {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user