From 661918f4e4e0b5962072702908294b2c434ebe56 Mon Sep 17 00:00:00 2001 From: mesh-admin Date: Wed, 14 Oct 2026 00:51:59 +0000 Subject: [PATCH] Promise get on the vault's seat, so the Go vault can serve it (issue 674) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The vault hands a secret only on request and reply, sealed to the asker's key (hq ADR 0349 §11). The seat set is the controller's, so the verb is promised here; optional until the vault that runs serves it (design 33 §7). Co-Authored-By: Claude Opus 5.5 --- internal/catalogue/seats.go | 14 +++++++++++- internal/catalogue/vault_seat_test.go | 31 +++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/internal/catalogue/seats.go b/internal/catalogue/seats.go index 68c7291a..1c9478e5 100644 --- a/internal/catalogue/seats.go +++ b/internal/catalogue/seats.go @@ -128,7 +128,19 @@ var defaultSeats = append([]Seat{ // The vault: the controller seals every minted credential with what it provides, which is the // test for a seat of the mesh's own (novox/hq ADR 0161) — a second provider of `secret` is a // second claimant, refused by name, rather than a candidate for a pin. - {Name: "mesh-vault", Scope: ScopeMesh, Delivers: "secret", Decision: "novox/hq ADR 0161"}, + // + // Its one verb, `get`, hands a secret on request and reply, sealed to the key the asker sends and only + // to an asker the vault allows (novox/hq ADR 0349 §11, issue 674). Optional until the vault that runs + // serves it (design 33 §7). + {Name: "mesh-vault", Scope: ScopeMesh, Delivers: "secret", Decision: "novox/hq ADR 0161", + Serves: []Verb{ + {Name: "get", Optional: true, Description: "One secret, sealed to the public key the asker sends (the " + + "sealed box of ADR 0206), with its generation; answered only to an asker the vault allows, as the " + + "bus proved it. Never the value in the clear, and never to a private key.", + Input: schema(map[string]string{"name": "the secret's name", + "public_key": "the asker's X25519 public key as SPKI PEM — never a private key"}, + []string{"name", "public_key"})}, + }}, // Named for its scope since 2026-09-30 (novox/hq ADR 0156); `the-artifact-store` resolves to it as // an alias on a mesh that predates the rename. It serves artifacts of every kind a build makes — // images and archives, by digest — which is why the provision is the artifact store and not an diff --git a/internal/catalogue/vault_seat_test.go b/internal/catalogue/vault_seat_test.go index 0f8827c7..92a31b1b 100644 --- a/internal/catalogue/vault_seat_test.go +++ b/internal/catalogue/vault_seat_test.go @@ -23,3 +23,34 @@ func TestTheVaultsSeatDeliversSecret(t *testing.T) { t.Fatal("a provider of secret that does not claim the seat was allowed to hold it") } } + +// The vault answers `get` on request and reply (novox/hq ADR 0349 §11, issue 674): the seat promises the +// verb, so a holder serving it is accepted — and, optional while the vault that runs is the TypeScript one, +// so is a holder that does not yet. +func TestTheVaultsSeatPromisesGet(t *testing.T) { + seat, _ := SeatNamed("mesh-vault") + var get *Verb + for i := range seat.Serves { + if seat.Serves[i].Name == "get" { + get = &seat.Serves[i] + } + } + if get == nil { + t.Fatal("the vault's seat does not promise get") + } + for _, arg := range []string{"name", "public_key"} { + if props, _ := get.Input["properties"].(map[string]any); props[arg] == nil { + t.Errorf("get takes no %s", arg) + } + } + serving := Manifest{Module: "mesh-vault", Provides: []Offer{{Name: "secret", Scope: ScopeMesh}}, + Claims: []Claim{{Name: "mesh-vault", Scope: ScopeMesh, Serves: []string{"get"}}}} + if err := CanHold(serving, seat); err != nil { + t.Fatalf("the vault serving get was refused: %v", err) + } + notYet := Manifest{Module: "mesh-vault", Provides: []Offer{{Name: "secret", Scope: ScopeMesh}}, + Claims: []Claim{{Name: "mesh-vault", Scope: ScopeMesh}}} + if err := CanHold(notYet, seat); err != nil { + t.Fatalf("the vault that does not serve get yet was refused: %v", err) + } +}