// mesh-vault's tools — vault's own code (novox/hq ADR 0039), served through the sdk's tool harness. They // return structured data about the secrets this vault provides, and **never a value**: a holder is // identified by its login and a value by its fingerprint. That is the rule the source mesh's // secret_locate / secret_verify were built on, after a secret printed into a transcript. import { readFileSync } from "node:fs"; import { join } from "node:path"; import { registerModuleTools, type ToolDefinition } from "@novox/mesh-sdk/tools"; import { Ledger, contributions, deliveredFingerprint, type Held } from "../client.js"; /** The mesh's export of every operator-sealed secret, as the mesh wrote it into the root dir. */ interface KeptExport { export: number; "operator-key": string; fingerprint: string; kept: { node: string; module: string; name: string; origin: string; sealed: string; key: string; "made-at": string }[]; unrecoverable?: { node: string; module: string; name: string }[]; } export function getVaultTools(ledger: Ledger, receives: string | undefined, root: string | undefined): ToolDefinition[] { return [ { name: "secret_export", description: "The mesh's root secrets as this vault keeps them: every secret a module holds for itself, " + "sealed to the operator's key (novox/hq ADR 0085, amended). Ciphertext — nothing here can " + "open a line of it; the operator, holding the private key off the mesh, recovers one with " + "`mesh-controller secret recover --from-export`. Also lists what is NOT recoverable: secrets " + "made before the mesh had an operator key.", input: { sealed: { type: "boolean", description: "include the sealed blobs (default true); false lists holders and the key only", }, }, run: async (args) => { if (!root) return { available: false, error: "this vault keeps no root secrets (MESH_VAULT_ROOT is not set)" }; let doc: KeptExport; try { doc = JSON.parse(readFileSync(join(root, "export.json"), "utf8")) as KeptExport; } catch (err) { return { available: false, error: `the mesh has not written an export here yet: ${err}` }; } const withBlobs = args.sealed !== false; return { available: true, export: doc.export, "operator-key": doc["operator-key"], fingerprint: doc.fingerprint, count: doc.kept.length, kept: doc.kept.map((k) => (withBlobs ? k : { node: k.node, module: k.module, name: k.name, origin: k.origin, "made-at": k["made-at"] })), unrecoverable: doc.unrecoverable ?? [], }; }, }, { name: "secret_holders", description: "Who holds a secret from this vault: each consumer's login, node and module, when it was " + "granted, how many times it has been rotated and when, and the fingerprint of the current " + "value. Fingerprints only — the value is never returned.", input: {}, run: async () => { const asked = receives ? contributions(receives) : []; const holders = ledger.list().map((h) => ({ ...h, module: asked.find((c) => c.as === h.as)?.from ?? null, asked: asked.some((c) => c.as === h.as), })); return { holders, count: holders.length }; }, }, { name: "secret_verify", description: "Check one holder's secret without seeing it: the fingerprint the vault recorded against " + "the fingerprint of the value the mesh currently delivers here, and optionally against a " + "fingerprint computed on the holder's own machine (sha256 of the file, as `sha256:`). " + "Two ends agreeing proves they agree, not that either works — the login itself is the test.", input: { as: { type: "string", description: "the holder's login, e.g. anchor-redis" }, fingerprint: { type: "string", description: "optional: sha256: of the value as the holder reads it, computed there — never the value", }, }, run: async (args) => { const as = String(args.as ?? ""); const recorded = ledger.get(as); if (!recorded) return { as, known: false, error: `this vault holds nothing for ${as}` }; const asked = receives ? contributions(receives).find((c) => c.as === as) : undefined; const delivered = asked ? deliveredFingerprint(asked) : { error: "the mesh does not currently ask this vault to serve that login" }; const given = args.fingerprint ? String(args.fingerprint) : undefined; return verdict(recorded, delivered, given); }, }, ]; } function verdict( recorded: Held, delivered: { fingerprint: string; length: number } | { error: string }, given: string | undefined, ): Record { const deliveredMatches = "fingerprint" in delivered ? delivered.fingerprint === recorded.fingerprint : null; const givenMatches = given === undefined ? null : given === recorded.fingerprint; return { as: recorded.as, known: true, recorded: recorded.fingerprint, rotations: recorded.rotations, changed: recorded.changed, delivered: "fingerprint" in delivered ? delivered.fingerprint : null, deliveredError: "error" in delivered ? delivered.error : null, deliveredMatchesRecorded: deliveredMatches, given: given ?? null, givenMatchesRecorded: givenMatches, givenIsAnEarlierValue: given === undefined ? null : recorded.history.some((h) => h.fingerprint === given), ok: deliveredMatches !== false && givenMatches !== false, }; } // The tools exist only when the ledger can be reached from the environment; without it, vault // contributes none rather than failing the whole tool runtime. registerModuleTools("mesh-vault", (env) => { try { return getVaultTools(Ledger.fromEnv(env), env.MESH_RECEIVES, env.MESH_VAULT_ROOT); } catch { return []; } });