163 lines
16 KiB
TypeScript
163 lines
16 KiB
TypeScript
/** Real publisher/ALS/principal/policy/crypto with synthetic SQL boundaries. */
|
|
import assert from "node:assert/strict"
|
|
import { test } from "node:test"
|
|
import { randomUUID } from "node:crypto"
|
|
import { mkdtemp, realpath, writeFile, rm } from "node:fs/promises"
|
|
import { tmpdir } from "node:os"
|
|
import { join, dirname } from "node:path"
|
|
import { performance } from "node:perf_hooks"
|
|
import { setTimeout as delay } from "node:timers/promises"
|
|
import type { McpPrincipal } from "./store.js"
|
|
import type { McpConnectionPolicy } from "@mmapp/contracts/mcp"
|
|
import { principalSourceRowsForTests } from "../../test/mcp-principal-source-rows.js"
|
|
|
|
test("ordinary MCP operation publisher before legacy locks; actual private origin with synthetic SQL", async t => {
|
|
const parent = await realpath(tmpdir()), directory = await mkdtemp(join(parent, "mm-operation-root-")), prior = process.env.MCP_STATE_DIR
|
|
process.env.MCP_STATE_DIR = directory
|
|
const generation = Buffer.alloc(32, 91)
|
|
await writeFile(join(directory, "encryption-key"), Buffer.alloc(32, 83)); await writeFile(join(directory, "access-generation"), generation)
|
|
const { pool, closePool } = await import("../../db/index.js"), actualQuery = pool.query, actualConnect = pool.connect
|
|
const source = await import("./operation-execution-origin.js")
|
|
const { encryptSecret, fingerprint, redact } = await import("./security.js")
|
|
const { findActionByOperation } = await import("./actions.js")
|
|
const { withApplicationMutationLock, withConfigMutationLock } = await import("../../services/config-mutation-lock.js")
|
|
const { withOperationConfigurationLockClient } = await import("../../services/operation-config-lock-lease.js")
|
|
let row: Record<string, unknown> & { id: string; plan_id: string; connection_id: string; operation_state: string; plan_state: string; result: Record<string, unknown> | null; claim_nonce?: unknown; payload: { sealed: string }; owner_permissions: string[] }
|
|
let connection: Record<string, unknown> & { owner_id: string; owner_permissions: string[]; owner_claims_issued_at: Date; owner_valid_until: Date; policy: McpConnectionPolicy }
|
|
let cleanups = 0, audits = 0, calls = 0
|
|
let fault: "none" | "lost-own" | "lost-other" | "rows-only" = "none", claimGate: (() => Promise<void>) | undefined
|
|
const clone = <T>(value: T) => structuredClone(value)
|
|
const result = (command: string, rows: unknown[]) => ({ command, rowCount: rows.length, rows })
|
|
async function query(raw: string | { text: string; values?: unknown[] }, values?: unknown[]) {
|
|
calls++; const text = typeof raw === "string" ? raw : raw.text, args = typeof raw === "string" ? values ?? [] : raw.values ?? []
|
|
if (text.startsWith("/* mcp-principal:coherent-source-v1 */")) return result("SELECT", principalSourceRowsForTests(connection,
|
|
{ credentialId: String(args[0]), credentialExpiresAt: connection.owner_valid_until.toISOString() }, { includeGrants: args[2] === true }))
|
|
if (text.startsWith("SELECT pg_current_xact_id_if_assigned")) return result("SELECT", [{ creating_xid: "123" }])
|
|
if (text.startsWith("INSERT INTO mcp_operations")) { row.id = String(args[0]); row.plan_id = String(args[1]); row.connection_id = String(args[2]); return result("INSERT", [{ id: row.id, plan_id: row.plan_id, connection_id: row.connection_id, state: "pending", result: null }]) }
|
|
if (text.includes("AS creating_transaction")) return result("SELECT", [{ ...clone(row), creating_transaction: true }])
|
|
if (text.startsWith("SELECT id FROM mcp_credentials")) return result("SELECT", [{ id: args[0] }])
|
|
if (text.startsWith("SELECT * FROM mcp_connections")) return result("SELECT", [clone(connection)])
|
|
if (text.startsWith("SELECT invalid_before FROM mcp_owner_revocations")) return result("SELECT", [])
|
|
if (text.startsWith("SELECT enabled FROM mcp_settings")) return result("SELECT", [{ enabled: true }])
|
|
if (text.startsWith("/* mcp-operation-root:source */")) return result("SELECT", [clone(row)])
|
|
if (text.includes("FROM public.mcp_grants")) return result("SELECT", [])
|
|
if (text.startsWith("/* mcp-operation-root:claim */")) {
|
|
await claimGate?.()
|
|
if (fault === "lost-other") { row.operation_state = "running"; row.claim_nonce = randomUUID(); row.result = { [source.MCP_OPERATION_PRIVATE_CLAIM_KEY]: row.claim_nonce }; throw Error("Real zero-row ACK lost after rival winner (synthetic driver)") }
|
|
if (row.operation_state !== "pending") return result("UPDATE", [])
|
|
row.operation_state = "running"; row.claim_nonce = args[3]; row.result = { [source.MCP_OPERATION_PRIVATE_CLAIM_KEY]: args[3] }
|
|
if (fault === "lost-own") throw Error("Applied own claim ACK lost (synthetic driver)")
|
|
const ack = result("UPDATE", [{ id: row.id, plan_id: row.plan_id, connection_id: row.connection_id, state: "running", result: clone(row.result) }])
|
|
return fault === "rows-only" ? { rows: ack.rows } : ack
|
|
}
|
|
if (text.startsWith("UPDATE public.mcp_operations SET state='unknown'")) {
|
|
if (!(row.operation_state === "pending" && !row.claim_nonce || row.operation_state === "running" && row.claim_nonce === args[3])) return result("UPDATE", [])
|
|
cleanups++; row.operation_state = "unknown"; row.result = { needsReview: true, automaticRetry: false }; return result("UPDATE", [{ plan_id: row.plan_id }])
|
|
}
|
|
if (text.startsWith("UPDATE public.mcp_plans")) { row.plan_state = "completed"; return result("UPDATE", []) }
|
|
if (text.startsWith("INSERT INTO mcp_audit")) { audits++; return result("INSERT", []) }
|
|
if (text === "BEGIN" || text === "COMMIT") return result(text, [])
|
|
if (text.includes("pg_try_advisory_lock")) return result("SELECT", [{ acquired: true }])
|
|
if (text.includes("pg_advisory_unlock")) return result("SELECT", [{ released: true }])
|
|
throw Error("Unexpected fixture SQL family")
|
|
}
|
|
pool.query = query as never
|
|
const client = { query, release() {}, on() {}, removeListener() {} }
|
|
pool.connect = (async () => client) as never
|
|
async function fixture(ttl = 30000) {
|
|
fault = "none"; claimGate = undefined
|
|
const principal: McpPrincipal = { connectionId: randomUUID(), credentialId: randomUUID(), credentialExpiresAt: new Date(Date.now() + 60000).toISOString() }
|
|
const expires = Date.now() + ttl, id = randomUUID(), planId = randomUUID(), action = findActionByOperation("users.create")
|
|
const evidence = { target: { scope: "global" }, objects: [{ kind: "user", id: "owned-user" }], snapshots: [], warnings: [], steps: [0, 1].map(index => ({ kind: "service", service: "users.create", input: { index } })) }
|
|
const input = { user: { name: "owned private input" } }, payload = { sealed: await encryptSecret(JSON.stringify(input)) }, encryptedEvidence = { sealed: await encryptSecret(JSON.stringify(evidence)) }
|
|
connection = { id: principal.connectionId, name: "fixture", owner_id: "owned-root-owner", owner_permissions: ["mm:users:write"], generation: generation.toString("hex"), owner_claims_issued_at: new Date(Date.now() - 1000), owner_valid_until: new Date(expires + 1000),
|
|
policy: { id: principal.connectionId, version: 1, status: "active", expiresAt: new Date(expires + 1000).toISOString(), mode: "autonomous", permissions: ["mm:users:write"], scope: { serverIds: [], operationIds: ["users.create"], allowGlobal: true }, dangerousPolicy: "explicit-allow", autonomousDangerousOperationIds: ["users.create"], limits: { callsPerMinute: 60, concurrentReads: 4, mutationsPerHour: 10, serversPerPlan: 5, objectsPerPlan: 100 } } }
|
|
row = { id, plan_id: planId, connection_id: principal.connectionId, operation_state: "pending", plan_state: "executing", operation_id: "users.create", operation_version: action.operation.version, policy_version: 1,
|
|
generation: generation.toString("hex"), connection_generation: generation.toString("hex"), expires_at: new Date(expires), approved_by: null, owner_id: connection.owner_id, owner_permissions: connection.owner_permissions, owner_valid_until: connection.owner_valid_until, policy: connection.policy,
|
|
payload, evidence: encryptedEvidence, grants: [], protections: [], concurrent_reads: 0, result: null }
|
|
const grant = { proof: fingerprint({ credentialId: principal.credentialId, grant: null }), expiresAt: null, monotonicEnd: Infinity, admissionExpiresAt: expires, admissionMonotonicEnd: performance.now() + ttl }
|
|
const start = source.beginMcpOperationAdmission(principal), issued = await source.insertMcpOperationAdmission(client as never, start, planId, randomUUID(), grant)
|
|
return { id: issued.operation.id, principal, grant, input, evidence, admission: issued.admission }
|
|
}
|
|
const terminal = () => { row.operation_state = "applied"; row.plan_state = "completed"; row.result = { confirmedWrites: 2 } }
|
|
try {
|
|
await t.test("no ambient root, fake/copy tokens and unproved admission cannot mint", async () => {
|
|
await fixture(); const before = calls
|
|
await assert.rejects(source.captureMcpOperationExecutionOrigin()); await assert.rejects(source.readCurrentMcpOperationExecutionOrigin({}))
|
|
await assert.rejects(source.withMcpOperationExecutionOrigin({}, async () => { throw Error("must not enter") })); assert.equal(calls, before)
|
|
})
|
|
await t.test("publisher exposes whole private operation, fixed lifetime and deeply frozen multi-step evidence", async () => {
|
|
const f = await fixture(); let saved: unknown, signal: AbortSignal | undefined
|
|
await source.withMcpOperationExecutionOrigin(f.admission, async () => {
|
|
const token = await source.captureMcpOperationExecutionOrigin(); saved = token
|
|
const metadata = await source.readCurrentMcpOperationExecutionOrigin(token), lifetime = await source.inspectMcpOperationExecutionLifetime(token); signal = lifetime.signal
|
|
assert.equal(metadata.operationId, f.id); assert.equal(metadata.evidence.steps.length, 2); assert.deepEqual(metadata.privateInput, f.input); assert.deepEqual(metadata.resources, f.evidence.objects)
|
|
assert(!("stepIndex" in metadata)); assert(Object.isFrozen(metadata.evidence.steps)); assert.equal(lifetime.monotonicDeadline, (await source.inspectMcpOperationExecutionLifetime(token)).monotonicDeadline)
|
|
const before = calls; for (const fake of [{}, { ...token }, JSON.parse(JSON.stringify(token))]) await assert.rejects(source.readCurrentMcpOperationExecutionOrigin(fake)); assert.equal(calls, before)
|
|
terminal()
|
|
})
|
|
assert.equal(signal?.aborted, true); await assert.rejects(source.readCurrentMcpOperationExecutionOrigin(saved))
|
|
})
|
|
await t.test("late capture denied under each actual legacy ALS, existing root remains inspectable", async () => {
|
|
const f = await fixture()
|
|
await source.withMcpOperationExecutionOrigin(f.admission, async () => {
|
|
const token = await source.captureMcpOperationExecutionOrigin()
|
|
await withApplicationMutationLock(async () => { await assert.rejects(source.captureMcpOperationExecutionOrigin()); await source.readCurrentMcpOperationExecutionOrigin(token) })
|
|
await withConfigMutationLock([101, 102], async () => { await assert.rejects(source.captureMcpOperationExecutionOrigin()); await source.readCurrentMcpOperationExecutionOrigin(token) })
|
|
await withOperationConfigurationLockClient(client as never, () => {}, new AbortController().signal, async () => { await assert.rejects(source.captureMcpOperationExecutionOrigin()); await source.readCurrentMcpOperationExecutionOrigin(token) })
|
|
terminal()
|
|
})
|
|
})
|
|
await t.test("one-shot admitted dual workers cannot publish or enter legacy twice", async () => {
|
|
const f = await fixture(); let arrivals = 0, callbacks = 0
|
|
claimGate = async () => { arrivals++ }
|
|
const outcomes = await Promise.allSettled([0, 1].map(() => source.withMcpOperationExecutionOrigin(f.admission, async () => { callbacks++; terminal() })))
|
|
assert.equal(arrivals, 1); assert.equal(callbacks, 1); assert.equal(outcomes.filter(value => value.status === "rejected").length, 1); assert.equal(row.operation_state, "applied")
|
|
})
|
|
for (const kind of ["lost-own", "lost-other", "rows-only"] as const) await t.test(kind + " claim refuses before legacy callback, exact nonce owns cleanup", async () => {
|
|
const f = await fixture(), before = cleanups; fault = kind; let entered = false
|
|
await assert.rejects(source.withMcpOperationExecutionOrigin(f.admission, async () => { entered = true }))
|
|
assert.equal(entered, false); assert.equal(cleanups - before, kind === "lost-other" ? 0 : 1); assert.equal(row.operation_state, kind === "lost-other" ? "running" : "unknown")
|
|
})
|
|
await t.test("callback throw or nonterminal return closes only own running claim as unknown", async () => {
|
|
for (const fail of [false, true]) { const f = await fixture(), before = cleanups
|
|
const work = source.withMcpOperationExecutionOrigin(f.admission, async () => { if (fail) throw Error("Owned callback failed") })
|
|
if (fail) await assert.rejects(work); else await work
|
|
assert.equal(row.operation_state, "unknown"); assert.equal(cleanups, before + 1)
|
|
}
|
|
assert(audits > 0)
|
|
})
|
|
await t.test("same-byte directory clone and expired queued admission cannot revive or leave owned pending", async () => {
|
|
const f = await fixture(), cloneDirectory = await mkdtemp(join(parent, "mm-operation-root-clone-"))
|
|
try {
|
|
await writeFile(join(cloneDirectory, "access-generation"), generation); await writeFile(join(cloneDirectory, "encryption-key"), Buffer.alloc(32, 83))
|
|
process.env.MCP_STATE_DIR = cloneDirectory
|
|
await assert.rejects(source.withMcpOperationExecutionOrigin(f.admission, async () => { throw Error("must not run from clone") }))
|
|
assert.equal(row.operation_state, "unknown")
|
|
} finally { process.env.MCP_STATE_DIR = directory; assert.equal(dirname(await realpath(cloneDirectory)), parent); await rm(cloneDirectory, { recursive: true, force: true }) }
|
|
const expired = await fixture(500); await delay(550)
|
|
await assert.rejects(source.withMcpOperationExecutionOrigin(expired.admission, async () => { throw Error("must not run expired") })); assert.equal(row.operation_state, "unknown")
|
|
})
|
|
await t.test("current sealed source/claim nonce and current actor permission revoke retained root", async () => {
|
|
for (const fault of ["sealed", "nonce", "permission"] as const) { const f = await fixture()
|
|
await source.withMcpOperationExecutionOrigin(f.admission, async () => {
|
|
const token = await source.captureMcpOperationExecutionOrigin()
|
|
if (fault === "sealed") row.payload.sealed += "!"
|
|
if (fault === "nonce") { row.claim_nonce = randomUUID(); row.result = { [source.MCP_OPERATION_PRIVATE_CLAIM_KEY]: row.claim_nonce } }
|
|
if (fault === "permission") { connection.owner_permissions = []; row.owner_permissions = [] }
|
|
await assert.rejects(source.readCurrentMcpOperationExecutionOrigin(token))
|
|
})
|
|
}
|
|
})
|
|
await t.test("private nonce stripped from direct result and nested model/UI redaction; terminal results unchanged", async () => {
|
|
const value = { confirmedWrites: 2, [source.MCP_OPERATION_PRIVATE_CLAIM_KEY]: "PRIVATE-NONCE" }
|
|
assert.deepEqual(source.stripMcpOperationExecutionPrivateResult(value), { confirmedWrites: 2 })
|
|
assert.deepEqual(redact({ items: [{ result: value }], operation: { result: value } }), { items: [{ result: { confirmedWrites: 2 } }], operation: { result: { confirmedWrites: 2 } } })
|
|
assert(!JSON.stringify(redact(value)).includes("PRIVATE-NONCE")); assert.deepEqual(source.stripMcpOperationExecutionPrivateResult({ confirmedWrites: 2 }), { confirmedWrites: 2 })
|
|
})
|
|
} finally {
|
|
pool.query = actualQuery; pool.connect = actualConnect; process.env.MCP_STATE_DIR = prior; await closePool()
|
|
assert.equal(dirname(await realpath(directory)), parent); await rm(directory, { recursive: true, force: true })
|
|
}
|
|
})
|