fix(housekeeping): harden audited command dispatch

This commit is contained in:
Simo committed 2026-08-27 18:58:14 +02:00
1 parent 6aed71a8b2
commit 796d009c07
7 files changed
+775 -124

No files matched your search

@@ -122,12 +122,8 @@ describe("dispatchHousekeepingCommand", () => {
error: { code: "FORBIDDEN" },
});
expect(executed).toBe(false);
expect(audit.entries.map((entry) => entry.outcome)).toEqual([
"intent",
"denied",
]);
expect(audit.entries.map((entry) => entry.outcome)).toEqual(["denied"]);
expect(audit.entries[0]?.correlationId).toBe(result.correlationId);
expect(audit.entries[1]?.correlationId).toBe(result.correlationId);
});
it("rejects invalid input before the command can execute", async () => {
@@ -182,10 +178,7 @@ describe("dispatchHousekeepingCommand", () => {
},
});
expect(executed).toBe(false);
expect(audit.entries.map((entry) => entry.outcome)).toEqual([
"intent",
"denied",
]);
expect(audit.entries.map((entry) => entry.outcome)).toEqual(["denied"]);
});
it("uses actor, IP, command ID, and the approved command limit", async () => {
@@ -392,4 +385,310 @@ describe("dispatchHousekeepingCommand", () => {
]);
expect(audit.entries[1]?.correlationId).toBe(result.correlationId);
});
it("runs sensitive validation and rate preflight before intent and execution", async () => {
const events: string[] = [];
const audit = auditRecorder(events);
const tracedContext = {
...capabilityContext(),
hasAny: (...slugs: string[]) => {
events.push("capability");
return slugs.includes("admin.settings.edit");
},
};
register(
baseCommand("system.dispatch.preflight-order", {
risk: "sensitive",
requiresReason: true,
input: z.object({ enabled: z.boolean() }).superRefine(() => {
events.push("input");
}),
execute: async (context) => {
events.push("execute");
return ok(null, context.correlationId);
},
}),
);
await dispatchHousekeepingCommand(
{
commandId: "system.dispatch.preflight-order",
input: { enabled: true },
reason: "Approved change",
},
dependencies({
context: tracedContext,
audit: audit.writer,
rateLimit: async () => {
events.push("rate");
return true;
},
}),
);
expect(events).toEqual([
"capability",
"input",
"rate",
"audit:intent",
"execute",
"audit:success",
]);
});
it.each([
["capability", "system.dispatch.preflight-denied"],
["input", "system.dispatch.preflight-invalid"],
["rate", "system.dispatch.preflight-limited"],
] as const)(
"writes only denied evidence when sensitive %s preflight rejects",
async (boundary, commandId) => {
const audit = auditRecorder();
let executed = false;
register(
baseCommand(commandId, {
risk: "sensitive",
input: z.object({ count: z.number().positive() }),
execute: async (context) => {
executed = true;
return ok(null, context.correlationId);
},
}),
);
const result = await dispatchHousekeepingCommand(
{
commandId,
input: { count: boundary === "input" ? -1 : 1 },
},
dependencies({
context:
boundary === "capability"
? capabilityContext([])
: capabilityContext(),
audit: audit.writer,
rateLimit: async () => boundary !== "rate",
}),
);
expect(result).toMatchObject({ ok: false });
expect(executed).toBe(false);
expect(audit.entries.map((entry) => entry.outcome)).toEqual(["denied"]);
expect(audit.entries[0]?.correlationId).toBe(result.correlationId);
},
);
it("writes generic server-owned evidence for a validated unknown command", async () => {
const audit = auditRecorder();
const result = await dispatchHousekeepingCommand(
{ commandId: "system.dispatch.unknown-audited", input: {} },
dependencies({ audit: audit.writer }),
);
expect(result).toMatchObject({
ok: false,
error: { code: "NOT_FOUND" },
});
expect(audit.entries).toEqual([
{
userId: 42,
action: "housekeeping.command.dispatch",
target: "system.dispatch.unknown-audited",
correlationId: result.correlationId,
outcome: "denied",
ipAddress: "198.51.100.8",
},
]);
});
it.each([
null,
[],
Object.assign(Object.create({ inherited: true }), {
commandId: "system.dispatch.unknown",
input: {},
}),
{ commandId: "system.dispatch.unknown", input: {}, risk: "safe" },
{ commandId: `system.${"x".repeat(200)}`, input: {} },
{
commandId: "system.dispatch.unknown",
input: {},
reason: "x".repeat(1001),
},
])(
"returns a correlated validation result for malformed runtime request %#",
async (request) => {
const result = await dispatchHousekeepingCommand(
request as never,
dependencies(),
);
expect(result).toMatchObject({
ok: false,
error: {
code: "VALIDATION",
messageKey: "errors.housekeeping.validation",
},
});
expect(result.correlationId).toMatch(/^[0-9a-f-]{36}$/i);
},
);
it("sanitizes a capability exception and writes failure evidence", async () => {
const audit = auditRecorder();
register(
baseCommand("system.dispatch.capability-exception", {
input: z.object({}),
execute: async (context) => ok(null, context.correlationId),
}),
);
const brokenContext = {
...capabilityContext(),
hasAny: () => {
throw new Error("capability secret exposed");
},
};
const result = await dispatchHousekeepingCommand(
{ commandId: "system.dispatch.capability-exception", input: {} },
dependencies({ context: brokenContext, audit: audit.writer }),
);
expect(result).toMatchObject({
ok: false,
error: { code: "INTERNAL", messageKey: "errors.housekeeping.internal" },
});
expect(JSON.stringify(result)).not.toContain("secret exposed");
expect(audit.entries.map((entry) => entry.outcome)).toEqual(["failure"]);
});
it("sanitizes a schema exception and writes failure evidence", async () => {
const audit = auditRecorder();
register(
baseCommand("system.dispatch.schema-exception", {
input: z.preprocess(() => {
throw new Error("schema secret exposed");
}, z.object({})),
execute: async (context) => ok(null, context.correlationId),
}),
);
const result = await dispatchHousekeepingCommand(
{ commandId: "system.dispatch.schema-exception", input: {} },
dependencies({ audit: audit.writer }),
);
expect(result).toMatchObject({
ok: false,
error: { code: "INTERNAL", messageKey: "errors.housekeeping.internal" },
});
expect(JSON.stringify(result)).not.toContain("secret exposed");
expect(audit.entries.map((entry) => entry.outcome)).toEqual(["failure"]);
});
it("throws completed-operation evidence and persists partial when success audit rejects", async () => {
const attempts: string[] = [];
const persisted: string[] = [];
register(
baseCommand("system.dispatch.success-audit-rejection", {
input: z.object({}),
execute: async (context) =>
ok({ changed: true }, context.correlationId),
}),
);
const dispatch = dispatchHousekeepingCommand(
{ commandId: "system.dispatch.success-audit-rejection", input: {} },
dependencies({
audit: {
write: async (entry) => {
attempts.push(entry.outcome ?? "missing");
if (entry.outcome === "success") {
throw new Error("success audit unavailable");
}
persisted.push(entry.outcome ?? "missing");
},
},
}),
);
await expect(dispatch).rejects.toMatchObject({
name: "AuditOutcomePersistenceError",
operationCompleted: true,
operationResult: { ok: true, data: { changed: true } },
});
expect(attempts).toEqual(["success", "partial"]);
expect(persisted).toEqual(["partial"]);
});
it("preserves a returned command failure when failure audit rejects", async () => {
const attempts: string[] = [];
register(
baseCommand("system.dispatch.returned-failure-audit-rejection", {
input: z.object({}),
execute: async () =>
fail(
"DEPENDENCY_UNAVAILABLE",
"errors.housekeeping.dependencyUnavailable",
"wrong-correlation",
),
}),
);
const result = await dispatchHousekeepingCommand(
{
commandId: "system.dispatch.returned-failure-audit-rejection",
input: {},
},
dependencies({
audit: {
write: async (entry) => {
attempts.push(entry.outcome ?? "missing");
throw new Error("failure audit unavailable");
},
},
}),
);
expect(result).toMatchObject({
ok: false,
error: { code: "DEPENDENCY_UNAVAILABLE" },
});
expect(result.correlationId).not.toBe("wrong-correlation");
expect(attempts).toEqual(["failure"]);
});
it("preserves a sanitized throwing-command failure when failure audit rejects", async () => {
const attempts: string[] = [];
register(
baseCommand("system.dispatch.thrown-failure-audit-rejection", {
input: z.object({}),
execute: async () => {
throw new Error("command database secret exposed");
},
}),
);
const result = await dispatchHousekeepingCommand(
{
commandId: "system.dispatch.thrown-failure-audit-rejection",
input: {},
},
dependencies({
audit: {
write: async (entry) => {
attempts.push(entry.outcome ?? "missing");
throw new Error("audit replacement secret exposed");
},
},
}),
);
expect(result).toMatchObject({
ok: false,
error: { code: "INTERNAL", messageKey: "errors.housekeeping.internal" },
});
expect(JSON.stringify(result)).not.toContain("secret exposed");
expect(attempts).toEqual(["failure"]);
});
});