67 lines
4.2 KiB
JavaScript
67 lines
4.2 KiB
JavaScript
// Row 234 (#1740, r6 X4): host and grant store records for tests. Row a has no way to make a host_grants
|
|
// record outside a fixture, because row b's grant executor writes them. The decision, its raise event and
|
|
// its close go in by SQL. The grant evidence goes through writeGrantEvent (F1), so the trigger sees the
|
|
// real shape.
|
|
import { randomUUID } from 'node:crypto';
|
|
import { registrySha256, writeGrantEvent } from '../src/broker.mjs';
|
|
import { grantTag } from '../src/host-grant.mjs';
|
|
|
|
const AT = '2026-10-21T00:00:00.000Z';
|
|
const OPTIONS = JSON.stringify([{ key: 'yes', text: 'Yes' }, { key: 'no', text: 'No' }]);
|
|
export const HUMAN_YES = { op: 'resolved', by: 'jason', choice: 'yes', via: 'cli' };
|
|
|
|
// A credential.mint decision with `grant` in its raise body. `close` is the decision_events row, or null
|
|
// for an open decision.
|
|
export function grantDecision(store, { business = 'demo', raiser = 'chief', action = 'credential.mint', route = 'human', domain = 'delivery', grant, close = HUMAN_YES }) {
|
|
const id = randomUUID();
|
|
store.run(
|
|
'INSERT INTO decisions(id,at,business,raised_by_role,raised_by_run,class,action,route_to,question,options,recommendation,blocking) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)',
|
|
id, AT, business, raiser, raiser+'-run', 'gated', action, route, 'Grant?', OPTIONS, 'yes', 0,
|
|
);
|
|
store.run(
|
|
"INSERT INTO events(id,at,business,kind,actor_role,actor_run,subject,body) VALUES(?,?,?,'action.allowed',?,?,?,?)",
|
|
randomUUID(), AT, business, raiser, raiser+'-run', id,
|
|
JSON.stringify({ decision: id, action, operation: 'decision.raise', ...(domain === null ? {} : { domain }), approvalChoice: 'yes', ...(grant ? { grant } : {}) }),
|
|
);
|
|
if (close)
|
|
store.run('INSERT INTO decision_events(decision,at,op,by,choice,via) VALUES(?,?,?,?,?,?)', id, AT, close.op, close.by, close.choice ?? null, close.via ?? null);
|
|
return id;
|
|
}
|
|
|
|
// A ready host record from an approved, spent and finished enrollment. grant.host.enrolled keeps the
|
|
// start reconcile from reading the enrollment as interrupted.
|
|
export function hostRecord(store, { business = 'demo', host = 'web1', entry, sudo = true }) {
|
|
const grant = { method: 'host-enroll', host, address: entry.address, port: entry.port, user: entry.user, sudo, fingerprints: [] };
|
|
const decision = grantDecision(store, { business, grant });
|
|
writeGrantEvent(store, AT, business, { operation: 'grant.host-enroll', decision }, decision);
|
|
const installerFingerprint = 'SHA256:' + 'A'.repeat(43);
|
|
writeGrantEvent(store, AT, business, {
|
|
action: 'grant.host.enrolled', grantDecision: decision, host, installerFingerprint, user: entry.user, sudo,
|
|
registrySha256: registrySha256({ ...entry, sudo }),
|
|
}, decision);
|
|
store.run(
|
|
'INSERT INTO hosts(business,host,address,port,user,sudo,host_keys,installer_fingerprint,state,decision,checked_at) VALUES(?,?,?,?,?,?,?,?,?,?,?)',
|
|
business, host, entry.address, entry.port, entry.user, sudo ? 1 : 0, JSON.stringify(entry.hostKeys), installerFingerprint, 'ready', decision, AT,
|
|
);
|
|
return decision;
|
|
}
|
|
|
|
// One agent's grant record on a host. By default its decision is a `host` grant for the same agent and
|
|
// host, resolved yes by the human via cli and spent as grant.host. Each option breaks one part.
|
|
export function hostGrantRecord(store, { business = 'demo', agent, host = 'web1', commands, rotateBy = '2099-01-01', grant = {}, close = HUMAN_YES, spend = 'grant.host', action }) {
|
|
const decision = grantDecision(store, {
|
|
business, close, action,
|
|
grant: grant === null ? undefined : { method: 'host', agent, host, commands, rotateBy, ...grant },
|
|
});
|
|
if (spend) writeGrantEvent(store, AT, business, { operation: spend, decision }, decision);
|
|
// Row 235: the executor commits each record with its grant.applied (r6 X2 step 5), so the start
|
|
// reconcile reads a fixture record as a finished grant.
|
|
if (spend === 'grant.host')
|
|
writeGrantEvent(store, AT, business, { action: 'grant.applied', grantDecision: decision, agent, host, tag: grantTag(business, agent, host) }, host);
|
|
store.run(
|
|
'INSERT INTO host_grants(business,agent,host,commands,rotate_by,tag,decision) VALUES(?,?,?,?,?,?,?)',
|
|
business, agent, host, JSON.stringify(commands), rotateBy, grantTag(business, agent, host), decision,
|
|
);
|
|
return decision;
|
|
}
|