A requirement answered on this machine is still a requirement

novox/hq 04-ISSUES/021. Two modules where one provided what the other
required, on one node, resolved cleanly with zero needs: no credential
was made, the consumer's secret file was never written, and whatever
read it would fail somewhere else entirely. Nothing was refused and
nothing was reported.

The world a node resolves against is every OTHER node, so a provider on
the same machine never became a Needed, and the credential loop walks
Needs. Every step reasonable, the sum a silent gap.

It survived because everything proven until now was cross-machine —
the interesting case for a mesh and the rare one in practice. The first
module to want a database on its own machine was the first real one.

The assumption underneath was that a local consumer needs no credential,
which holds for a process reaching a unix socket where the system can
vouch for the caller. It does not hold for containers, which is how
nearly everything here runs: the consumer reaches the provider over TCP
from its own container and the database asks for a password exactly as
it would from another machine. **The machine stops being a trust
boundary once both ends are containers.**

A brokered provision answered here is now a need naming this node, and
carries what the provider serves — which a local provider never
contributes through the world. A name nothing grants is unchanged: a
shell answered here is answered, and nothing more is owed. Both
directions tested, both injections bite.
This commit is contained in:
2026-09-01 02:15:26 +02:00
parent d0511ee3fe
commit df62bb57e5
2 changed files with 86 additions and 0 deletions
+56
View File
@@ -335,3 +335,59 @@ func mustDeclare(t *testing.T, r Resolution) []map[string]any {
}
return out
}
// A requirement answered on the same machine is still a requirement (novox/hq 04-ISSUES/021).
//
// **The machine stops being a trust boundary once both ends are containers.** A consumer reaches
// its provider over TCP from its own container, and the database asks for a password exactly as it
// would from another machine. Before this, two such modules resolved cleanly with zero needs: no
// credential was made, the consumer's secret file was never written, and whatever read it failed
// somewhere else entirely.
//
// It went unnoticed because everything proven until then was cross-machine, which is the
// interesting case for a mesh and the rare one in practice.
func TestSomethingAnsweredOnThisMachineIsStillANeed(t *testing.T) {
provider := Manifest{
Module: "postgres", Version: "1",
Provides: FromAnywhere("postgres-database"),
Serves: map[string]map[string]any{"postgres-database": {"port": 5432}},
Grants: map[string]string{"postgres-database": "/var/lib/postgres/grants"},
}
consumer := Manifest{
Module: "keycloak", Version: "1",
Requires: []string{"postgres-database"},
Secrets: map[string]string{"postgres-database": "/var/lib/keycloak/database.env"},
}
got, err := Resolve(shelf(provider, consumer), []string{"postgres", "keycloak"},
Node{Name: "anchor", At: "10.0.0.1", Capabilities: map[string]bool{}}, World{})
if err != nil {
t.Fatal(err)
}
if len(got.Needs) != 1 {
t.Fatalf("%d need(s); a consumer of a brokered provision needs a credential wherever "+
"the provider is", len(got.Needs))
}
if got.Needs[0].From != "anchor" {
t.Errorf("the need names %q as the provider, and it is this machine", got.Needs[0].From)
}
// And it carries what the provider says a consumer must know, which a local provider never
// contributes through the world.
if got.Needs[0].Serves["port"] != 5432 {
t.Errorf("the need carries %v, and the provider serves port 5432", got.Needs[0].Serves)
}
}
// A name nothing grants is unchanged: answered here means answered, and nothing more is owed.
func TestSomethingOrdinaryAnsweredHereNeedsNothing(t *testing.T) {
got, err := Resolve(shelf(
mod("zsh", []string{"shell"}, nil, nil),
mod("editor-user", nil, []string{"shell"}, nil),
), []string{"zsh", "editor-user"},
Node{Name: "anchor", At: "10.0.0.1", Capabilities: map[string]bool{}}, World{})
if err != nil {
t.Fatal(err)
}
if len(got.Needs) != 0 {
t.Fatalf("a shell answered on this machine produced %d need(s)", len(got.Needs))
}
}