A module's trusted list of callers in the SDK, so the vault's secret-ask answers the callers its manifest names as the runtime proved them (issue 774, ADR 0563 §8)
This commit is contained in:
@@ -75,6 +75,21 @@ func TestACallerInTheArgumentsIsNeverTheCaller(t *testing.T) {
|
||||
if got != "shanks.node-tools" {
|
||||
t.Fatalf("with a caller in the arguments the tool read %q, want the runtime's", got)
|
||||
}
|
||||
// A module's trusted list of callers (issue 774, ADR 0563 §8) grants the callers it names as the runtime proved them:
|
||||
// a module on any machine, <machine>.<module> exactly, person.<name> exactly; no wildcard, never one unproven.
|
||||
callers, err := ParseCallers([]byte(`{"callers":["node-tools","ace.claude-code","person.jo","*"]}`))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for caller, want := range map[string]bool{"shanks.node-tools": true, "ace.claude-code": true, "g14.claude-code": false,
|
||||
"person.jo": true, "person.node-tools": false, Unproven: false, "": false, "novox.mesh-vault": false} {
|
||||
if callers.Allows(caller) != want {
|
||||
t.Errorf("%q allowed: %v, want %v", caller, !want, want)
|
||||
}
|
||||
}
|
||||
if _, err := ParseCallers([]byte(`{"callers":["x"],"more":1}`)); err == nil {
|
||||
t.Error("a list with a field it does not know was read")
|
||||
}
|
||||
}
|
||||
|
||||
// A runtime that names no caller — one from before issue 365, or a call on the subject that names none — is
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package stdio
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Callers is a module's trusted list of who may call a verb of its (novox/hq ADR 0459 §2, ADR 0563 §8), as the mesh
|
||||
// writes a list setting into a file the module reads: `{"callers": [...]}`. An entry is a module's name (that module on
|
||||
// any machine), exactly <machine>.<module>, or exactly person.<name>. Each caller is the runtime's proof (CallerOf), never
|
||||
// an argument; nobody beyond the list is granted, a wildcard is no entry, and an unproven caller never matches.
|
||||
type Callers []string
|
||||
|
||||
// ParseCallers reads a callers file: the list under `callers`, and nothing else.
|
||||
func ParseCallers(raw []byte) (Callers, error) {
|
||||
var f struct {
|
||||
Callers Callers `json:"callers"`
|
||||
}
|
||||
dec := json.NewDecoder(bytes.NewReader(raw))
|
||||
dec.DisallowUnknownFields()
|
||||
if err := dec.Decode(&f); err != nil {
|
||||
return nil, fmt.Errorf("the callers setting is not a list of callers: %v", err)
|
||||
}
|
||||
return f.Callers, nil
|
||||
}
|
||||
|
||||
// Allows says whether caller, as the runtime proved it, is one the list names.
|
||||
func (c Callers) Allows(caller string) bool {
|
||||
if caller == "" || caller == Unproven {
|
||||
return false
|
||||
}
|
||||
for _, entry := range c {
|
||||
if entry == "" || strings.ContainsAny(entry, "*> ") {
|
||||
continue
|
||||
}
|
||||
if entry == caller {
|
||||
return true
|
||||
}
|
||||
if !strings.Contains(entry, ".") {
|
||||
if _, module, ok := strings.Cut(caller, "."); ok && module == entry && !strings.HasPrefix(caller, "person.") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user