events: an e2e test — an emitted event reaches the audit trail over the mesh's broker #2
@@ -774,6 +774,11 @@ test("rotating a credential moves both ends, and the old one stops working", {
|
||||
`"serves":{"realdatabase":{"port":5433}},` +
|
||||
`"needs":{"superuser":"${store}/superuser"},` +
|
||||
`"grants":{"realdatabase":"${store}/grants"},` +
|
||||
// Both halves. `grants` is where each consumer's sealed password lands; `receives` is the
|
||||
// manifest saying who asked and for what. Without the second the provisioner finds a
|
||||
// directory of unexplained secrets and says nothing has been granted — which is true, and
|
||||
// reads exactly like a credential that was never delivered.
|
||||
`"receives":{"realdatabase":"${store}/grants/mesh.json"},` +
|
||||
`"listens":[{"port":5433,"from":"mesh","why":"a database the mesh provisions"}],` +
|
||||
`"resources":[` +
|
||||
`{"id":"state","type":"directory","path":"${store}","mode":"0755"},` +
|
||||
@@ -937,3 +942,78 @@ test("a route is a grant: a workload is reached by the name it asked for", {
|
||||
}
|
||||
assert.ok(gone, "the proxy still serves a name whose module was unassigned");
|
||||
});
|
||||
|
||||
test("model access is answered by a record, and the key the mesh took is one it cannot read", {
|
||||
skip, timeout: 900_000,
|
||||
}, async () => {
|
||||
// novox/hq ADR 0024. The first provision no machine answers: a hosted model is on nobody's
|
||||
// node and is reached over the public internet, so the rule that refuses two ends sharing no
|
||||
// private network must not apply to it.
|
||||
await must("anchor", `printf %s '{"module":"assistant","version":"1",` +
|
||||
`"requires":["model-access"],` +
|
||||
`"binds":{"model-access":"/etc/assistant/model.json"},` +
|
||||
`"secrets":{"model-access":"/etc/assistant/key"},` +
|
||||
`"resources":[{"id":"dir","type":"directory","path":"/etc/assistant","mode":"0755"}]}' ` +
|
||||
`> /tmp/assistant.json`);
|
||||
await must("anchor", `docker cp /tmp/assistant.json mesh-control:/assistant.json`);
|
||||
await mesh("module add /assistant.json");
|
||||
await mesh("assign laptop assistant");
|
||||
|
||||
await mesh(`licence add anthropic personal --serves '{"model":"a-model"}'`);
|
||||
await mesh(`licence add anthropic the-organisation --serves '{"model":"a-model"}'`);
|
||||
|
||||
// Refused until somebody says which, and the refusal names both candidates and the command.
|
||||
// ADR 0024 warns this will be felt — which is correct, and correct is not the same as usable.
|
||||
const refused = await on("anchor", `docker exec mesh-control /mesh-control plan laptop`);
|
||||
assert.ok(!refused.ok, `a consumer was given model access without anybody saying which:\n${refused.out}`);
|
||||
for (const want of ["personal", "the-organisation", "licence use"]) {
|
||||
assert.match(refused.out, new RegExp(want),
|
||||
`the refusal does not name ${want}:\n${refused.out}`);
|
||||
}
|
||||
|
||||
await mesh("licence use personal laptop assistant");
|
||||
|
||||
// Chosen, and still no key: the mesh has one thing to deliver and has not been given it.
|
||||
const noKey = await on("anchor", `docker exec mesh-control /mesh-control plan laptop`);
|
||||
assert.ok(!noKey.ok, `a module was planned with a licence that has no key:\n${noKey.out}`);
|
||||
assert.match(noKey.out, /licence key personal/, noKey.out);
|
||||
|
||||
// The accept verb. Given on standard input rather than as an argument, because a key in a
|
||||
// command line is a key in shell history and in every process listing taken while it ran.
|
||||
const secret = "sk-test-" + "0123456789abcdef".repeat(2);
|
||||
const accepted = await must("anchor",
|
||||
`printf %s ${quote(secret)} | docker exec -i mesh-control /mesh-control licence key personal`);
|
||||
assert.match(accepted, /sealed to 1 holder/, accepted);
|
||||
assert.doesNotMatch(accepted, new RegExp(secret),
|
||||
"the key was echoed back, so the one copy that matters is on a terminal");
|
||||
|
||||
await mesh("push laptop");
|
||||
await new Promise((r) => setTimeout(r, 15_000));
|
||||
|
||||
// What is public arrives, and says it is a record rather than leaving an empty address that a
|
||||
// reader would take for something the mesh failed to fill in.
|
||||
const bound = await must("laptop", `cat /etc/assistant/model.json`);
|
||||
assert.match(bound, /personal/, `the consumer was not told which licence it is on:\n${bound}`);
|
||||
assert.match(bound, /a-model/, `what the licence serves did not arrive:\n${bound}`);
|
||||
assert.match(bound, /not a machine/, `the binding leaves an unexplained empty address:\n${bound}`);
|
||||
|
||||
// And the key arrives, readable only by this machine.
|
||||
assert.equal((await must("laptop", `cat /etc/assistant/key`)).trim(), secret,
|
||||
"the key that arrived is not the key that was given");
|
||||
assert.match(await must("laptop", `stat -c %a /etc/assistant/key`), /^600/);
|
||||
|
||||
// The mesh cannot read it back. This is the whole argument: what is stored is unusable by
|
||||
// whoever holds it, the control plane included.
|
||||
const stored = await must("anchor",
|
||||
`docker exec mesh-store psql -U postgres -d licences -qAt ` +
|
||||
`-c "select coalesce(sealed,'') from licence_holder"`);
|
||||
assert.ok(stored.trim().length > 0, "nothing was stored, so nothing was sealed");
|
||||
assert.doesNotMatch(stored, new RegExp(secret),
|
||||
"the key is in the control plane's own database in the open");
|
||||
|
||||
// Nor is it anywhere it could have been read on the way.
|
||||
for (const where of ["/var/lib/mesh-host/declared.json", "/var/lib/mesh-host/state.json"]) {
|
||||
const held = await on("laptop", `grep -c ${quote(secret)} ${where} 2>/dev/null || echo 0`);
|
||||
assert.equal(held.out.trim(), "0", `the key is in the open in ${where}`);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user