The vault bed installs a consumer that keeps two secrets, and both are delivered and rotated
Two files with two values, two holders in the vault's ledger — the identity with the local name after it — and one rotate moves both (novox/hq ADR 0094).
This commit is contained in:
@@ -259,9 +259,32 @@ test("redis's own password is a secret the vault provides: it authenticates, and
|
||||
assert.match(issued, /scoped to what it emits and consumes/, issued);
|
||||
await mesh(`assign ${MACHINE} ${name}`);
|
||||
}
|
||||
// A consumer that needs TWO values from the vault (novox/hq ADR 0094): its `secrets` entry names
|
||||
// them under local names, and each is a pair of its own. It runs no code — the delivery is what
|
||||
// is under test. Synthetic, so it wears no catalogue module's name.
|
||||
const twoSecrets = JSON.stringify({
|
||||
module: "two-secrets", version: "1", slug: "two",
|
||||
requires: ["secret"],
|
||||
secrets: { secret: { first: "/var/lib/two-secrets/first", second: "/var/lib/two-secrets/second" } },
|
||||
resources: [{ id: "state", type: "directory", path: "/var/lib/two-secrets", mode: "0700" }],
|
||||
});
|
||||
await must(`printf %s ${quote(twoSecrets)} > /tmp/two-secrets.json && docker cp /tmp/two-secrets.json mesh-controller:/two-secrets.json`);
|
||||
await mesh("module add /two-secrets.json");
|
||||
await mesh(`assign ${MACHINE} two-secrets`);
|
||||
await mesh(`push ${MACHINE}`);
|
||||
await settled();
|
||||
|
||||
// Two files, two values, and the vault holds two holders for one module — the identity with the
|
||||
// local name after it.
|
||||
const first = (await must(`cat /var/lib/two-secrets/first`)).replace(/\n$/, "");
|
||||
const second = (await must(`cat /var/lib/two-secrets/second`)).replace(/\n$/, "");
|
||||
assert.ok(first.length >= 20 && second.length >= 20, "a two-secrets value is empty or implausibly short");
|
||||
assert.notEqual(first, second, "two local names were given one value");
|
||||
for (const holderOf of ["mesh_anchor_two_first", "mesh_anchor_two_second"]) {
|
||||
await until(`the vault holding ${holderOf}`, 90_000, async () =>
|
||||
(await on(`test -s ${LEDGER}/${holderOf}.json`)).ok ? true : undefined);
|
||||
}
|
||||
|
||||
const running = await must(`docker ps --format '{{.Names}}'`);
|
||||
for (const c of ["mesh-vault", "redis", "mesh-redis"]) {
|
||||
assert.match(running, new RegExp(`(^|\\n)${c}(\\n|$)`),
|
||||
@@ -335,6 +358,21 @@ test("rotating the secret moves both ends: the new password works, the old one i
|
||||
});
|
||||
assert.notEqual(after, before);
|
||||
|
||||
// Both of the two-secrets consumer's values moved too, apart from each other (ADR 0094).
|
||||
const firstAfter = await until("the rotated first secret", 180_000, async () => {
|
||||
const now = (await must(`cat /var/lib/two-secrets/first`)).replace(/\n$/, "");
|
||||
return now !== "" ? now : undefined;
|
||||
});
|
||||
const secondAfter = (await must(`cat /var/lib/two-secrets/second`)).replace(/\n$/, "");
|
||||
assert.notEqual(firstAfter, secondAfter, "two local names were given one value after rotation");
|
||||
for (const holderOf of ["mesh_anchor_two_first", "mesh_anchor_two_second"]) {
|
||||
const h = await until(`the vault recording ${holderOf}'s rotation`, 90_000, async () => {
|
||||
const got = JSON.parse(await must(`cat ${LEDGER}/${holderOf}.json`)) as Held;
|
||||
return got.rotations >= 1 ? got : undefined;
|
||||
});
|
||||
assert.equal(h.rotations, 1, holderOf);
|
||||
}
|
||||
|
||||
// Three logins. The new one works (redis was restarted on its config — `restart-on`), the old one
|
||||
// does not: that third check is what makes it a rotation rather than an addition.
|
||||
await until("redis accepting the rotated password", 180_000, async () => {
|
||||
|
||||
Reference in New Issue
Block a user