AM-D4: the real bus delivers no marked call to a runtime denied the marks
A deny composed into the user list must hold on the server itself: the runtime keeps its allow of the module's tools, and neither the tool's subject nor the caller-named subject process.Call sends on first reaches it. Builds: design 46 7 §6 (integration, the grants part's real-bus test) Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -623,3 +623,58 @@ func theToolRunnerHearsEveryEventOnTheBus(t *testing.T) {
|
||||
}
|
||||
hears(ledger, "the restricted stream after its grant value changed")
|
||||
}
|
||||
|
||||
// aRuntimeDeniedTheMarksHearsNoMarkedCall, run by TestTheGrantsPartWhole, defends design 46 approval mark §6 on a real
|
||||
// server (AM-D4): a runtime account composed with the deny, its node's tool runner stating no approval-mark/1, holds
|
||||
// `mesh.mod.<module>.tool.>` and is delivered no call on a marked tool's subject nor on the caller-named subject
|
||||
// process.Call sends on first; a call of an unmarked tool still reaches it.
|
||||
func aRuntimeDeniedTheMarksHearsNoMarkedCall(t *testing.T) {
|
||||
records := buscompose.Records{Nodes: []string{"a"}, Assigned: map[string][]buscompose.Declared{"a": {
|
||||
{Module: "node-tools", ToolRunner: true},
|
||||
{Module: "shell", Serves: []string{"execute", "read"}, Marked: []string{"execute"}},
|
||||
{Module: "asker", Invokes: []string{"shell.execute", "shell.read"}},
|
||||
}}, Readings: map[string]buscompose.RunnerReading{"a": {Capabilities: []string{"bus-state-calls"}, Fingerprint: "sha256:runner"}},
|
||||
Running: map[string]string{"a.node-tools": "sha256:runner"}}
|
||||
bus := startComposedBus(t, records)
|
||||
runner, _ := bus.dial("a.node-tools")
|
||||
heard := make(chan *nats.Msg, 16)
|
||||
for _, s := range []string{"mesh.mod.shell.tool.>", "mesh.mod.shell.call.>"} {
|
||||
if _, err := runner.ChanSubscribe(s, heard); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err := runner.Flush(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
asker, askerRefused := bus.dial("a.asker")
|
||||
// The caller-named subject is process.Call's first: mesh.mod.<module>.call.<tool>.<caller's token>.
|
||||
for _, subject := range []string{"mesh.mod.shell.tool.execute", "mesh.mod.shell.call.execute.asker~a", "mesh.mod.shell.tool.read"} {
|
||||
if err := asker.Publish(subject, []byte(`{}`)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err := asker.Flush(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
select {
|
||||
case e := <-askerRefused:
|
||||
t.Fatalf("the asker may not call: %s", e)
|
||||
default:
|
||||
}
|
||||
select {
|
||||
case m := <-heard:
|
||||
if m.Subject != "mesh.mod.shell.tool.read" {
|
||||
t.Errorf("the runtime denied the marks was delivered %s", m.Subject)
|
||||
}
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("the unmarked call did not reach the runtime")
|
||||
}
|
||||
if err := runner.Flush(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
select {
|
||||
case m := <-heard:
|
||||
t.Errorf("the runtime denied the marks was delivered %s", m.Subject)
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
@@ -628,6 +628,7 @@ func TestTheGrantsPartWhole(t *testing.T) {
|
||||
// And what the part composes holds on a server that loads it (one integration test per module, the test budget).
|
||||
t.Run("the composed grants hold on a server that loads them", theBusNodeFollowsTheSealedListUnderTheComposedGrants)
|
||||
t.Run("the tool runner hears every event on a server that loads its grants", theToolRunnerHearsEveryEventOnTheBus)
|
||||
t.Run("a runtime denied the marks is delivered no call on a marked subject", aRuntimeDeniedTheMarksHearsNoMarkedCall)
|
||||
}
|
||||
|
||||
// lockedLog is the part's log, read by the test while the part writes it.
|
||||
|
||||
Reference in New Issue
Block a user