mesh-vault provides `secret` (novox/hq ADR 0085, design 24). The value is the pair credential the controller mints — the vault holds no copy, only a ledger of who holds one, its fingerprint and every rotation, and two tools that answer by fingerprint and never by value. Rotation is `rotate secret`, unchanged machinery pointed at a secret with an owner (design 13). Named in the mesh's own namespace, beside mesh-controller and mesh-catalog, because it is the mesh's own code rather than wrapped software. redis is the first consumer: its own password stops being an own-secret nothing could rotate and becomes a `secret` it requires, read from the same file into the same hole. The server now restarts on its config, or it would keep the password it started with through every rotation (playbook 06).
32 lines
1.4 KiB
TypeScript
32 lines
1.4 KiB
TypeScript
// mesh-vault's events entrypoint, loaded by the per-node tool host (the provisioner runs in the same
|
|
// process — ADR 0052). The lifecycle events are EMITTED from the provisioner, where custody
|
|
// actually changes (novox/hq ADR 0041/0042):
|
|
// module.mesh-vault.secret.provisioned — a consumer was granted a secret
|
|
// module.mesh-vault.secret.rotated — that consumer's value changed (`rotate secret`)
|
|
// module.mesh-vault.secret.deprovisioned — the consumer went away and its secret was withdrawn
|
|
// Here the vault reacts to them, keeping a lightweight audit line of who holds what and when it
|
|
// moved — the audit an owner of secrets is best placed to log. Fingerprints, never values.
|
|
|
|
import { on } from "@novox/mesh-sdk/events";
|
|
|
|
interface SecretEvent {
|
|
as: string;
|
|
consumer?: string;
|
|
fingerprint?: string;
|
|
rotations?: number;
|
|
}
|
|
|
|
await on<SecretEvent>("module.mesh-vault.secret.provisioned", async (e) => {
|
|
console.log(`[mesh-vault] secret provisioned for ${e.body.as} on ${e.body.consumer} (${e.body.fingerprint})`);
|
|
});
|
|
|
|
await on<SecretEvent>("module.mesh-vault.secret.rotated", async (e) => {
|
|
console.log(`[mesh-vault] secret rotated for ${e.body.as} — rotation ${e.body.rotations} (${e.body.fingerprint})`);
|
|
});
|
|
|
|
await on<SecretEvent>("module.mesh-vault.secret.deprovisioned", async (e) => {
|
|
console.log(`[mesh-vault] secret withdrawn from ${e.body.as}`);
|
|
});
|
|
|
|
console.log("[mesh-vault] auditing secret lifecycle events");
|