@mcpose/audit 3.0.0 → 3.1.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.
- package/README.md +8 -5
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +94 -11
- package/dist/middleware.js.map +1 -1
- package/dist/types.d.ts +14 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +20 -4
- package/dist/verify.js.map +1 -1
- package/package.json +5 -5
- package/src/__tests__/chain.test.ts +34 -0
- package/src/__tests__/middleware.rejection.test.ts +183 -0
- package/src/__tests__/middleware.robustness.test.ts +72 -0
- package/src/__tests__/middleware.unusableResult.test.ts +141 -0
- package/src/__tests__/properties.test.ts +27 -0
- package/src/middleware.ts +102 -11
- package/src/types.ts +14 -8
- package/src/verify.ts +20 -4
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ This package exists for the harder problem: a record that stays credible when so
|
|
|
51
51
|
- **Subkeys derived through the signing oracle.** Chain and encryption keys derive from the signing secret with domain separation, never from the public key id ([ADR-0003](https://github.com/amir-gorji/mcpose/blob/main/docs/adr/0003-audit-subkeys-derived-from-signing-oracle.md)).
|
|
52
52
|
- **Optional erasable mode.** Supply a `SubjectKeyStore` and a subject's payloads become destroyable: `destroy(sub)` kills both decryptability and hash-confirmability for that subject, and the chain and manifest keep verifying ([ADR-0018](https://github.com/amir-gorji/mcpose/blob/main/docs/adr/0018-cryptographic-erasure-and-the-chain.md)). Omit it and nothing changes.
|
|
53
53
|
- **Never blocks the call path.** Audit failures (a throwing sink, unserializable payloads) are routed to `onAuditError`; the tool call always completes with its real result or error.
|
|
54
|
-
A throwing `onAuditError
|
|
54
|
+
A throwing `onAuditError`, or one that returns a rejected promise, is contained too, so a broken reporter cannot replace a tool result or mask an upstream error.
|
|
55
55
|
Three configuration errors are the deliberate exception, and all fail before the upstream is reached rather than after: an unavailable signing provider, a `ProxyContext` with no `proxy` identity, and an unavailable `SubjectKeyStore` in erasable mode.
|
|
56
56
|
Each would otherwise produce a record that cannot be verified or cannot be attributed, so the call fails instead of running unaudited.
|
|
57
57
|
A proxy built by `createProxyServer` always stamps `ctx.proxy`, so only a host that invokes the middleware with its own hand-built context needs to supply it.
|
|
@@ -291,8 +291,8 @@ Only the root the key comes from changes.
|
|
|
291
291
|
| `createSensitivityResolver(map, override?)` | Build a `SensitivityResolverFn`. Unknown or invalid tiers resolve to `high`. |
|
|
292
292
|
| `createDefaultSigningKeyProvider(secret)` | In-process HMAC-SHA256 `SigningKeyProvider`. |
|
|
293
293
|
| `createInMemorySubjectKeyStore()` | Reference `SubjectKeyStore` for [erasable mode](#erasable-mode-cryptographic-erasure). **Not durable**: development and tests only. |
|
|
294
|
-
| `verifyAuditChain(events, signingKey)` | **Keyed** chain verification: recomputes every `chainHash` and reports the first tampered index. An empty event list is invalid. |
|
|
295
|
-
| `verifyManifestSignature(manifest, signingKey)` | **Keyed** check of the full-manifest signature, in constant time. |
|
|
294
|
+
| `verifyAuditChain(events, signingKey)` | **Keyed** chain verification: recomputes every `chainHash` and reports the first tampered index. An empty event list is invalid. A stored `chainHash` must be the exact lowercase hex string; a respelling is a mismatch. |
|
|
295
|
+
| `verifyManifestSignature(manifest, signingKey)` | **Keyed** check of the full-manifest signature, in constant time. The stored `signature` must be the exact lowercase hex string; a respelling (uppercase, an appended character) does not verify, so an independent verifier that compares strings agrees with this one. |
|
|
296
296
|
| `computeMerkleRoot` · `computeMerkleProof` · `verifyMerkleProof` | Low-level Merkle helpers for independent verification. |
|
|
297
297
|
| `canonicalJson` · `stableStringify` | The canonical serializations the format is defined over, exported so third parties can write their own verifier. |
|
|
298
298
|
|
|
@@ -332,7 +332,7 @@ interface AuditOptions {
|
|
|
332
332
|
onAuditError?: (
|
|
333
333
|
err: unknown,
|
|
334
334
|
info: { tool: string; requestId: string; sessionId?: string },
|
|
335
|
-
) =>
|
|
335
|
+
) => unknown;
|
|
336
336
|
}
|
|
337
337
|
|
|
338
338
|
interface AuditMiddlewareHandle {
|
|
@@ -446,7 +446,10 @@ interface AuditEventBase {
|
|
|
446
446
|
tool: string; // the tool name, or the prompt name when kind is 'prompt'
|
|
447
447
|
duration_ms: number;
|
|
448
448
|
outcome: 'success' | 'rejected' | 'error';
|
|
449
|
-
/**
|
|
449
|
+
/**
|
|
450
|
+
* Present when outcome is 'rejected': a member of the `RejectionReason` union read from the
|
|
451
|
+
* MCP error's data field. An unrecognized value is recorded as outcome 'error' instead.
|
|
452
|
+
*/
|
|
450
453
|
rejectionReason?: RejectionReason;
|
|
451
454
|
/** Present when outcome is 'error': what the upstream call threw. */
|
|
452
455
|
error?: { name: string; message: string };
|
package/dist/middleware.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,qBAAqB,EACrB,YAAY,EACZ,cAAc,EAEf,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,qBAAqB,EACrB,YAAY,EACZ,cAAc,EAEf,MAAM,YAAY,CAAC;AA2LpB,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,YAAY,GACpB,qBAAqB,CA4avB;AAED,4EAA4E;AAC5E,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,GAC1C,MAAM,CA8BR"}
|
package/dist/middleware.js
CHANGED
|
@@ -65,10 +65,50 @@ function anonymousIdentity() {
|
|
|
65
65
|
source: 'custom',
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Every member of the closed `RejectionReason` union, as an own-key
|
|
70
|
+
* membership table.
|
|
71
|
+
*
|
|
72
|
+
* The union is a type, so it is erased at runtime and `err.data.rejectionReason`
|
|
73
|
+
* arrives as an unchecked string. The `Record` annotation is the drift guard in
|
|
74
|
+
* both directions: a member added to the union without a matching key here is a
|
|
75
|
+
* compile error, and so is a key that is not a member of the union.
|
|
76
|
+
*
|
|
77
|
+
* Core keeps its own copy for telemetry. This one is not imported from there
|
|
78
|
+
* because the `mcpose` peer range admits 3.0.0, which exports no runtime guard.
|
|
79
|
+
*/
|
|
80
|
+
const REJECTION_REASONS = {
|
|
81
|
+
TOOL_HIDDEN: true,
|
|
82
|
+
RESOURCE_HIDDEN: true,
|
|
83
|
+
BACKEND_UNROUTABLE: true,
|
|
84
|
+
POLICY_DENIED: true,
|
|
85
|
+
IDENTITY_UNRESOLVED: true,
|
|
86
|
+
CONSENT_MISSING: true,
|
|
87
|
+
SENSITIVITY_BLOCKED: true,
|
|
88
|
+
DELEGATION_INVALID: true,
|
|
89
|
+
BUDGET_EXCEEDED: true,
|
|
90
|
+
SESSION_LIMIT: true,
|
|
91
|
+
BODY_LIMIT: true,
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* The rejection reason this error carries, or `undefined` when it carries
|
|
95
|
+
* none.
|
|
96
|
+
*
|
|
97
|
+
* Fail CLOSED, like the sensitivity tier: a `rejectionReason` outside the
|
|
98
|
+
* union is not a governance rejection, so the call is recorded as an ordinary
|
|
99
|
+
* `error` that keeps the real name and message. Casting the string through
|
|
100
|
+
* instead would record a failure as a rejection with no `error` field, and
|
|
101
|
+
* chain the unvalidated value as a covered field, which is the identity-less
|
|
102
|
+
* `outputHash` weakness the structured `error` field exists to close
|
|
103
|
+
* (ADR-0004). Mirrors `createSensitivityResolver`.
|
|
104
|
+
*/
|
|
68
105
|
function getRejectionReason(err) {
|
|
69
106
|
const data = err?.data;
|
|
70
|
-
|
|
71
|
-
|
|
107
|
+
const reason = data?.rejectionReason;
|
|
108
|
+
// `Object.hasOwn`, not `in`: the reason is upstream-controlled, so a value
|
|
109
|
+
// like `constructor` must not pass as a member off the prototype.
|
|
110
|
+
return typeof reason === 'string' && Object.hasOwn(REJECTION_REASONS, reason)
|
|
111
|
+
? reason
|
|
72
112
|
: undefined;
|
|
73
113
|
}
|
|
74
114
|
export function createAuditMiddleware(options) {
|
|
@@ -77,12 +117,23 @@ export function createAuditMiddleware(options) {
|
|
|
77
117
|
const sealed = new Map();
|
|
78
118
|
const includeRejections = options.includeRejections ?? true;
|
|
79
119
|
const closeDrainTimeoutMs = options.closeDrainTimeoutMs ?? 30_000;
|
|
120
|
+
// `!(x >= 0)` rejects NaN too, which the `??` default above lets through:
|
|
121
|
+
// a NaN deadline never fires, so the drain this option exists to bound would
|
|
122
|
+
// wait for a call that never settles and leave the recorded events unsigned
|
|
123
|
+
// with nothing reported. Same form as `maxSessions` in core (#277).
|
|
124
|
+
if (!(closeDrainTimeoutMs >= 0)) {
|
|
125
|
+
throw new Error(`mcpose/audit: closeDrainTimeoutMs must be >= 0 or Infinity, got ${String(options.closeDrainTimeoutMs)}`);
|
|
126
|
+
}
|
|
80
127
|
const reportAuditError = options.onAuditError ?? ((err) => console.error(err));
|
|
81
|
-
// A throwing reporter is outside the audited call path too
|
|
82
|
-
// not replace a tool result, mask an upstream error,
|
|
128
|
+
// A throwing or rejecting reporter is outside the audited call path too
|
|
129
|
+
// (#172, #245): it must not replace a tool result, mask an upstream error,
|
|
130
|
+
// abort a drain, or leave an unobserved rejection that Node's default
|
|
131
|
+
// --unhandled-rejections=throw turns into a dead process.
|
|
83
132
|
const onAuditError = (err, info) => {
|
|
84
133
|
try {
|
|
85
|
-
reportAuditError(err, info)
|
|
134
|
+
Promise.resolve(reportAuditError(err, info)).catch(() => {
|
|
135
|
+
// Nothing left to report it to.
|
|
136
|
+
});
|
|
86
137
|
}
|
|
87
138
|
catch {
|
|
88
139
|
// Nothing left to report it to.
|
|
@@ -202,10 +253,32 @@ export function createAuditMiddleware(options) {
|
|
|
202
253
|
// A call can fail without throwing: an MCP tool reports failure
|
|
203
254
|
// in-band with `isError: true` (#171). The caller supplies the
|
|
204
255
|
// predicate, so only tool calls pass one and prompts never match.
|
|
205
|
-
|
|
256
|
+
//
|
|
257
|
+
// A result that is not an object is decided here too, and for the same
|
|
258
|
+
// reason: the predicate below narrows to a `CallToolResult` and a
|
|
259
|
+
// primitive has no `.content` to narrow on. A local tool handler that
|
|
260
|
+
// resolves to a string reaches the client as `-32602 Invalid
|
|
261
|
+
// tools/call result`, so recording it as a success would put a clean
|
|
262
|
+
// outcome, and no `error` field, in a signed chain covering a call the
|
|
263
|
+
// client saw fail. `isResultless` in core's telemetry draws the same
|
|
264
|
+
// line, so both record what the caller observed.
|
|
265
|
+
//
|
|
266
|
+
// A nullish result is decided here, BEFORE the predicate narrows it,
|
|
267
|
+
// because narrowing reads `.content` and a nullish value has none: a
|
|
268
|
+
// local tool handler with a missing `return` made the predicate throw,
|
|
269
|
+
// and that throw reached the `catch` below, which reports and moves on
|
|
270
|
+
// — so `buildEvent` never ran and the governed call reached the client
|
|
271
|
+
// as a failure and the trail not at all. The manifest that counted it
|
|
272
|
+
// still verified, a valid chain under a valid signature, one event
|
|
273
|
+
// short of the calls it claims to cover.
|
|
274
|
+
const noToolResult = !threw &&
|
|
275
|
+
(result === null ||
|
|
276
|
+
result === undefined ||
|
|
277
|
+
typeof result !== 'object');
|
|
278
|
+
const inBandError = !threw && !noToolResult && isInBandError?.(result) === true;
|
|
206
279
|
const outcome = rejectionReason !== undefined
|
|
207
280
|
? 'rejected'
|
|
208
|
-
: threw || inBandError
|
|
281
|
+
: threw || inBandError || noToolResult
|
|
209
282
|
? 'error'
|
|
210
283
|
: 'success';
|
|
211
284
|
if (outcome !== 'rejected' || includeRejections) {
|
|
@@ -246,10 +319,20 @@ export function createAuditMiddleware(options) {
|
|
|
246
319
|
}
|
|
247
320
|
: // A fixed message: `error` is never encrypted, so copying the
|
|
248
321
|
// tool's own text here would leak a high-tier payload.
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
322
|
+
noToolResult
|
|
323
|
+
? {
|
|
324
|
+
name: 'InvalidToolResult',
|
|
325
|
+
// `kind` decides the shape that was expected, and the
|
|
326
|
+
// message is plaintext, so it has to name the one that
|
|
327
|
+
// was actually missing.
|
|
328
|
+
message: kind === 'prompt'
|
|
329
|
+
? 'Prompt fetch resolved to a value that is not a GetPromptResult'
|
|
330
|
+
: 'Tool call resolved to a value that is not a CallToolResult',
|
|
331
|
+
}
|
|
332
|
+
: {
|
|
333
|
+
name: 'ToolError',
|
|
334
|
+
message: 'Tool result returned isError: true',
|
|
335
|
+
},
|
|
253
336
|
position,
|
|
254
337
|
prevChainHash: session?.prevChainHash ?? '',
|
|
255
338
|
tier,
|
package/dist/middleware.js.map
CHANGED
|
@@ -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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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -95,9 +95,11 @@ export interface AuditEventBase {
|
|
|
95
95
|
/** Present when outcome is 'rejected' (from the MCP error's data field). */
|
|
96
96
|
rejectionReason?: RejectionReason;
|
|
97
97
|
/**
|
|
98
|
-
* Present when outcome is 'error': what the upstream call threw, or
|
|
99
|
-
* `{ name: 'ToolError' }`
|
|
100
|
-
* `isError: true` in-band
|
|
98
|
+
* Present when outcome is 'error': what the upstream call threw, or a fixed
|
|
99
|
+
* message when the call failed without throwing -- `{ name: 'ToolError' }`
|
|
100
|
+
* for a tool result that carried `isError: true` in-band, and
|
|
101
|
+
* `{ name: 'InvalidToolResult' }` when the call resolved to a value that is
|
|
102
|
+
* not the shape its `kind` expects.
|
|
101
103
|
*/
|
|
102
104
|
error?: {
|
|
103
105
|
name: string;
|
|
@@ -151,7 +153,8 @@ export interface ReplayManifest {
|
|
|
151
153
|
/**
|
|
152
154
|
* HMAC over the canonical serialization of the ENTIRE manifest (every
|
|
153
155
|
* field above, domain-separated) — not just the Merkle root. Verify with
|
|
154
|
-
* `verifyManifestSignature
|
|
156
|
+
* `verifyManifestSignature`, which accepts only this exact lowercase hex
|
|
157
|
+
* string: a respelling (uppercase, an appended character) does not verify.
|
|
155
158
|
*/
|
|
156
159
|
signature: string;
|
|
157
160
|
}
|
|
@@ -198,22 +201,25 @@ export interface AuditOptions {
|
|
|
198
201
|
* to append and persist their events before it seals the manifest. Past
|
|
199
202
|
* the deadline the manifest covers what has landed, and each straggler is
|
|
200
203
|
* reported through `onAuditError` with its tool and requestId. `Infinity`
|
|
201
|
-
* waits without bound.
|
|
204
|
+
* waits without bound. Any other value (NaN, a negative number) is
|
|
205
|
+
* rejected at construction, because it would leave the drain with no
|
|
206
|
+
* deadline at all.
|
|
202
207
|
* @default 30_000
|
|
203
208
|
*/
|
|
204
209
|
closeDrainTimeoutMs?: number;
|
|
205
210
|
/**
|
|
206
211
|
* Called when the audit layer itself fails (event serialization, a
|
|
207
212
|
* throwing onEvent sink). The audit layer NEVER throws into the tool-call
|
|
208
|
-
* path; failures are reported here instead. If this hook itself throws
|
|
209
|
-
* the
|
|
213
|
+
* path; failures are reported here instead. If this hook itself throws or
|
|
214
|
+
* returns a rejected promise, the failure is contained and never reaches
|
|
215
|
+
* the caller either.
|
|
210
216
|
* @default console.error
|
|
211
217
|
*/
|
|
212
218
|
onAuditError?: (err: unknown, info: {
|
|
213
219
|
tool: string;
|
|
214
220
|
requestId: string;
|
|
215
221
|
sessionId?: string;
|
|
216
|
-
}) =>
|
|
222
|
+
}) => unknown;
|
|
217
223
|
}
|
|
218
224
|
export interface AuditMiddlewareHandle {
|
|
219
225
|
middleware: ToolMiddleware;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,cAAc,EACf,MAAM,QAAQ,CAAC;AAIhB,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAExD,MAAM,MAAM,qBAAqB,GAAG,CAClC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC1B,eAAe,CAAC;AAErB;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAClC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,eAAe,KACrB,eAAe,CAAC;AAIrB,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,aAAa,CAAC;CAC1B;AAID,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;;;OAQG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD;;;;;OAKG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;CAC1D;AAID,MAAM,WAAW,cAAc;IAC7B,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC3B;;;;;;;;OAQG;IACH,KAAK,EAAE,aAAa,CAAC;IACrB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;IAC1C,4EAA4E;IAC5E,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,cAAc,EACf,MAAM,QAAQ,CAAC;AAIhB,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAExD,MAAM,MAAM,qBAAqB,GAAG,CAClC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC1B,eAAe,CAAC;AAErB;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAClC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,eAAe,KACrB,eAAe,CAAC;AAIrB,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,aAAa,CAAC;CAC1B;AAID,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;;;OAQG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD;;;;;OAKG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;CAC1D;AAID,MAAM,WAAW,cAAc;IAC7B,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC3B;;;;;;;;OAQG;IACH,KAAK,EAAE,aAAa,CAAC;IACrB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;IAC1C,4EAA4E;IAC5E,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;;;;;OAMG;IACH,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG;IAC3C,eAAe,EAAE,KAAK,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,cAAc,GAAG;IAC9C,eAAe,EAAE,QAAQ,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG;IAC5C,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG,gBAAgB,GAAG,cAAc,CAAC;AAI3E,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;IACnB;;;;;;;;OAQG;IACH,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,kBAAkB,CAAC;IAC/B,mBAAmB,EAAE,qBAAqB,CAAC;IAC3C;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;;;;OASG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,CACb,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAC1D,OAAO,CAAC;CACd;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,cAAc,CAAC;IAC3B;;;;;OAKG;IACH,gBAAgB,EAAE,gBAAgB,CAAC;IACnC;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;CACtE"}
|
package/dist/verify.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAMpB,MAAM,MAAM,iBAAiB,GAC3B;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAMpB,MAAM,MAAM,iBAAiB,GAC3B;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAwBpE;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,UAAU,EAAE,kBAAkB,GAC7B,OAAO,CAAC,iBAAiB,CAAC,CA4B5B;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,kBAAkB,GAC7B,OAAO,CAAC,OAAO,CAAC,CAMlB"}
|
package/dist/verify.js
CHANGED
|
@@ -2,10 +2,26 @@ import { timingSafeEqual } from 'node:crypto';
|
|
|
2
2
|
import { chainPreimageFields, computeChainHash } from './chain.js';
|
|
3
3
|
import { manifestSigningPayload } from './middleware.js';
|
|
4
4
|
const DOMAIN_CHAIN = Buffer.from('mcpose/v2/chain');
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Canonical hex: lowercase, even length, hex digits only, non-empty. This
|
|
7
|
+
* is what the producer writes (`digest('hex')`), and the exact string a
|
|
8
|
+
* third-party verifier compares.
|
|
9
|
+
*/
|
|
10
|
+
const CANONICAL_HEX = /^(?:[0-9a-f]{2})+$/;
|
|
11
|
+
/**
|
|
12
|
+
* Compares a stored hex string against the recomputed value in constant
|
|
13
|
+
* time. The stored string must be canonical first: Node's hex decoder drops
|
|
14
|
+
* a trailing odd nibble and stops at the first non-hex character, so
|
|
15
|
+
* `sig + '0'`, `sig + 'z'` and `SIG` all decode to the stored bytes and would
|
|
16
|
+
* otherwise verify. The verifiers authenticate the stored string itself, not
|
|
17
|
+
* just its decoding, so two implementations agree on one artifact (#281).
|
|
18
|
+
*/
|
|
19
|
+
function hexEqual(storedHex, expectedHex) {
|
|
20
|
+
if (!CANONICAL_HEX.test(storedHex))
|
|
21
|
+
return false;
|
|
22
|
+
const a = Buffer.from(storedHex, 'hex');
|
|
23
|
+
const b = Buffer.from(expectedHex, 'hex');
|
|
24
|
+
return a.length === b.length && timingSafeEqual(a, b);
|
|
9
25
|
}
|
|
10
26
|
/**
|
|
11
27
|
* KEYED chain verification: recomputes every event's chainHash from its
|
package/dist/verify.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAM9C,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;AAKpD,SAAS,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAM9C,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;AAKpD;;;;GAIG;AACH,MAAM,aAAa,GAAG,oBAAoB,CAAC;AAE3C;;;;;;;GAOG;AACH,SAAS,QAAQ,CAAC,SAAiB,EAAE,WAAmB;IACtD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC;QAAE,OAAO,KAAK,CAAC;IACjD,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACxC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAC1C,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAA6B,EAC7B,UAA8B;IAE9B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAChE,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACrD,IAAI,aAAa,GAAG,EAAE,CAAC;IAEvB,KAAK,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QAC1C,IAAI,KAAK,CAAC,sBAAsB,KAAK,CAAC,EAAE,CAAC;YACvC,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,CAAC;gBACR,MAAM,EAAE,0BAA0B,KAAK,CAAC,sBAAsB,cAAc,CAAC,EAAE;aAChF,CAAC;QACJ,CAAC;QACD,MAAM,QAAQ,GAAG,gBAAgB,CAC/B,mBAAmB,CAAC,KAAK,CAAC,EAC1B,aAAa,EACb,QAAQ,CACT,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC;YACzC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC;QAClE,CAAC;QACD,aAAa,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,QAAwB,EACxB,UAA8B;IAE9B,MAAM,EAAE,SAAS,EAAE,GAAG,QAAQ,EAAE,GAAG,QAAQ,CAAC;IAC5C,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,IAAI,CACpC,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC,CAC9C,CAAC;IACF,OAAO,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AACvD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcpose/audit",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Integrity-chained audit middleware for mcpose — HMAC chain, Merkle proofs, ReplayManifest",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@stryker-mutator/core": "10.0.0",
|
|
51
51
|
"@stryker-mutator/vitest-runner": "10.0.0",
|
|
52
|
-
"@types/node": "^26.5
|
|
53
|
-
"@vitest/coverage-v8": "5.0.
|
|
52
|
+
"@types/node": "^26.6.5",
|
|
53
|
+
"@vitest/coverage-v8": "5.0.4",
|
|
54
54
|
"fast-check": "4.10.2",
|
|
55
55
|
"typescript": "6.0.3",
|
|
56
|
-
"vitest": "5.0.
|
|
57
|
-
"mcpose": "3.
|
|
56
|
+
"vitest": "5.0.4",
|
|
57
|
+
"mcpose": "3.1.0"
|
|
58
58
|
},
|
|
59
59
|
"scripts": {
|
|
60
60
|
"build": "tsc -p tsconfig.build.json",
|
|
@@ -241,6 +241,25 @@ describe('verifyAuditChain (keyed)', () => {
|
|
|
241
241
|
const result = await verifyAuditChain(events, otherKey);
|
|
242
242
|
expect(result.valid).toBe(false);
|
|
243
243
|
});
|
|
244
|
+
|
|
245
|
+
// Node's hex decoder drops a trailing odd nibble and stops at the first
|
|
246
|
+
// non-hex character, so these respellings decode to the stored bytes. The
|
|
247
|
+
// verifier authenticates the stored string, not just its decoding (#281).
|
|
248
|
+
it.each([
|
|
249
|
+
['an appended nibble', (h: string) => h + '0'],
|
|
250
|
+
['an appended non-hex character', (h: string) => h + 'z'],
|
|
251
|
+
['an uppercase respelling', (h: string) => h.toUpperCase()],
|
|
252
|
+
])('rejects a chainHash with %s', async (_label, respell) => {
|
|
253
|
+
const { events, signingKey } = await produceSession('s-respell', 3);
|
|
254
|
+
const respelled = events.map((e, i) =>
|
|
255
|
+
i === 1 ? { ...e, chainHash: respell(e.chainHash) } : e,
|
|
256
|
+
);
|
|
257
|
+
expect(await verifyAuditChain(respelled, signingKey)).toEqual({
|
|
258
|
+
valid: false,
|
|
259
|
+
index: 1,
|
|
260
|
+
reason: 'chainHash mismatch',
|
|
261
|
+
});
|
|
262
|
+
});
|
|
244
263
|
});
|
|
245
264
|
|
|
246
265
|
describe('sensitivityTier is covered by the chain (ADR-0015)', () => {
|
|
@@ -328,6 +347,21 @@ describe('verifyManifestSignature', () => {
|
|
|
328
347
|
const otherKey = createDefaultSigningKeyProvider('other-secret');
|
|
329
348
|
expect(await verifyManifestSignature(manifest, otherKey)).toBe(false);
|
|
330
349
|
});
|
|
350
|
+
|
|
351
|
+
// Same decoder leniency as above: a respelled signature must not verify,
|
|
352
|
+
// or a tool that indexes by the stored string disagrees with this one (#281).
|
|
353
|
+
it.each([
|
|
354
|
+
['an appended nibble', (h: string) => h + '0'],
|
|
355
|
+
['an appended non-hex character', (h: string) => h + 'z'],
|
|
356
|
+
['two appended non-hex characters', (h: string) => h + 'zz'],
|
|
357
|
+
['an uppercase respelling', (h: string) => h.toUpperCase()],
|
|
358
|
+
])('rejects a signature with %s', async (_label, respell) => {
|
|
359
|
+
const { manifest, signingKey } = await produceSession('m-respell', 3);
|
|
360
|
+
const respelled = { ...manifest, signature: respell(manifest.signature) };
|
|
361
|
+
expect(await verifyManifestSignature(respelled, signingKey)).toBe(false);
|
|
362
|
+
// Positive control: the untouched manifest still verifies.
|
|
363
|
+
expect(await verifyManifestSignature(manifest, signingKey)).toBe(true);
|
|
364
|
+
});
|
|
331
365
|
});
|
|
332
366
|
|
|
333
367
|
describe('domain label pinning', () => {
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import type * as http from 'node:http';
|
|
3
|
+
import { startHttpProxy } from 'mcpose';
|
|
4
|
+
import type { LocalTool } from 'mcpose';
|
|
5
|
+
import { createMockBackendClient } from 'mcpose/testing';
|
|
6
|
+
import { createAuditMiddleware } from '../middleware.js';
|
|
7
|
+
import { createDefaultSigningKeyProvider } from '../signingKey.js';
|
|
8
|
+
import { createSensitivityResolver } from '../sensitivity.js';
|
|
9
|
+
import { verifyAuditChain, verifyManifestSignature } from '../verify.js';
|
|
10
|
+
import type { AuditEvent, AuditOptions, ReplayManifest } from '../types.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A call that fails is only a `rejected` event when its error carries a
|
|
14
|
+
* member of the closed `RejectionReason` union.
|
|
15
|
+
*
|
|
16
|
+
* The failing call is a LOCAL tool handler (ADR-0007), so it runs inside the
|
|
17
|
+
* pipeline and the audit middleware observes it there, exactly as the tool
|
|
18
|
+
* call in the issue does. The error is shaped like an `McpError` from
|
|
19
|
+
* `rejectionMcpError()` without importing the SDK: the middleware
|
|
20
|
+
* duck-types `err.data.rejectionReason`.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const MESSAGE = 'ledger pool reset: no capacity';
|
|
24
|
+
|
|
25
|
+
const MCP_HEADERS = {
|
|
26
|
+
'Content-Type': 'application/json',
|
|
27
|
+
Accept: 'application/json, text/event-stream',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function port(server: http.Server): number {
|
|
31
|
+
const addr = server.address();
|
|
32
|
+
if (!addr || typeof addr === 'string') throw new Error('no port');
|
|
33
|
+
return addr.port;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** A local tool that always fails, carrying `reason` in the error's data. */
|
|
37
|
+
function failingLocalTool(reason: string): LocalTool {
|
|
38
|
+
return {
|
|
39
|
+
tool: { name: 'ledger_entry', inputSchema: { type: 'object' } },
|
|
40
|
+
handler: async () => {
|
|
41
|
+
throw Object.assign(new Error(MESSAGE), {
|
|
42
|
+
code: -32603,
|
|
43
|
+
data: { rejectionReason: reason },
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const signingKey = createDefaultSigningKeyProvider('test-secret');
|
|
50
|
+
|
|
51
|
+
async function harness(reason: string, overrides: Partial<AuditOptions> = {}) {
|
|
52
|
+
const events: AuditEvent[] = [];
|
|
53
|
+
const audit = createAuditMiddleware({
|
|
54
|
+
signingKey,
|
|
55
|
+
sensitivityResolver: createSensitivityResolver({ ledger_entry: 'low' }),
|
|
56
|
+
onEvent: (e) => void events.push(e),
|
|
57
|
+
...overrides,
|
|
58
|
+
});
|
|
59
|
+
const server = await startHttpProxy(
|
|
60
|
+
createMockBackendClient(),
|
|
61
|
+
{
|
|
62
|
+
name: 'audit-rejection-test',
|
|
63
|
+
localTools: [failingLocalTool(reason)],
|
|
64
|
+
toolMiddleware: [audit.middleware],
|
|
65
|
+
},
|
|
66
|
+
{ port: 0, path: '/mcp' },
|
|
67
|
+
);
|
|
68
|
+
const baseUrl = `http://localhost:${port(server)}/mcp`;
|
|
69
|
+
const init = await fetch(baseUrl, {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
headers: MCP_HEADERS,
|
|
72
|
+
body: JSON.stringify({
|
|
73
|
+
jsonrpc: '2.0',
|
|
74
|
+
id: 1,
|
|
75
|
+
method: 'initialize',
|
|
76
|
+
params: {
|
|
77
|
+
protocolVersion: '2024-11-05',
|
|
78
|
+
capabilities: {},
|
|
79
|
+
clientInfo: { name: 'test', version: '0.0.1' },
|
|
80
|
+
},
|
|
81
|
+
}),
|
|
82
|
+
});
|
|
83
|
+
await init.text();
|
|
84
|
+
const sessionId = init.headers.get('mcp-session-id')!;
|
|
85
|
+
expect(sessionId).toBeTruthy();
|
|
86
|
+
|
|
87
|
+
const call = await fetch(baseUrl, {
|
|
88
|
+
method: 'POST',
|
|
89
|
+
headers: { ...MCP_HEADERS, 'mcp-session-id': sessionId },
|
|
90
|
+
body: JSON.stringify({
|
|
91
|
+
jsonrpc: '2.0',
|
|
92
|
+
id: 2,
|
|
93
|
+
method: 'tools/call',
|
|
94
|
+
params: { name: 'ledger_entry', arguments: { amount: 10 } },
|
|
95
|
+
}),
|
|
96
|
+
});
|
|
97
|
+
await call.text();
|
|
98
|
+
const manifest: ReplayManifest | undefined =
|
|
99
|
+
await audit.closeSession(sessionId);
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
events,
|
|
103
|
+
manifest,
|
|
104
|
+
close: () => new Promise<void>((r) => server.close(() => r())),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
describe('rejection classification — only a RejectionReason member is a rejection (#238)', () => {
|
|
109
|
+
it('records an error carrying a reason outside the union as an error, with the real message', async () => {
|
|
110
|
+
const h = await harness('LEDGER_POOL_RESET');
|
|
111
|
+
try {
|
|
112
|
+
expect(h.events).toHaveLength(1);
|
|
113
|
+
const event = h.events[0]!;
|
|
114
|
+
expect(event.outcome).toBe('error');
|
|
115
|
+
// The unvalidated string is not a covered field of this event: an
|
|
116
|
+
// omitted key keeps the preimage the event has always had
|
|
117
|
+
// (ADR-0012), and the classification that ADR-0004's `error` field
|
|
118
|
+
// exists for is restored.
|
|
119
|
+
expect(Object.hasOwn(event, 'rejectionReason')).toBe(false);
|
|
120
|
+
expect(event.error).toEqual({ name: 'Error', message: MESSAGE });
|
|
121
|
+
expect(event.tool).toBe('ledger_entry');
|
|
122
|
+
expect(await verifyAuditChain(h.events, signingKey)).toEqual({
|
|
123
|
+
valid: true,
|
|
124
|
+
});
|
|
125
|
+
expect(h.manifest?.eventCount).toBe(1);
|
|
126
|
+
expect(await verifyManifestSignature(h.manifest!, signingKey)).toBe(true);
|
|
127
|
+
} finally {
|
|
128
|
+
await h.close();
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('records a reason inside the union as a rejection, unchanged', async () => {
|
|
133
|
+
const h = await harness('POLICY_DENIED');
|
|
134
|
+
try {
|
|
135
|
+
expect(h.events).toHaveLength(1);
|
|
136
|
+
const event = h.events[0]!;
|
|
137
|
+
expect(event.outcome).toBe('rejected');
|
|
138
|
+
expect(event.rejectionReason).toBe('POLICY_DENIED');
|
|
139
|
+
expect(Object.hasOwn(event, 'error')).toBe(false);
|
|
140
|
+
expect(await verifyAuditChain(h.events, signingKey)).toEqual({
|
|
141
|
+
valid: true,
|
|
142
|
+
});
|
|
143
|
+
} finally {
|
|
144
|
+
await h.close();
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('records a reason that is a prototype key as an error, not a rejection', async () => {
|
|
149
|
+
const h = await harness('constructor');
|
|
150
|
+
try {
|
|
151
|
+
expect(h.events).toHaveLength(1);
|
|
152
|
+
expect(h.events[0]!.outcome).toBe('error');
|
|
153
|
+
expect(Object.hasOwn(h.events[0]!, 'rejectionReason')).toBe(false);
|
|
154
|
+
} finally {
|
|
155
|
+
await h.close();
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('includeRejections: false still drops a rejection, and still records a non-member as an error', async () => {
|
|
160
|
+
const dropped = await harness('POLICY_DENIED', {
|
|
161
|
+
includeRejections: false,
|
|
162
|
+
});
|
|
163
|
+
try {
|
|
164
|
+
expect(dropped.events).toEqual([]);
|
|
165
|
+
} finally {
|
|
166
|
+
await dropped.close();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const recorded = await harness('LEDGER_POOL_RESET', {
|
|
170
|
+
includeRejections: false,
|
|
171
|
+
});
|
|
172
|
+
try {
|
|
173
|
+
expect(recorded.events).toHaveLength(1);
|
|
174
|
+
expect(recorded.events[0]!.outcome).toBe('error');
|
|
175
|
+
expect(recorded.events[0]!.error).toEqual({
|
|
176
|
+
name: 'Error',
|
|
177
|
+
message: MESSAGE,
|
|
178
|
+
});
|
|
179
|
+
} finally {
|
|
180
|
+
await recorded.close();
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
});
|
|
@@ -221,6 +221,53 @@ describe('createAuditMiddleware — never blocks the call path', () => {
|
|
|
221
221
|
expect(events[0]!.sensitivityTier).toBe('high');
|
|
222
222
|
});
|
|
223
223
|
|
|
224
|
+
it('an async onAuditError reporter that rejects does not fail a successful call (#245)', async () => {
|
|
225
|
+
// The reporter is observability (#172). An async reporter that rejects
|
|
226
|
+
// after its first await escapes the synchronous guard: nothing observes
|
|
227
|
+
// the rejection, so Node's default --unhandled-rejections=throw ends the
|
|
228
|
+
// process around the tool call it must not touch.
|
|
229
|
+
const rejections: unknown[] = [];
|
|
230
|
+
const onUnhandled = (reason: unknown): void => {
|
|
231
|
+
rejections.push(reason);
|
|
232
|
+
};
|
|
233
|
+
process.on('unhandledRejection', onUnhandled);
|
|
234
|
+
|
|
235
|
+
try {
|
|
236
|
+
// A plain async function, not a vi.fn spy: a spy attaches its own
|
|
237
|
+
// handler to the promise it returns to track settledResults, which
|
|
238
|
+
// would swallow the very rejection this test observes.
|
|
239
|
+
let reporterCalls = 0;
|
|
240
|
+
const onAuditError = async (): Promise<void> => {
|
|
241
|
+
reporterCalls += 1;
|
|
242
|
+
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
243
|
+
throw new Error('reporter down');
|
|
244
|
+
};
|
|
245
|
+
const { middleware } = createAuditMiddleware(
|
|
246
|
+
makeOptions({
|
|
247
|
+
onEvent: () => {
|
|
248
|
+
throw new Error('sink down');
|
|
249
|
+
},
|
|
250
|
+
onAuditError,
|
|
251
|
+
}),
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
await expect(
|
|
255
|
+
middleware(
|
|
256
|
+
makeReq('search'),
|
|
257
|
+
async () => ({ content: [{ type: 'text', text: 'ok' }] }),
|
|
258
|
+
makeCtx('s1'),
|
|
259
|
+
),
|
|
260
|
+
).resolves.toEqual({ content: [{ type: 'text', text: 'ok' }] });
|
|
261
|
+
expect(reporterCalls).toBe(1);
|
|
262
|
+
// One macrotask turn, so a rejection nobody adopted has surfaced as an
|
|
263
|
+
// unhandledRejection event by the time this asserts.
|
|
264
|
+
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
265
|
+
expect(rejections).toHaveLength(0);
|
|
266
|
+
} finally {
|
|
267
|
+
process.removeListener('unhandledRejection', onUnhandled);
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
|
|
224
271
|
it('circular and BigInt arguments still produce an event', async () => {
|
|
225
272
|
const events: AuditEvent[] = [];
|
|
226
273
|
const { middleware } = createAuditMiddleware(
|
|
@@ -522,6 +569,31 @@ describe('createAuditMiddleware — close during an in-flight call (#168)', () =
|
|
|
522
569
|
expect(await closeSession('s')).toBeUndefined();
|
|
523
570
|
});
|
|
524
571
|
|
|
572
|
+
// The bound is the whole reason this option exists. `packages/audit/README.md`
|
|
573
|
+
// says the wait is bounded and names `Infinity` as the only way to wait
|
|
574
|
+
// without bound, so a value that is neither -- NaN, which the `?? 30_000`
|
|
575
|
+
// default does not catch, or a negative number -- must not leave the drain
|
|
576
|
+
// with a deadline that never fires.
|
|
577
|
+
it('rejects a closeDrainTimeoutMs that cannot bound the drain', () => {
|
|
578
|
+
expect(() =>
|
|
579
|
+
createAuditMiddleware(
|
|
580
|
+
makeOptions({ closeDrainTimeoutMs: Number('not a duration') }),
|
|
581
|
+
),
|
|
582
|
+
).toThrow(/closeDrainTimeoutMs must be >= 0 or Infinity, got NaN/);
|
|
583
|
+
expect(() =>
|
|
584
|
+
createAuditMiddleware(makeOptions({ closeDrainTimeoutMs: -1 })),
|
|
585
|
+
).toThrow(/closeDrainTimeoutMs must be >= 0 or Infinity, got -1/);
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
it('accepts 0 and Infinity as the documented bounds', () => {
|
|
589
|
+
expect(() =>
|
|
590
|
+
createAuditMiddleware(makeOptions({ closeDrainTimeoutMs: 0 })),
|
|
591
|
+
).not.toThrow();
|
|
592
|
+
expect(() =>
|
|
593
|
+
createAuditMiddleware(makeOptions({ closeDrainTimeoutMs: Infinity })),
|
|
594
|
+
).not.toThrow();
|
|
595
|
+
});
|
|
596
|
+
|
|
525
597
|
it('concurrent closeSession calls share one manifest', async () => {
|
|
526
598
|
const { middleware, closeSession } = createAuditMiddleware(makeOptions());
|
|
527
599
|
const release = deferred();
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import { createAuditMiddleware } from '../middleware.js';
|
|
3
|
+
import { createDefaultSigningKeyProvider } from '../signingKey.js';
|
|
4
|
+
import { createSensitivityResolver } from '../sensitivity.js';
|
|
5
|
+
import { verifyAuditChain, verifyManifestSignature } from '../verify.js';
|
|
6
|
+
import type { AuditEvent, AuditOptions } from '../types.js';
|
|
7
|
+
import { createProxyContext } from 'mcpose';
|
|
8
|
+
import type { Identity } from 'mcpose';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A call that neither throws nor produces a tool result is a failed call, and
|
|
12
|
+
* the trail has to say so.
|
|
13
|
+
*
|
|
14
|
+
* `hasToolContent` narrows the pipeline's result and reads `.content` on the
|
|
15
|
+
* way, so a nullish one used to throw inside the post-call section — whose
|
|
16
|
+
* only handler reports and moves on. `buildEvent` never ran, so a governed
|
|
17
|
+
* call that failed reached the client and never reached the trail, while the
|
|
18
|
+
* manifest that counted it still verified: a valid chain under a valid
|
|
19
|
+
* signature, short one event of the calls it claims to cover.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
const identity: Identity = {
|
|
23
|
+
sub: 'user-1',
|
|
24
|
+
type: 'human',
|
|
25
|
+
roles: ['analyst'],
|
|
26
|
+
claims: {},
|
|
27
|
+
resolvedAt: '2026-06-01T00:00:00.000Z',
|
|
28
|
+
source: 'jwt',
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const signingKey = createDefaultSigningKeyProvider('test-secret');
|
|
32
|
+
|
|
33
|
+
function makeCtx(sessionId: string) {
|
|
34
|
+
return createProxyContext({
|
|
35
|
+
transport: 'http',
|
|
36
|
+
identity,
|
|
37
|
+
sessionId,
|
|
38
|
+
proxy: { name: 'test-proxy', version: '0.0.0' },
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function makeReq(tool: string) {
|
|
43
|
+
return {
|
|
44
|
+
method: 'tools/call' as const,
|
|
45
|
+
params: { name: tool, arguments: {} },
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function makeOptions(events: AuditEvent[]): AuditOptions {
|
|
50
|
+
return {
|
|
51
|
+
signingKey,
|
|
52
|
+
sensitivityResolver: createSensitivityResolver({ search: 'low' }),
|
|
53
|
+
onEvent: (e) => void events.push(e),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
describe('a pipeline that resolves without a tool result', () => {
|
|
58
|
+
for (const [label, value] of [
|
|
59
|
+
['undefined', undefined],
|
|
60
|
+
['null', null],
|
|
61
|
+
['a string', 'all good'],
|
|
62
|
+
['the number 0', 0],
|
|
63
|
+
] as const) {
|
|
64
|
+
it(`records the call as an error when the pipeline resolves to ${label}`, async () => {
|
|
65
|
+
const events: AuditEvent[] = [];
|
|
66
|
+
const handle = createAuditMiddleware(makeOptions(events));
|
|
67
|
+
|
|
68
|
+
await handle.middleware(
|
|
69
|
+
makeReq('search'),
|
|
70
|
+
async () => value as never,
|
|
71
|
+
makeCtx(`sess-${label}`),
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
expect(events).toHaveLength(1);
|
|
75
|
+
const event = events[0]!;
|
|
76
|
+
expect(event.outcome).toBe('error');
|
|
77
|
+
expect(event.error).toEqual({
|
|
78
|
+
name: 'InvalidToolResult',
|
|
79
|
+
message: 'Tool call resolved to a value that is not a CallToolResult',
|
|
80
|
+
});
|
|
81
|
+
expect(event.replayManifestPosition).toBe(0);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
it('names the shape a prompt fetch was expected to return', async () => {
|
|
86
|
+
const events: AuditEvent[] = [];
|
|
87
|
+
const { promptMiddleware } = createAuditMiddleware(makeOptions(events));
|
|
88
|
+
|
|
89
|
+
await promptMiddleware(
|
|
90
|
+
{ method: 'prompts/get' as const, params: { name: 'greet' } },
|
|
91
|
+
async () => undefined as never,
|
|
92
|
+
makeCtx('sess-prompt'),
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
expect(events).toHaveLength(1);
|
|
96
|
+
const event = events[0]!;
|
|
97
|
+
expect(event.kind).toBe('prompt');
|
|
98
|
+
expect(event.outcome).toBe('error');
|
|
99
|
+
expect(event.error).toEqual({
|
|
100
|
+
name: 'InvalidToolResult',
|
|
101
|
+
message: 'Prompt fetch resolved to a value that is not a GetPromptResult',
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('keeps the chain and the manifest honest across a dropped result', async () => {
|
|
106
|
+
const events: AuditEvent[] = [];
|
|
107
|
+
const onAuditError = vi.fn();
|
|
108
|
+
const handle = createAuditMiddleware({
|
|
109
|
+
...makeOptions(events),
|
|
110
|
+
onAuditError,
|
|
111
|
+
});
|
|
112
|
+
const ctx = makeCtx('sess-mixed');
|
|
113
|
+
|
|
114
|
+
// First call fails the way a local tool handler with a missing `return`
|
|
115
|
+
// does; the second is an ordinary success.
|
|
116
|
+
await handle.middleware(
|
|
117
|
+
makeReq('search'),
|
|
118
|
+
async () => undefined as never,
|
|
119
|
+
ctx,
|
|
120
|
+
);
|
|
121
|
+
await handle.middleware(
|
|
122
|
+
makeReq('search'),
|
|
123
|
+
async () => ({ content: [{ type: 'text', text: 'ok' }] }),
|
|
124
|
+
ctx,
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
const manifest = await handle.closeSession('sess-mixed');
|
|
128
|
+
|
|
129
|
+
// Two governed calls, two records, in order.
|
|
130
|
+
expect(events).toHaveLength(2);
|
|
131
|
+
expect(events.map((e) => e.replayManifestPosition)).toEqual([0, 1]);
|
|
132
|
+
expect(events.map((e) => e.outcome)).toEqual(['error', 'success']);
|
|
133
|
+
// Nothing needed the containment report any more: the unusable result is
|
|
134
|
+
// in the trail, not in the operator's log.
|
|
135
|
+
expect(onAuditError).not.toHaveBeenCalled();
|
|
136
|
+
|
|
137
|
+
expect(await verifyAuditChain(events, signingKey)).toEqual({ valid: true });
|
|
138
|
+
expect(manifest?.eventCount).toBe(2);
|
|
139
|
+
expect(await verifyManifestSignature(manifest!, signingKey)).toBe(true);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
@@ -688,6 +688,33 @@ describe('verifyManifestSignature (properties)', () => {
|
|
|
688
688
|
}),
|
|
689
689
|
);
|
|
690
690
|
});
|
|
691
|
+
|
|
692
|
+
it('rejects any respelling of the signature that is not the exact string', async () => {
|
|
693
|
+
// `anyLengthHex` only emits canonical hex, so it cannot reach the
|
|
694
|
+
// decoder's leniency: an odd nibble, a non-hex tail, or uppercase all
|
|
695
|
+
// decode to the same bytes and used to verify (#281). Start from the
|
|
696
|
+
// real signature and respell it: uppercase any subset of its characters
|
|
697
|
+
// and append a short tail.
|
|
698
|
+
const respelling = fc
|
|
699
|
+
.tuple(
|
|
700
|
+
fc.array(fc.boolean(), { minLength: 64, maxLength: 64 }),
|
|
701
|
+
fc.array(fc.constantFrom(...'0123456789abcdefz'), { maxLength: 3 }),
|
|
702
|
+
)
|
|
703
|
+
.map(
|
|
704
|
+
([upper, tail]) =>
|
|
705
|
+
[...manifest.signature]
|
|
706
|
+
.map((c, i) => (upper[i] ? c.toUpperCase() : c))
|
|
707
|
+
.join('') + tail.join(''),
|
|
708
|
+
);
|
|
709
|
+
await fc.assert(
|
|
710
|
+
fc.asyncProperty(respelling, async (signature) => {
|
|
711
|
+
fc.pre(signature !== manifest.signature);
|
|
712
|
+
expect(
|
|
713
|
+
await verifyManifestSignature({ ...manifest, signature }, signingKey),
|
|
714
|
+
).toBe(false);
|
|
715
|
+
}),
|
|
716
|
+
);
|
|
717
|
+
});
|
|
691
718
|
});
|
|
692
719
|
|
|
693
720
|
// ── Signing key derivation ────────────────────────────────────────────────────
|
package/src/middleware.ts
CHANGED
|
@@ -144,10 +144,51 @@ function anonymousIdentity(): Identity {
|
|
|
144
144
|
};
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Every member of the closed `RejectionReason` union, as an own-key
|
|
149
|
+
* membership table.
|
|
150
|
+
*
|
|
151
|
+
* The union is a type, so it is erased at runtime and `err.data.rejectionReason`
|
|
152
|
+
* arrives as an unchecked string. The `Record` annotation is the drift guard in
|
|
153
|
+
* both directions: a member added to the union without a matching key here is a
|
|
154
|
+
* compile error, and so is a key that is not a member of the union.
|
|
155
|
+
*
|
|
156
|
+
* Core keeps its own copy for telemetry. This one is not imported from there
|
|
157
|
+
* because the `mcpose` peer range admits 3.0.0, which exports no runtime guard.
|
|
158
|
+
*/
|
|
159
|
+
const REJECTION_REASONS: Record<RejectionReason, true> = {
|
|
160
|
+
TOOL_HIDDEN: true,
|
|
161
|
+
RESOURCE_HIDDEN: true,
|
|
162
|
+
BACKEND_UNROUTABLE: true,
|
|
163
|
+
POLICY_DENIED: true,
|
|
164
|
+
IDENTITY_UNRESOLVED: true,
|
|
165
|
+
CONSENT_MISSING: true,
|
|
166
|
+
SENSITIVITY_BLOCKED: true,
|
|
167
|
+
DELEGATION_INVALID: true,
|
|
168
|
+
BUDGET_EXCEEDED: true,
|
|
169
|
+
SESSION_LIMIT: true,
|
|
170
|
+
BODY_LIMIT: true,
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* The rejection reason this error carries, or `undefined` when it carries
|
|
175
|
+
* none.
|
|
176
|
+
*
|
|
177
|
+
* Fail CLOSED, like the sensitivity tier: a `rejectionReason` outside the
|
|
178
|
+
* union is not a governance rejection, so the call is recorded as an ordinary
|
|
179
|
+
* `error` that keeps the real name and message. Casting the string through
|
|
180
|
+
* instead would record a failure as a rejection with no `error` field, and
|
|
181
|
+
* chain the unvalidated value as a covered field, which is the identity-less
|
|
182
|
+
* `outputHash` weakness the structured `error` field exists to close
|
|
183
|
+
* (ADR-0004). Mirrors `createSensitivityResolver`.
|
|
184
|
+
*/
|
|
147
185
|
function getRejectionReason(err: unknown): RejectionReason | undefined {
|
|
148
186
|
const data = (err as { data?: { rejectionReason?: unknown } } | null)?.data;
|
|
149
|
-
|
|
150
|
-
|
|
187
|
+
const reason = data?.rejectionReason;
|
|
188
|
+
// `Object.hasOwn`, not `in`: the reason is upstream-controlled, so a value
|
|
189
|
+
// like `constructor` must not pass as a member off the prototype.
|
|
190
|
+
return typeof reason === 'string' && Object.hasOwn(REJECTION_REASONS, reason)
|
|
191
|
+
? (reason as RejectionReason)
|
|
151
192
|
: undefined;
|
|
152
193
|
}
|
|
153
194
|
|
|
@@ -159,16 +200,31 @@ export function createAuditMiddleware(
|
|
|
159
200
|
const sealed = new Map<string, SealedSession>();
|
|
160
201
|
const includeRejections = options.includeRejections ?? true;
|
|
161
202
|
const closeDrainTimeoutMs = options.closeDrainTimeoutMs ?? 30_000;
|
|
203
|
+
// `!(x >= 0)` rejects NaN too, which the `??` default above lets through:
|
|
204
|
+
// a NaN deadline never fires, so the drain this option exists to bound would
|
|
205
|
+
// wait for a call that never settles and leave the recorded events unsigned
|
|
206
|
+
// with nothing reported. Same form as `maxSessions` in core (#277).
|
|
207
|
+
if (!(closeDrainTimeoutMs >= 0)) {
|
|
208
|
+
throw new Error(
|
|
209
|
+
`mcpose/audit: closeDrainTimeoutMs must be >= 0 or Infinity, got ${String(
|
|
210
|
+
options.closeDrainTimeoutMs,
|
|
211
|
+
)}`,
|
|
212
|
+
);
|
|
213
|
+
}
|
|
162
214
|
const reportAuditError: NonNullable<AuditOptions['onAuditError']> =
|
|
163
215
|
options.onAuditError ?? ((err) => console.error(err));
|
|
164
|
-
// A throwing reporter is outside the audited call path too
|
|
165
|
-
// not replace a tool result, mask an upstream error,
|
|
216
|
+
// A throwing or rejecting reporter is outside the audited call path too
|
|
217
|
+
// (#172, #245): it must not replace a tool result, mask an upstream error,
|
|
218
|
+
// abort a drain, or leave an unobserved rejection that Node's default
|
|
219
|
+
// --unhandled-rejections=throw turns into a dead process.
|
|
166
220
|
const onAuditError: NonNullable<AuditOptions['onAuditError']> = (
|
|
167
221
|
err,
|
|
168
222
|
info,
|
|
169
223
|
) => {
|
|
170
224
|
try {
|
|
171
|
-
reportAuditError(err, info)
|
|
225
|
+
Promise.resolve(reportAuditError(err, info)).catch(() => {
|
|
226
|
+
// Nothing left to report it to.
|
|
227
|
+
});
|
|
172
228
|
} catch {
|
|
173
229
|
// Nothing left to report it to.
|
|
174
230
|
}
|
|
@@ -300,11 +356,35 @@ export function createAuditMiddleware(
|
|
|
300
356
|
// A call can fail without throwing: an MCP tool reports failure
|
|
301
357
|
// in-band with `isError: true` (#171). The caller supplies the
|
|
302
358
|
// predicate, so only tool calls pass one and prompts never match.
|
|
303
|
-
|
|
359
|
+
//
|
|
360
|
+
// A result that is not an object is decided here too, and for the same
|
|
361
|
+
// reason: the predicate below narrows to a `CallToolResult` and a
|
|
362
|
+
// primitive has no `.content` to narrow on. A local tool handler that
|
|
363
|
+
// resolves to a string reaches the client as `-32602 Invalid
|
|
364
|
+
// tools/call result`, so recording it as a success would put a clean
|
|
365
|
+
// outcome, and no `error` field, in a signed chain covering a call the
|
|
366
|
+
// client saw fail. `isResultless` in core's telemetry draws the same
|
|
367
|
+
// line, so both record what the caller observed.
|
|
368
|
+
//
|
|
369
|
+
// A nullish result is decided here, BEFORE the predicate narrows it,
|
|
370
|
+
// because narrowing reads `.content` and a nullish value has none: a
|
|
371
|
+
// local tool handler with a missing `return` made the predicate throw,
|
|
372
|
+
// and that throw reached the `catch` below, which reports and moves on
|
|
373
|
+
// — so `buildEvent` never ran and the governed call reached the client
|
|
374
|
+
// as a failure and the trail not at all. The manifest that counted it
|
|
375
|
+
// still verified, a valid chain under a valid signature, one event
|
|
376
|
+
// short of the calls it claims to cover.
|
|
377
|
+
const noToolResult =
|
|
378
|
+
!threw &&
|
|
379
|
+
(result === null ||
|
|
380
|
+
result === undefined ||
|
|
381
|
+
typeof result !== 'object');
|
|
382
|
+
const inBandError =
|
|
383
|
+
!threw && !noToolResult && isInBandError?.(result as Res) === true;
|
|
304
384
|
const outcome: AuditEvent['outcome'] =
|
|
305
385
|
rejectionReason !== undefined
|
|
306
386
|
? 'rejected'
|
|
307
|
-
: threw || inBandError
|
|
387
|
+
: threw || inBandError || noToolResult
|
|
308
388
|
? 'error'
|
|
309
389
|
: 'success';
|
|
310
390
|
|
|
@@ -348,10 +428,21 @@ export function createAuditMiddleware(
|
|
|
348
428
|
}
|
|
349
429
|
: // A fixed message: `error` is never encrypted, so copying the
|
|
350
430
|
// tool's own text here would leak a high-tier payload.
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
431
|
+
noToolResult
|
|
432
|
+
? {
|
|
433
|
+
name: 'InvalidToolResult',
|
|
434
|
+
// `kind` decides the shape that was expected, and the
|
|
435
|
+
// message is plaintext, so it has to name the one that
|
|
436
|
+
// was actually missing.
|
|
437
|
+
message:
|
|
438
|
+
kind === 'prompt'
|
|
439
|
+
? 'Prompt fetch resolved to a value that is not a GetPromptResult'
|
|
440
|
+
: 'Tool call resolved to a value that is not a CallToolResult',
|
|
441
|
+
}
|
|
442
|
+
: {
|
|
443
|
+
name: 'ToolError',
|
|
444
|
+
message: 'Tool result returned isError: true',
|
|
445
|
+
},
|
|
355
446
|
position,
|
|
356
447
|
prevChainHash: session?.prevChainHash ?? '',
|
|
357
448
|
tier,
|
package/src/types.ts
CHANGED
|
@@ -125,9 +125,11 @@ export interface AuditEventBase {
|
|
|
125
125
|
/** Present when outcome is 'rejected' (from the MCP error's data field). */
|
|
126
126
|
rejectionReason?: RejectionReason;
|
|
127
127
|
/**
|
|
128
|
-
* Present when outcome is 'error': what the upstream call threw, or
|
|
129
|
-
* `{ name: 'ToolError' }`
|
|
130
|
-
* `isError: true` in-band
|
|
128
|
+
* Present when outcome is 'error': what the upstream call threw, or a fixed
|
|
129
|
+
* message when the call failed without throwing -- `{ name: 'ToolError' }`
|
|
130
|
+
* for a tool result that carried `isError: true` in-band, and
|
|
131
|
+
* `{ name: 'InvalidToolResult' }` when the call resolved to a value that is
|
|
132
|
+
* not the shape its `kind` expects.
|
|
131
133
|
*/
|
|
132
134
|
error?: { name: string; message: string };
|
|
133
135
|
inputHash: string;
|
|
@@ -186,7 +188,8 @@ export interface ReplayManifest {
|
|
|
186
188
|
/**
|
|
187
189
|
* HMAC over the canonical serialization of the ENTIRE manifest (every
|
|
188
190
|
* field above, domain-separated) — not just the Merkle root. Verify with
|
|
189
|
-
* `verifyManifestSignature
|
|
191
|
+
* `verifyManifestSignature`, which accepts only this exact lowercase hex
|
|
192
|
+
* string: a respelling (uppercase, an appended character) does not verify.
|
|
190
193
|
*/
|
|
191
194
|
signature: string;
|
|
192
195
|
}
|
|
@@ -236,21 +239,24 @@ export interface AuditOptions {
|
|
|
236
239
|
* to append and persist their events before it seals the manifest. Past
|
|
237
240
|
* the deadline the manifest covers what has landed, and each straggler is
|
|
238
241
|
* reported through `onAuditError` with its tool and requestId. `Infinity`
|
|
239
|
-
* waits without bound.
|
|
242
|
+
* waits without bound. Any other value (NaN, a negative number) is
|
|
243
|
+
* rejected at construction, because it would leave the drain with no
|
|
244
|
+
* deadline at all.
|
|
240
245
|
* @default 30_000
|
|
241
246
|
*/
|
|
242
247
|
closeDrainTimeoutMs?: number;
|
|
243
248
|
/**
|
|
244
249
|
* Called when the audit layer itself fails (event serialization, a
|
|
245
250
|
* throwing onEvent sink). The audit layer NEVER throws into the tool-call
|
|
246
|
-
* path; failures are reported here instead. If this hook itself throws
|
|
247
|
-
* the
|
|
251
|
+
* path; failures are reported here instead. If this hook itself throws or
|
|
252
|
+
* returns a rejected promise, the failure is contained and never reaches
|
|
253
|
+
* the caller either.
|
|
248
254
|
* @default console.error
|
|
249
255
|
*/
|
|
250
256
|
onAuditError?: (
|
|
251
257
|
err: unknown,
|
|
252
258
|
info: { tool: string; requestId: string; sessionId?: string },
|
|
253
|
-
) =>
|
|
259
|
+
) => unknown;
|
|
254
260
|
}
|
|
255
261
|
|
|
256
262
|
export interface AuditMiddlewareHandle {
|
package/src/verify.ts
CHANGED
|
@@ -12,10 +12,26 @@ const DOMAIN_CHAIN = Buffer.from('mcpose/v2/chain');
|
|
|
12
12
|
export type ChainVerification =
|
|
13
13
|
{ valid: true } | { valid: false; index: number; reason: string };
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Canonical hex: lowercase, even length, hex digits only, non-empty. This
|
|
17
|
+
* is what the producer writes (`digest('hex')`), and the exact string a
|
|
18
|
+
* third-party verifier compares.
|
|
19
|
+
*/
|
|
20
|
+
const CANONICAL_HEX = /^(?:[0-9a-f]{2})+$/;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Compares a stored hex string against the recomputed value in constant
|
|
24
|
+
* time. The stored string must be canonical first: Node's hex decoder drops
|
|
25
|
+
* a trailing odd nibble and stops at the first non-hex character, so
|
|
26
|
+
* `sig + '0'`, `sig + 'z'` and `SIG` all decode to the stored bytes and would
|
|
27
|
+
* otherwise verify. The verifiers authenticate the stored string itself, not
|
|
28
|
+
* just its decoding, so two implementations agree on one artifact (#281).
|
|
29
|
+
*/
|
|
30
|
+
function hexEqual(storedHex: string, expectedHex: string): boolean {
|
|
31
|
+
if (!CANONICAL_HEX.test(storedHex)) return false;
|
|
32
|
+
const a = Buffer.from(storedHex, 'hex');
|
|
33
|
+
const b = Buffer.from(expectedHex, 'hex');
|
|
34
|
+
return a.length === b.length && timingSafeEqual(a, b);
|
|
19
35
|
}
|
|
20
36
|
|
|
21
37
|
/**
|