@mcpose/audit 2.0.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +437 -28
  3. package/dist/chain.d.ts +49 -6
  4. package/dist/chain.d.ts.map +1 -1
  5. package/dist/chain.js +227 -28
  6. package/dist/chain.js.map +1 -1
  7. package/dist/index.d.ts +5 -2
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +3 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/middleware.d.ts +3 -1
  12. package/dist/middleware.d.ts.map +1 -1
  13. package/dist/middleware.js +416 -85
  14. package/dist/middleware.js.map +1 -1
  15. package/dist/sensitivity.d.ts +11 -2
  16. package/dist/sensitivity.d.ts.map +1 -1
  17. package/dist/sensitivity.js +18 -2
  18. package/dist/sensitivity.js.map +1 -1
  19. package/dist/signingKey.d.ts +8 -0
  20. package/dist/signingKey.d.ts.map +1 -1
  21. package/dist/signingKey.js +21 -4
  22. package/dist/signingKey.js.map +1 -1
  23. package/dist/subjectKeyStore.d.ts +17 -0
  24. package/dist/subjectKeyStore.d.ts.map +1 -0
  25. package/dist/subjectKeyStore.js +37 -0
  26. package/dist/subjectKeyStore.js.map +1 -0
  27. package/dist/types.d.ts +164 -18
  28. package/dist/types.d.ts.map +1 -1
  29. package/dist/verify.d.ts +24 -0
  30. package/dist/verify.d.ts.map +1 -0
  31. package/dist/verify.js +50 -0
  32. package/dist/verify.js.map +1 -0
  33. package/package.json +43 -15
  34. package/src/__tests__/chain.batch.test.ts +30 -0
  35. package/src/__tests__/chain.test.ts +399 -0
  36. package/src/__tests__/erasable.test.ts +499 -0
  37. package/src/__tests__/merkle-batch.middleware.test.ts +96 -0
  38. package/src/__tests__/middleware.http.test.ts +172 -0
  39. package/src/__tests__/middleware.robustness.test.ts +737 -0
  40. package/src/__tests__/middleware.test.ts +1121 -0
  41. package/src/__tests__/properties.test.ts +737 -0
  42. package/src/__tests__/sensitivity.test.ts +72 -0
  43. package/src/__tests__/signingKey.test.ts +76 -0
  44. package/src/chain.ts +317 -0
  45. package/src/index.ts +31 -0
  46. package/src/middleware.ts +690 -0
  47. package/src/sensitivity.ts +33 -0
  48. package/src/signingKey.ts +35 -0
  49. package/src/subjectKeyStore.ts +38 -0
  50. package/src/types.ts +281 -0
  51. package/src/verify.ts +76 -0
@@ -1,18 +1,59 @@
1
1
  import { createCipheriv, randomBytes, createHmac } from 'node:crypto';
2
- import { computeChainHash, computeMerkleProof, computeMerkleRoot, sha256hex } from './chain.js';
2
+ import { canonicalJson, chainPreimageFields, computeChainHash, computeMerkleRootAndProofs, sha256hex, stableStringify, } from './chain.js';
3
+ import { hasToolContent, markPassThroughObserver } from 'mcpose';
3
4
  // Domain-separation labels for subkey derivation. The version segment lets the
4
- // derivation scheme rotate without colliding with chains written under an old scheme.
5
- const DOMAIN_CHAIN = Buffer.from('mcpose/v1/chain');
6
- const DOMAIN_ENC = Buffer.from('mcpose/v1/enc');
7
- function aesEncrypt(plaintext, key) {
5
+ // derivation scheme rotate without colliding with chains written under an old
6
+ // scheme. v1 → v2: canonical-JSON preimages, signed full manifest,
7
+ // domain-separated Merkle, per-position event keys, AEAD-bound ciphertexts.
8
+ // See ADR-0003 and ADR-0004.
9
+ const DOMAIN_CHAIN = Buffer.from('mcpose/v2/chain');
10
+ const DOMAIN_ENC = Buffer.from('mcpose/v2/enc');
11
+ const DOMAIN_MANIFEST = 'mcpose/v2/manifest';
12
+ const DOMAIN_EVENT_KEY = 'mcpose/v2/eventkey\0';
13
+ const DOMAIN_AAD = 'mcpose/v2/aad\0';
14
+ // Erasable mode only (ADR-0018): keys the payload hashes so that destroying a
15
+ // subject key destroys confirmability along with decryptability. A new label
16
+ // for a new mechanism is additive within v2 — no existing label changes, and
17
+ // no default-mode event is derived under it.
18
+ const DOMAIN_HASH_KEY = 'mcpose/v2/hashkey';
19
+ function aesEncrypt(plaintext, key, aad) {
20
+ if (key.length !== 32) {
21
+ throw new RangeError(`aesEncrypt: expected a 32-byte key, got ${key.length}`);
22
+ }
8
23
  const iv = randomBytes(12);
9
- const cipher = createCipheriv('aes-256-gcm', key.subarray(0, 32), iv);
10
- const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
24
+ const cipher = createCipheriv('aes-256-gcm', key, iv);
25
+ cipher.setAAD(Buffer.from(aad));
26
+ const encrypted = Buffer.concat([
27
+ cipher.update(plaintext, 'utf8'),
28
+ cipher.final(),
29
+ ]);
11
30
  const tag = cipher.getAuthTag();
12
31
  return Buffer.concat([iv, tag, encrypted]).toString('base64');
13
32
  }
14
- function deriveEventKey(encRoot, eventId) {
15
- return createHmac('sha256', encRoot).update(eventId).digest();
33
+ /**
34
+ * Per-event AES key. Bound to session + position + event id so no two
35
+ * events can share a key even if a host reuses a ProxyContext (and with it
36
+ * a requestId) across calls.
37
+ */
38
+ function deriveEventKey(encRoot, sessionId, position, eventId) {
39
+ return createHmac('sha256', encRoot)
40
+ .update(`${DOMAIN_EVENT_KEY}${sessionId ?? ''}\0${position}\0${eventId}`)
41
+ .digest();
42
+ }
43
+ /**
44
+ * Payload hash for one event.
45
+ *
46
+ * Default mode: plain `sha256`, unchanged and unkeyed, so a replay verifier
47
+ * needs no key custody. Erasable mode: `HMAC-SHA256` under a subkey of the
48
+ * subject key, so an adversary holding a candidate payload cannot confirm it
49
+ * against an erased event's hash (ADR-0018). Both hash the same
50
+ * `stableStringify` bytes, so only the key changes.
51
+ */
52
+ function payloadHash(value, hashSubkey) {
53
+ const serialized = stableStringify(value);
54
+ return hashSubkey === undefined
55
+ ? sha256hex(serialized)
56
+ : createHmac('sha256', hashSubkey).update(serialized).digest('hex');
16
57
  }
17
58
  function anonymousIdentity() {
18
59
  return {
@@ -24,8 +65,29 @@ function anonymousIdentity() {
24
65
  source: 'custom',
25
66
  };
26
67
  }
68
+ function getRejectionReason(err) {
69
+ const data = err?.data;
70
+ return typeof data?.rejectionReason === 'string'
71
+ ? data.rejectionReason
72
+ : undefined;
73
+ }
27
74
  export function createAuditMiddleware(options) {
28
75
  const sessions = new Map();
76
+ // Drained sessions awaiting signature or delivery, retried by closeSession.
77
+ const sealed = new Map();
78
+ const includeRejections = options.includeRejections ?? true;
79
+ const closeDrainTimeoutMs = options.closeDrainTimeoutMs ?? 30_000;
80
+ const reportAuditError = options.onAuditError ?? ((err) => console.error(err));
81
+ // A throwing reporter is outside the audited call path too (#172): it must
82
+ // not replace a tool result, mask an upstream error, or abort a drain.
83
+ const onAuditError = (err, info) => {
84
+ try {
85
+ reportAuditError(err, info);
86
+ }
87
+ catch {
88
+ // Nothing left to report it to.
89
+ }
90
+ };
29
91
  // Private subkeys, derived once from the signing secret THROUGH the oracle with
30
92
  // domain separation. The provider never exposes raw key bytes, and keyId must
31
93
  // NOT be used as key material — keyId is a public identifier, published in
@@ -33,125 +95,394 @@ export function createAuditMiddleware(options) {
33
95
  // contract, hence a PRF suitable for key derivation.
34
96
  // chainKey — keys the per-entry HMAC chain (forgery resistance)
35
97
  // encRoot — root for per-event AES-256 keys (high-tier confidentiality)
36
- // Cache the promise so concurrent first calls share one derivation.
98
+ // Cache the promise so concurrent first calls share one derivation; a failed
99
+ // derivation clears the cache so a transient provider error is retryable.
37
100
  let subkeys;
38
- const deriveSubkeys = () => (subkeys ?? (subkeys = (async () => {
39
- const [chainKey, encRoot] = await Promise.all([
40
- options.signingKey.sign(DOMAIN_CHAIN),
41
- options.signingKey.sign(DOMAIN_ENC),
42
- ]);
43
- return { chainKey, encRoot };
44
- })()));
45
- const middleware = async (req, next, ctx) => {
46
- const { chainKey, encRoot } = await deriveSubkeys();
47
- const start = Date.now();
101
+ const deriveSubkeys = () => {
102
+ subkeys ??= (async () => {
103
+ const [chainKey, encRoot] = await Promise.all([
104
+ options.signingKey.sign(DOMAIN_CHAIN),
105
+ options.signingKey.sign(DOMAIN_ENC),
106
+ ]);
107
+ return { chainKey, encRoot };
108
+ })();
109
+ subkeys.catch(() => {
110
+ subkeys = undefined;
111
+ });
112
+ return subkeys;
113
+ };
114
+ // One implementation for both audited surfaces. A tool call and a prompt
115
+ // fetch differ only in the event's `kind`: both requests carry a name and
116
+ // optional arguments, and both share the session chain, so duplicating the
117
+ // body would duplicate every invariant below with it (ADR-0014).
118
+ const observe = async (kind, req, next, ctx, isInBandError) => {
119
+ // The proxy identity is a required covered field (ADR-0019), so a context
120
+ // without one cannot produce a verifiable event. That is a configuration
121
+ // error rather than a runtime condition: core has stamped `ctx.proxy` on
122
+ // every ProxyContext since 3.0.0, so reaching here without it means a host
123
+ // invoked this middleware with a hand-built context.
124
+ //
125
+ // Handled here, at the pre-call stage alongside subkey derivation, which is
126
+ // the one failure point allowed to fail the call. Throwing after the call
127
+ // would mask the tool result, and substituting a sentinel identity would
128
+ // write a trail that looks attributed and is not, which is the failure
129
+ // #85 and #122 exist to prevent.
130
+ const proxy = ctx.proxy;
131
+ if (proxy === undefined) {
132
+ throw new Error('mcpose/audit: ctx.proxy is required, because the proxy identity is a covered field of every audit event. mcpose core stamps it on every ProxyContext; a host invoking this middleware with its own context must supply it.');
133
+ }
48
134
  const identity = ctx.identity ?? anonymousIdentity();
49
135
  const sessionId = ctx.sessionId;
136
+ const tool = req.params.name;
137
+ const args = req.params.arguments ?? {};
50
138
  if (sessionId && !sessions.has(sessionId)) {
139
+ // First-seen wins: the manifest records the proxy identity of the
140
+ // request that opened the session, and each event still records its own.
141
+ // No backfill branch is needed now that `proxy` is always present.
51
142
  sessions.set(sessionId, {
52
143
  events: [],
53
144
  prevChainHash: '',
54
145
  startedAt: new Date().toISOString(),
55
146
  identity,
147
+ proxy,
148
+ inflight: new Map(),
56
149
  });
57
150
  }
151
+ // Admission (#168): registered synchronously, before the first await of
152
+ // this function, and captured once. From here until the `finally` below
153
+ // the call counts as in flight: `closeSession` drains that set before it
154
+ // seals, so the session cannot vanish under a call that is still deriving
155
+ // keys, awaiting the upstream, or persisting its event. Re-resolving the
156
+ // id after an await is what produced position-0 orphans with no manifest.
58
157
  const session = sessionId ? sessions.get(sessionId) : undefined;
59
- const position = session?.events.length ?? 0;
60
- const tool = req.params.name;
61
- const args = req.params.arguments ?? {};
62
- const tier = options.sensitivityResolver(tool, identity, args);
63
- let outcome = 'success';
64
- let result;
65
- let threw = false;
158
+ const admission = Symbol(tool);
159
+ session?.inflight.set(admission, { tool, requestId: ctx.requestId });
66
160
  try {
67
- result = await next(req);
68
- }
69
- catch (err) {
70
- outcome = 'error';
71
- threw = true;
72
- result = undefined;
73
- const event = buildEvent({
74
- ctx, identity, tool, args, result: undefined,
75
- duration_ms: Date.now() - start, outcome, position,
76
- prevChainHash: session?.prevChainHash ?? '',
77
- tier, chainKey, encRoot,
78
- });
79
- advanceSession(session, event);
80
- await options.onEvent(event);
81
- throw err;
161
+ // Subkey derivation runs BEFORE the upstream call: if the signing
162
+ // provider is unavailable the call fails fast rather than running
163
+ // unaudited.
164
+ const { chainKey, encRoot } = await deriveSubkeys();
165
+ // Erasable mode (ADR-0018). Fetched at the pre-call stage alongside subkey
166
+ // derivation, for the same reason: without the subject key there is no way
167
+ // to record this event, so the call fails fast rather than running
168
+ // unaudited. Nothing is cached across calls — `destroy` must take effect
169
+ // immediately, and a subject that calls again after erasure gets a fresh
170
+ // key from the store rather than a stale one from here. A rejected fetch
171
+ // therefore leaves no poisoned state and the next call retries.
172
+ //
173
+ // The subject is the RESOLVED identity's `sub`, so anonymous events all
174
+ // land in the `anonymousIdentity()` bucket, which is the designated
175
+ // single bucket the ADR calls for.
176
+ // Written as a ternary rather than `await options.keyStore?.…` so default
177
+ // mode does not even take the extra microtask tick an `await undefined`
178
+ // would cost it.
179
+ const subjectKey = options.keyStore
180
+ ? await options.keyStore.getOrCreate(identity.sub)
181
+ : undefined;
182
+ const startedAt = new Date().toISOString();
183
+ const start = performance.now();
184
+ let result;
185
+ let thrown;
186
+ let threw = false;
187
+ try {
188
+ result = await next(req);
189
+ }
190
+ catch (err) {
191
+ thrown = err;
192
+ threw = true;
193
+ }
194
+ // Post-call audit section. Two invariants:
195
+ // 1. Atomic append — no `await` between reading the position and
196
+ // pushing the event, so concurrent calls in one session cannot
197
+ // allocate duplicate positions (buildEvent is fully synchronous).
198
+ // 2. Never throws — an audit failure is reported via onAuditError and
199
+ // must not fail (or mask the failure of) the audited call itself.
200
+ try {
201
+ const rejectionReason = threw ? getRejectionReason(thrown) : undefined;
202
+ // A call can fail without throwing: an MCP tool reports failure
203
+ // in-band with `isError: true` (#171). The caller supplies the
204
+ // predicate, so only tool calls pass one and prompts never match.
205
+ const inBandError = !threw && isInBandError?.(result) === true;
206
+ const outcome = rejectionReason !== undefined
207
+ ? 'rejected'
208
+ : threw || inBandError
209
+ ? 'error'
210
+ : 'success';
211
+ if (outcome !== 'rejected' || includeRejections) {
212
+ let tier;
213
+ try {
214
+ tier = options.sensitivityResolver(tool, identity, args);
215
+ }
216
+ catch (err) {
217
+ onAuditError(err, {
218
+ tool,
219
+ requestId: ctx.requestId,
220
+ ...(sessionId === undefined ? {} : { sessionId }),
221
+ });
222
+ tier = 'high';
223
+ }
224
+ const position = session?.events.length ?? 0;
225
+ const event = buildEvent({
226
+ ctx,
227
+ identity,
228
+ proxy,
229
+ kind,
230
+ tool,
231
+ args,
232
+ result: threw ? undefined : result,
233
+ startedAt,
234
+ endedAt: new Date().toISOString(),
235
+ duration_ms: Math.round(performance.now() - start),
236
+ outcome,
237
+ rejectionReason,
238
+ error: outcome !== 'error'
239
+ ? undefined
240
+ : threw
241
+ ? {
242
+ name: thrown instanceof Error ? thrown.name : 'Error',
243
+ message: thrown instanceof Error
244
+ ? thrown.message
245
+ : String(thrown),
246
+ }
247
+ : // A fixed message: `error` is never encrypted, so copying the
248
+ // tool's own text here would leak a high-tier payload.
249
+ {
250
+ name: 'ToolError',
251
+ message: 'Tool result returned isError: true',
252
+ },
253
+ position,
254
+ prevChainHash: session?.prevChainHash ?? '',
255
+ tier,
256
+ chainKey,
257
+ encRoot,
258
+ subjectKey,
259
+ });
260
+ if (session) {
261
+ session.events.push(event);
262
+ session.prevChainHash = event.chainHash;
263
+ }
264
+ await options.onEvent(event);
265
+ }
266
+ }
267
+ catch (err) {
268
+ onAuditError(err, {
269
+ tool,
270
+ requestId: ctx.requestId,
271
+ ...(sessionId === undefined ? {} : { sessionId }),
272
+ });
273
+ }
274
+ if (threw)
275
+ throw thrown;
276
+ return result;
82
277
  }
83
- if (!threw) {
84
- const event = buildEvent({
85
- ctx, identity, tool, args, result,
86
- duration_ms: Date.now() - start, outcome, position,
87
- prevChainHash: session?.prevChainHash ?? '',
88
- tier, chainKey, encRoot,
89
- });
90
- advanceSession(session, event);
91
- await options.onEvent(event);
278
+ finally {
279
+ // Settle after the event is appended and `onEvent` has settled, so a
280
+ // draining close also waits for pending persistence. A pre-call failure
281
+ // lands here too, so a rejected key fetch never leaves the session
282
+ // looking busy.
283
+ if (session) {
284
+ session.inflight.delete(admission);
285
+ if (session.inflight.size === 0)
286
+ session.onDrained?.();
287
+ }
92
288
  }
93
- return result;
94
289
  };
95
- const closeSession = async (sessionId) => {
290
+ // Tool calls: wrapped so `passThroughTools` stay audited. Prompts have no
291
+ // pass-through concept, so the prompt middleware needs no wrapper.
292
+ const inner = (req, next, ctx) => observe(undefined, req, next, ctx, (result) => hasToolContent(result) && result.isError === true);
293
+ const middleware = markPassThroughObserver(inner);
294
+ const promptMiddleware = (req, next, ctx) => observe('prompt', req, next, ctx);
295
+ const closeSession = (sessionId) => {
96
296
  const session = sessions.get(sessionId);
97
- if (!session || session.events.length === 0)
98
- return undefined;
297
+ if (session) {
298
+ // A close already in progress is the close: joining it is what keeps a
299
+ // DELETE that races a TTL expiry from signing two manifests.
300
+ session.closing ??= sealSession(sessionId, session);
301
+ return session.closing;
302
+ }
303
+ // Sealed but undelivered: a signer or sink failed on an earlier close.
304
+ // Retry from where it stopped instead of reporting the session unknown.
305
+ const pending = sealed.get(sessionId);
306
+ if (pending)
307
+ return finalize(sessionId, pending);
308
+ return Promise.resolve(undefined);
309
+ };
310
+ const sealSession = async (sessionId, session) => {
311
+ // Drain: every admitted call appends its event before it settles, so the
312
+ // manifest sealed below covers them all with continuous positions. The
313
+ // loop re-checks because a call can be admitted while one drain waits.
314
+ // Bounded, because a handler or sink that never settles must not hold
315
+ // the session's already-recorded events unsigned forever: past the
316
+ // deadline the manifest seals what it has and each straggler is reported.
317
+ const deadline = performance.now() + closeDrainTimeoutMs;
318
+ while (session.inflight.size > 0) {
319
+ const remaining = deadline - performance.now();
320
+ if (remaining <= 0) {
321
+ for (const { tool, requestId } of session.inflight.values()) {
322
+ onAuditError(new Error(`mcpose/audit: closeSession(${sessionId}) sealed after ${closeDrainTimeoutMs} ms with this call still in flight; its event is not in the manifest`), { tool, requestId, sessionId });
323
+ }
324
+ break;
325
+ }
326
+ await new Promise((resolve) => {
327
+ const timer = Number.isFinite(remaining)
328
+ ? setTimeout(resolve, remaining)
329
+ : undefined;
330
+ session.onDrained = () => {
331
+ if (timer !== undefined)
332
+ clearTimeout(timer);
333
+ resolve();
334
+ };
335
+ });
336
+ }
337
+ delete session.onDrained;
338
+ // Sealed: the session leaves the admission map here, so no later call can
339
+ // append to a manifest that is already being signed. What follows can
340
+ // still fail, so the sealed state is kept until delivery succeeds (#169).
99
341
  sessions.delete(sessionId);
342
+ if (session.events.length === 0)
343
+ return undefined;
100
344
  const hashes = session.events.map((e) => e.chainHash);
101
- const merkleRoot = computeMerkleRoot(hashes);
102
- const merkleProofs = hashes.map((_, i) => computeMerkleProof(hashes, i));
103
- const signature = (await options.signingKey.sign(Buffer.from(merkleRoot))).toString('hex');
104
- const manifest = {
345
+ const { merkleRoot, merkleProofs } = computeMerkleRootAndProofs(hashes);
346
+ // The signature covers the ENTIRE manifest (domain-separated, canonical
347
+ // serialization) — signing only the Merkle root would leave sessionId,
348
+ // identity, eventCount, and the proofs swappable after the fact.
349
+ const unsigned = {
105
350
  sessionId,
106
351
  identity: session.identity,
352
+ proxy: session.proxy,
107
353
  startedAt: session.startedAt,
108
354
  closedAt: new Date().toISOString(),
109
355
  eventCount: session.events.length,
110
356
  merkleRoot,
111
357
  merkleProofs,
112
358
  signedBy: options.signingKey.keyId,
113
- signature,
114
359
  };
115
- await options.onManifest?.(manifest);
116
- return manifest;
360
+ const previous = sealed.get(sessionId);
361
+ if (previous) {
362
+ // The id was reused before the earlier session's manifest was delivered.
363
+ // The host had every chance to retry; keeping the newer one is the only
364
+ // choice that does not lose the session that is closing now.
365
+ onAuditError(new Error(`mcpose/audit: closeSession(${sessionId}) replaced an undelivered manifest for an earlier session with the same id`), { tool: '', requestId: '', sessionId });
366
+ }
367
+ const pending = { unsigned };
368
+ sealed.set(sessionId, pending);
369
+ return finalize(sessionId, pending);
117
370
  };
118
- return { middleware, closeSession };
371
+ /**
372
+ * Signs and delivers a sealed manifest. Each step is memoized on the sealed
373
+ * state, so a retry after a transient signer failure signs the same payload
374
+ * (same `closedAt`, so the same bytes) and a retry after a sink failure
375
+ * re-delivers the identical signed manifest rather than minting a second
376
+ * one. Concurrent retries share one attempt.
377
+ */
378
+ const finalize = (sessionId, pending) => {
379
+ pending.attempt ??= (async () => {
380
+ try {
381
+ if (pending.signature === undefined) {
382
+ const payload = canonicalJson({
383
+ domain: DOMAIN_MANIFEST,
384
+ manifest: pending.unsigned,
385
+ });
386
+ pending.signature = (await options.signingKey.sign(Buffer.from(payload))).toString('hex');
387
+ }
388
+ const manifest = {
389
+ ...pending.unsigned,
390
+ signature: pending.signature,
391
+ };
392
+ await options.onManifest?.(manifest);
393
+ sealed.delete(sessionId);
394
+ return manifest;
395
+ }
396
+ finally {
397
+ delete pending.attempt;
398
+ }
399
+ })();
400
+ return pending.attempt;
401
+ };
402
+ return { middleware, promptMiddleware, closeSession };
119
403
  }
120
- // ── Helpers ────────────────────────────────────────────────────────────────────
121
- function advanceSession(session, event) {
122
- if (!session)
123
- return;
124
- session.events.push(event);
125
- session.prevChainHash = event.chainHash;
404
+ /** Rebuilds the exact signed payload for a manifest (used by verifiers). */
405
+ export function manifestSigningPayload(manifest) {
406
+ const { sessionId, identity, proxy, startedAt, closedAt, eventCount, merkleRoot, merkleProofs, signedBy, } = manifest;
407
+ return canonicalJson({
408
+ domain: DOMAIN_MANIFEST,
409
+ manifest: {
410
+ sessionId,
411
+ identity,
412
+ // Required covered field, included unconditionally (ADR-0019). Under
413
+ // the omission pattern a manifest with `proxy` stripped rebuilt the
414
+ // same payload as one that never had it, so the signature could not
415
+ // detect the removal.
416
+ proxy,
417
+ startedAt,
418
+ closedAt,
419
+ eventCount,
420
+ merkleRoot,
421
+ merkleProofs,
422
+ signedBy,
423
+ },
424
+ });
126
425
  }
426
+ /** Fully synchronous — position allocation relies on that (no await between read and append). */
127
427
  function buildEvent(p) {
128
- const stableFields = {
428
+ // Fail CLOSED: only explicit low/medium get plaintext; any other tier
429
+ // value — including garbage from a user-supplied resolver — encrypts.
430
+ // Decided before the preimage is built, because the tier is a covered
431
+ // field and must be the one the event actually ships with (ADR-0015).
432
+ const sensitivityTier = p.tier === 'low' || p.tier === 'medium' ? p.tier : 'high';
433
+ // Erasable mode: one subkey off the subject key keys both payload hashes.
434
+ // Derived per event rather than held anywhere, so it dies with the subject
435
+ // key it came from (ADR-0018).
436
+ const hashSubkey = p.subjectKey === undefined
437
+ ? undefined
438
+ : createHmac('sha256', p.subjectKey).update(DOMAIN_HASH_KEY).digest();
439
+ const withoutChainHash = {
129
440
  id: p.ctx.requestId,
130
- timestamp: new Date().toISOString(),
441
+ startedAt: p.startedAt,
442
+ endedAt: p.endedAt,
131
443
  ...(p.ctx.sessionId !== undefined ? { sessionId: p.ctx.sessionId } : {}),
132
- ...(p.ctx.delegatedFrom !== undefined ? { delegatedFrom: p.ctx.delegatedFrom } : {}),
444
+ ...(p.ctx.delegatedFrom !== undefined
445
+ ? { delegatedFrom: p.ctx.delegatedFrom }
446
+ : {}),
447
+ proxy: p.proxy,
448
+ ...(p.kind !== undefined ? { kind: p.kind } : {}),
449
+ // Optional covered field under the ADR-0012 omission rule, exactly as
450
+ // `kind` is: default-mode events do not carry the key at all, so their
451
+ // preimage is unchanged (ADR-0018).
452
+ ...(p.subjectKey !== undefined ? { erasable: true } : {}),
133
453
  identity: p.identity,
134
454
  tool: p.tool,
135
455
  duration_ms: p.duration_ms,
136
456
  outcome: p.outcome,
137
- inputHash: sha256hex(JSON.stringify(p.args)),
138
- outputHash: sha256hex(JSON.stringify(p.result ?? null)),
457
+ sensitivityTier,
458
+ ...(p.rejectionReason !== undefined
459
+ ? { rejectionReason: p.rejectionReason }
460
+ : {}),
461
+ ...(p.error !== undefined ? { error: p.error } : {}),
462
+ inputHash: payloadHash(p.args, hashSubkey),
463
+ outputHash: payloadHash(p.result ?? null, hashSubkey),
139
464
  replayManifestPosition: p.position,
140
465
  };
141
- const chainHash = computeChainHash(stableFields, p.prevChainHash, p.chainKey);
142
- const base = { ...stableFields, chainHash };
143
- if (p.tier === 'high') {
144
- const eventKey = deriveEventKey(p.encRoot, base.id);
466
+ const chainHash = computeChainHash(chainPreimageFields(withoutChainHash), p.prevChainHash, p.chainKey);
467
+ const base = { ...withoutChainHash, chainHash };
468
+ if (sensitivityTier !== 'high') {
145
469
  return {
146
470
  ...base,
147
- sensitivityTier: 'high',
148
- inputEncrypted: aesEncrypt(JSON.stringify(p.args), eventKey),
149
- outputEncrypted: aesEncrypt(JSON.stringify(p.result ?? null), eventKey),
471
+ sensitivityTier,
472
+ inputRaw: p.args,
473
+ outputRaw: p.result,
150
474
  };
151
475
  }
152
- if (p.tier === 'medium') {
153
- return { ...base, sensitivityTier: 'medium', inputRaw: p.args, outputRaw: p.result };
154
- }
155
- return { ...base, sensitivityTier: 'low', inputRaw: p.args, outputRaw: p.result };
476
+ // Erasable mode swaps the ROOT and nothing else: same label, same session,
477
+ // position and event-id inputs, same AES-256-GCM layout and AAD. Only the
478
+ // key's provenance changes, from the pure-derived `encRoot` to the stored,
479
+ // destroyable subject key (ADR-0018).
480
+ const eventKey = deriveEventKey(p.subjectKey ?? p.encRoot, p.ctx.sessionId, p.position, base.id);
481
+ return {
482
+ ...base,
483
+ sensitivityTier: 'high',
484
+ inputEncrypted: aesEncrypt(stableStringify(p.args), eventKey, `${DOMAIN_AAD}${base.id}\0input`),
485
+ outputEncrypted: aesEncrypt(stableStringify(p.result ?? null), eventKey, `${DOMAIN_AAD}${base.id}\0output`),
486
+ };
156
487
  }
157
488
  //# sourceMappingURL=middleware.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,12 @@
1
- import type { SensitivityTier, SensitivityResolverFn } from './types.js';
2
- export declare function createSensitivityResolver(map: Record<string, SensitivityTier>, override?: SensitivityResolverFn): SensitivityResolverFn;
1
+ import type { SensitivityTier, SensitivityResolverFn, SensitivityOverrideFn } from './types.js';
2
+ /**
3
+ * Builds a resolver from a static tool→tier map, with an optional dynamic
4
+ * override that receives the map's resolution as its fourth argument.
5
+ *
6
+ * Unknown tools resolve to `'high'` (encrypt by default). The lookup uses
7
+ * `Object.hasOwn`, so prototype-inherited keys (a tool named `toString` or
8
+ * `constructor` — tool names are attacker-controlled) cannot bypass that
9
+ * default.
10
+ */
11
+ export declare function createSensitivityResolver(map: Record<string, SensitivityTier>, override?: SensitivityOverrideFn): SensitivityResolverFn;
3
12
  //# sourceMappingURL=sensitivity.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sensitivity.d.ts","sourceRoot":"","sources":["../src/sensitivity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEzE,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,EACpC,QAAQ,CAAC,EAAE,qBAAqB,GAC/B,qBAAqB,CAKvB"}
1
+ {"version":3,"file":"sensitivity.d.ts","sourceRoot":"","sources":["../src/sensitivity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAUpB;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,EACpC,QAAQ,CAAC,EAAE,qBAAqB,GAC/B,qBAAqB,CAMvB"}