Files
mesh-controller/internal/broker/vault_calls_live_test.go
T

106 lines
4.4 KiB
Go

package broker
import (
"strings"
"testing"
)
// vaultRecords is a mesh of two machines: anchor, a desk whose runtime carries the desk's prompt (rofi holding
// node-launcher) beside an issuing provider (plex) and a module with a tool of its own; and novox, where the vault
// runs in a runtime of its own on its own account (ADR 0259 §8's runs-as).
func vaultRecords() Records {
launcher := Seat{Name: "node-launcher", Scope: "node", Serves: []string{"menu", "secret"}}
vault := Seat{Name: VaultSeat, Scope: "mesh", Serves: []string{"get", "accept", "secret-ask", "issued", "rotate"}}
return Records{Nodes: []string{"anchor", "novox"}, Assigned: map[string][]Declared{
"anchor": {{Module: RuntimeModule}, {Module: "rofi", Holds: []Seat{launcher}, NoAccount: true},
{Module: "plex", Serves: []string{"plex_issued_credential", "plex_status"},
Issued: []string{"plex_issued_credential"}, NoAccount: true},
{Module: "other", Serves: []string{"tool"}, NoAccount: true}},
"novox": {{Module: RuntimeModule}, {Module: "mesh-vault", Holds: []Seat{vault}, RunsAs: "mesh-vault"}},
}}
}
// The vault's holder may ask the desk's prompt and each issuing tool in its own name, and nothing else outside its
// seat; no other module and no runtime is granted it (issue 723).
func TestTheVaultAsksTheDeskAndTheIssuingToolsInItsOwnNameAlone(t *testing.T) {
users, err := Users(vaultRecords())
if err != nil {
t.Fatal(err)
}
perms := map[string]Permissions{}
for _, u := range users {
p, err := PermissionsFor(u)
if err != nil {
t.Fatal(err)
}
perms[u.Username()] = p
}
vault, ok := perms["novox.mesh-vault"]
if !ok {
t.Fatal("the vault has no account of its own")
}
token := CallerToken("novox.mesh-vault")
for _, s := range []string{
"mesh.seat.node-launcher.call.secret.anchor." + token,
"mesh.mod.plex.call.plex_issued_credential.anchor." + token,
} {
if !MayPublish(vault, s) {
t.Errorf("the vault may not ask %s", s)
}
}
for _, s := range []string{
"mesh.seat.node-launcher.tool.secret.anchor",
"mesh.seat.node-launcher.call.secret.anchor.controller",
"mesh.seat.node-launcher.call.menu.anchor." + token,
"mesh.mod.rofi.call.node-launcher.secret.anchor." + token,
"mesh.mod.plex.call.plex_status.anchor." + token,
"mesh.mod.plex.tool.plex_issued_credential.anchor",
"mesh.mod.other.call.tool.anchor." + token,
"mesh.mod.other.tool.tool.anchor",
"mesh.seat.mesh-controller.call.status." + token,
} {
if MayPublish(vault, s) {
t.Errorf("the vault may publish %s", s)
}
}
// Outside its own namespace and its own seat, the vault publishes nothing but those two calls, its inbox's
// answers and the stream API's reads of what it keeps.
for _, s := range vault.Publish {
switch {
case strings.HasPrefix(s, "mesh.mod.mesh-vault."), strings.HasPrefix(s, "mesh.seat."+VaultSeat+"."),
s == "mesh.seat.node-launcher.call.secret.*."+token,
s == "mesh.mod.plex.call.plex_issued_credential.*."+token,
strings.HasPrefix(s, "$JS."), strings.HasPrefix(s, "$KV."), strings.HasPrefix(s, "_INBOX."),
strings.HasPrefix(s, "mesh.discover."), strings.HasPrefix(s, "$SRV."):
default:
t.Errorf("the vault is granted %s, outside its seat", s)
}
}
// Nobody else is granted the vault's calls; the controller keeps today's path until R1 (issue 682).
for name, p := range perms {
if name == "novox.mesh-vault" {
continue
}
for _, s := range []string{"mesh.seat.node-launcher.call.secret.anchor." + token,
"mesh.mod.plex.call.plex_issued_credential.anchor." + token} {
if MayPublish(p, s) {
t.Errorf("%s may call in the vault's name: %s", name, s)
}
}
}
controller := perms["controller"]
for _, s := range []string{"mesh.seat.node-launcher.tool.secret.anchor",
"mesh.mod.plex.call.plex_issued_credential.anchor.controller"} {
if !MayPublish(controller, s) {
t.Errorf("the controller lost today's path %s before R1", s)
}
}
if MayPublish(perms["anchor.node-tools"], "mesh.seat.node-launcher.call.secret.anchor."+CallerToken("anchor.node-tools")) {
t.Error("a machine's runtime may ask the desk's prompt")
}
}
// **On a real server, as composed** (issue 723): the vault's account asks the desk's prompt and an issuing tool
// and is answered, naming itself; the server refuses it any other call; and the controller is still answered on
// today's path. That only sealed values cross is the vault's test (mesh-catalog, mesh-vault intake_test.go).