Files
mesh-host/internal/compose/resolution/grant_secret_owner_test.go
T
jschoubben d68e241724 Take the catalogue's composition rules into the node-engine
ADR 0593 §7: the composer with its refusals leaves mesh-sdk, so mesh-sdk
carries no composition rule. The catalogue functions only the
node-engine's composition reaches (Resolve, Resolution's Compose,
Declaration, DataItems, LeftOut, Rules and the rest, the settings,
placeholder and template refusals, the rendering helpers) are copied
with their tests into internal/compose/resolution; a method of a
mesh-sdk shape becomes a function taking it first. The composition
calls its own copies, and the captured catalogue its tests read lives
here now, shared by mesh-compose's tests.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 19:15:55 +01:00

106 lines
3.6 KiB
Go

package resolution
import (
"strings"
"testing"
mcat "git.novox.be/novox/mesh-sdk/go/catalogue"
)
// aProviderWithABundle is a provider whose code is a bundle the node's runtime runs — the shape
// every TypeScript provisioner has since ADR 0198.
func aProviderWithABundle() mcat.Manifest {
return mcat.Manifest{
Module: "mongodb", Version: "1",
Provides: mcat.FromAnywhere("mongodb-database"),
Receives: map[string]string{"mongodb-database": "/var/lib/mongodb/grants/mesh.json"},
Grants: map[string]string{"mongodb-database": "/var/lib/mongodb/grants"},
Bundles: []mcat.Bundle{{Name: "code", Language: "typescript"}},
Resources: []map[string]any{{
"id": "server", "type": "container", "name": "mongodb-server",
"image": "mongo@sha256:" + strings.Repeat("a", 64),
}},
}
}
func TestAGrantSecretIsOwnedByTheAccountThatProvisions(t *testing.T) {
r, err := Resolve(shelf(aProviderWithABundle()), []string{"mongodb"}, reachable(), mcat.World{})
if err != nil {
t.Fatal(err)
}
r.Account = "operator"
out, err := Declaration(r, mcat.Rendering{Grants: []mcat.Grant{{
Provision: "mongodb-database", Consumer: "workstation", From: "photos", Slug: "photos",
Values: map[string]any{}, Sealed: "c2VhbGVk",
}}})
if err != nil {
t.Fatal(err)
}
var secret map[string]any
for _, res := range out {
if res["type"] == "file" && strings.HasSuffix(fmtPath(res), ".secret") {
secret = res
}
}
if secret == nil {
t.Fatalf("no grant secret was composed at all: %v", out)
}
if got := secret["owner"]; got != "operator" {
t.Fatalf("the grant secret at %v belongs to %v; the provisioner runs as %q and a "+
"root-owned 0600 file is one it cannot read — which is silent, because the harness "+
"calls it \"not readable yet\"", fmtPath(secret), got, "operator")
}
// A grant whose offer presents no credential (form none, issue 1126) carries nothing sealed: no secret file is
// written for it, as none is for a need with no credential, and the provider still learns who asked.
out, err = Declaration(r, mcat.Rendering{Grants: []mcat.Grant{{
Provision: "mongodb-database", Consumer: "workstation", From: "photos", Slug: "photos", Values: map[string]any{}}}})
if err != nil {
t.Fatal(err)
}
asked := false
for _, res := range out {
if res["type"] == "file" && strings.HasSuffix(fmtPath(res), ".secret") {
t.Errorf("a grant with no credential writes %v", res)
}
asked = asked || fmtPath(res) == "/var/lib/mongodb/grants/mesh.json"
}
if !asked {
t.Errorf("the provider no longer learns who asked: %v", out)
}
}
// And a provider whose code still runs in a container keeps the owner it declares, so this
// changes nothing for the modules the runtime has not taken.
func TestAContainerProvidersGrantSecretKeepsItsDeclaredOwner(t *testing.T) {
m := aProviderWithABundle()
m.Bundles = nil
m.SecretsOwner = "65534:65534"
r, err := Resolve(shelf(m), []string{"mongodb"}, reachable(), mcat.World{})
if err != nil {
t.Fatal(err)
}
r.Account = "operator"
out, err := Declaration(r, mcat.Rendering{Grants: []mcat.Grant{{
Provision: "mongodb-database", Consumer: "workstation", From: "photos", Slug: "photos",
Values: map[string]any{}, Sealed: "c2VhbGVk",
}}})
if err != nil {
t.Fatal(err)
}
for _, res := range out {
if res["type"] == "file" && strings.HasSuffix(fmtPath(res), ".secret") {
if got := res["owner"]; got != "65534:65534" {
t.Fatalf("a container provider's grant secret belongs to %v, not what it declares", got)
}
return
}
}
t.Fatal("no grant secret was composed")
}
func fmtPath(r map[string]any) string {
p, _ := r["path"].(string)
return p
}