protect-mcp 0.5.5 → 0.6.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 +70 -3
- package/dist/{ed25519-V7HDL2WC.mjs → chunk-LYKNULYU.mjs} +166 -10
- package/dist/cli.mjs +3 -3
- package/dist/ed25519-DZMMNNVE.mjs +38 -0
- package/dist/index.d.mts +149 -1
- package/dist/index.d.ts +149 -1
- package/dist/index.js +2749 -390
- package/dist/index.mjs +240 -7
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,73 @@
|
|
|
1
1
|
# protect-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/protect-mcp)
|
|
4
|
+
[](https://www.npmjs.com/package/protect-mcp)
|
|
5
|
+
[](https://github.com/wshobson/agents/tree/main/plugins/protect-mcp)
|
|
6
|
+
[](./LICENSE)
|
|
7
|
+
|
|
8
|
+
> A policy check that sits between your AI agent and the tools it calls.
|
|
9
|
+
> Every tool call is evaluated against a rule you wrote. Every decision is signed.
|
|
10
|
+
|
|
11
|
+
## What it does, in plain English
|
|
12
|
+
|
|
13
|
+
When an AI agent (Claude Code, Cursor, a custom LangChain app, anything that
|
|
14
|
+
uses the Model Context Protocol) wants to run a command, edit a file, or call
|
|
15
|
+
an API, `protect-mcp` intercepts that request before it executes:
|
|
16
|
+
|
|
17
|
+
1. **Checks a policy.** You write rules in [Cedar](https://www.cedarpolicy.com/)
|
|
18
|
+
— the same policy language AWS uses for IAM. Rules like *"never allow
|
|
19
|
+
`rm -rf /`"*, *"only allow `Bash` during working hours"*, or *"require
|
|
20
|
+
human approval for anything touching production."*
|
|
21
|
+
2. **Returns a decision.** `allow`, `deny`, or `request_approval`. The agent
|
|
22
|
+
framework respects the decision — if it's `deny`, the tool call doesn't run.
|
|
23
|
+
3. **Signs a receipt.** An Ed25519-signed, hash-chained record of the decision,
|
|
24
|
+
written to `.receipts/`. Verifiable offline by anyone with the public key.
|
|
25
|
+
When your auditor asks *"what did that agent do on 2026-03-14?"* you have
|
|
26
|
+
cryptographic proof — not a log file you might have tampered with.
|
|
27
|
+
|
|
28
|
+
You install it once. Your agent keeps working the same way. The difference:
|
|
29
|
+
every action it takes is now policy-checked and audit-evidenced.
|
|
30
|
+
|
|
31
|
+
## Who this is for
|
|
32
|
+
|
|
33
|
+
- **Developers using Claude Code / Cursor / Cline** who want *"don't let the
|
|
34
|
+
agent delete my repo"* enforced rather than hoped for.
|
|
35
|
+
- **Security teams** shipping agents to engineering who need a portable
|
|
36
|
+
policy layer that travels across frameworks.
|
|
37
|
+
- **Compliance teams** who need tamper-evident evidence of what agents did,
|
|
38
|
+
verifiable without trusting the vendor.
|
|
39
|
+
|
|
40
|
+
## How it relates to `sb-runtime`
|
|
41
|
+
|
|
42
|
+
`protect-mcp` is a **library** — it sits inside your agent framework and
|
|
43
|
+
gates tool calls cooperatively. Right tool when you own the agent's code and
|
|
44
|
+
trust its framework to honour decisions.
|
|
45
|
+
|
|
46
|
+
[`sb-runtime`](https://github.com/ScopeBlind/sb-runtime) is the companion
|
|
47
|
+
**binary** that wraps the whole agent *process* in an OS-level sandbox
|
|
48
|
+
(Landlock + seccomp on Linux). It enforces decisions at the kernel layer —
|
|
49
|
+
the agent can't ignore them even if it tried. Use `sb-runtime` when you're
|
|
50
|
+
running an agent you didn't write, or when you want belt-and-braces defence
|
|
51
|
+
in depth:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
┌─────────────────────────────────────────────────┐
|
|
55
|
+
│ sb-runtime ← OS refuses forbidden syscalls │
|
|
56
|
+
│ ┌───────────────────────────────────────────┐ │
|
|
57
|
+
│ │ agent process (Claude Code, Python, …) │ │
|
|
58
|
+
│ │ ┌─────────────────────────────────────┐ │ │
|
|
59
|
+
│ │ │ protect-mcp │ │ │
|
|
60
|
+
│ │ │ ← Cedar decides per tool call, │ │ │
|
|
61
|
+
│ │ │ receipts every decision │ │ │
|
|
62
|
+
│ │ └─────────────────────────────────────┘ │ │
|
|
63
|
+
│ └───────────────────────────────────────────┘ │
|
|
64
|
+
└─────────────────────────────────────────────────┘
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**One-liner:** `protect-mcp` is the policy hook inside your agent.
|
|
68
|
+
`sb-runtime` is the OS sandbox around it. You want both.
|
|
69
|
+
|
|
70
|
+
---
|
|
4
71
|
|
|
5
72
|
## Quick Start — Claude Code
|
|
6
73
|
|
|
@@ -277,7 +344,7 @@ The receipt format is independently implemented and verified across multiple sys
|
|
|
277
344
|
| **4 independent implementations** | TypeScript (protect-mcp), Python (protect-mcp-adk), Rust (Cedar WASM), APS ProxyGateway |
|
|
278
345
|
| **2 IETF Internet-Drafts** | [draft-farley-acta-signed-receipts-01](https://datatracker.ietf.org/doc/draft-farley-acta-signed-receipts/), [draft-pidlisnyi-aps-00](https://datatracker.ietf.org/doc/draft-pidlisnyi-aps/) |
|
|
279
346
|
| **8 cross-engine receipts** | [Composition test](https://github.com/ScopeBlind/examples/tree/main/interop/composition-test): 2 engines, 1 verifier, all VALID |
|
|
280
|
-
| **
|
|
347
|
+
| **3 enterprise integrations** | Microsoft AGT [#667](https://github.com/microsoft/agent-governance-toolkit/pull/667), [#1159](https://github.com/microsoft/agent-governance-toolkit/pull/1159), [#1168](https://github.com/microsoft/agent-governance-toolkit/pull/1168) |
|
|
281
348
|
| **1 verifier, zero dependencies** | `npx @veritasacta/verify receipt.json --key <hex>` (Apache-2.0, offline) |
|
|
282
349
|
|
|
283
350
|
Verify any receipt from any implementation:
|
|
@@ -291,7 +358,7 @@ npx @veritasacta/verify receipt.json --key <public-key-hex>
|
|
|
291
358
|
|
|
292
359
|
- **IETF Internet-Draft**: [draft-farley-acta-signed-receipts-01](https://datatracker.ietf.org/doc/draft-farley-acta-signed-receipts/)
|
|
293
360
|
- **Patent Status**: 4 Australian provisional patents pending (2025-2026)
|
|
294
|
-
- **Cedar WASM**: [PR #64](https://github.com/cedar-policy/cedar-for-agents/pull/64)
|
|
361
|
+
- **Cedar WASM**: [PR #64](https://github.com/cedar-policy/cedar-for-agents/pull/64) merged + [PR #73](https://github.com/cedar-policy/cedar-for-agents/pull/73) (RequestGenerator, pending review)
|
|
295
362
|
|
|
296
363
|
## What's New in v0.5.3
|
|
297
364
|
|
|
@@ -12,10 +12,10 @@ import {
|
|
|
12
12
|
hexToBytes,
|
|
13
13
|
isBytes,
|
|
14
14
|
randomBytes,
|
|
15
|
+
rotr,
|
|
15
16
|
toBytes,
|
|
16
17
|
utf8ToBytes
|
|
17
18
|
} from "./chunk-D733KAPG.mjs";
|
|
18
|
-
import "./chunk-PQJP2ZCI.mjs";
|
|
19
19
|
|
|
20
20
|
// node_modules/@noble/hashes/esm/_md.js
|
|
21
21
|
function setBigUint64(view, byteOffset, value, isLE) {
|
|
@@ -30,6 +30,12 @@ function setBigUint64(view, byteOffset, value, isLE) {
|
|
|
30
30
|
view.setUint32(byteOffset + h, wh, isLE);
|
|
31
31
|
view.setUint32(byteOffset + l, wl, isLE);
|
|
32
32
|
}
|
|
33
|
+
function Chi(a, b, c) {
|
|
34
|
+
return a & b ^ ~a & c;
|
|
35
|
+
}
|
|
36
|
+
function Maj(a, b, c) {
|
|
37
|
+
return a & b ^ a & c ^ b & c;
|
|
38
|
+
}
|
|
33
39
|
var HashMD = class extends Hash {
|
|
34
40
|
constructor(blockLen, outputLen, padOffset, isLE) {
|
|
35
41
|
super();
|
|
@@ -120,6 +126,16 @@ var HashMD = class extends Hash {
|
|
|
120
126
|
return this._cloneInto();
|
|
121
127
|
}
|
|
122
128
|
};
|
|
129
|
+
var SHA256_IV = /* @__PURE__ */ Uint32Array.from([
|
|
130
|
+
1779033703,
|
|
131
|
+
3144134277,
|
|
132
|
+
1013904242,
|
|
133
|
+
2773480762,
|
|
134
|
+
1359893119,
|
|
135
|
+
2600822924,
|
|
136
|
+
528734635,
|
|
137
|
+
1541459225
|
|
138
|
+
]);
|
|
123
139
|
var SHA512_IV = /* @__PURE__ */ Uint32Array.from([
|
|
124
140
|
1779033703,
|
|
125
141
|
4089235720,
|
|
@@ -175,6 +191,143 @@ var add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >
|
|
|
175
191
|
var add5H = (low, Ah, Bh, Ch, Dh, Eh) => Ah + Bh + Ch + Dh + Eh + (low / 2 ** 32 | 0) | 0;
|
|
176
192
|
|
|
177
193
|
// node_modules/@noble/hashes/esm/sha2.js
|
|
194
|
+
var SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
|
195
|
+
1116352408,
|
|
196
|
+
1899447441,
|
|
197
|
+
3049323471,
|
|
198
|
+
3921009573,
|
|
199
|
+
961987163,
|
|
200
|
+
1508970993,
|
|
201
|
+
2453635748,
|
|
202
|
+
2870763221,
|
|
203
|
+
3624381080,
|
|
204
|
+
310598401,
|
|
205
|
+
607225278,
|
|
206
|
+
1426881987,
|
|
207
|
+
1925078388,
|
|
208
|
+
2162078206,
|
|
209
|
+
2614888103,
|
|
210
|
+
3248222580,
|
|
211
|
+
3835390401,
|
|
212
|
+
4022224774,
|
|
213
|
+
264347078,
|
|
214
|
+
604807628,
|
|
215
|
+
770255983,
|
|
216
|
+
1249150122,
|
|
217
|
+
1555081692,
|
|
218
|
+
1996064986,
|
|
219
|
+
2554220882,
|
|
220
|
+
2821834349,
|
|
221
|
+
2952996808,
|
|
222
|
+
3210313671,
|
|
223
|
+
3336571891,
|
|
224
|
+
3584528711,
|
|
225
|
+
113926993,
|
|
226
|
+
338241895,
|
|
227
|
+
666307205,
|
|
228
|
+
773529912,
|
|
229
|
+
1294757372,
|
|
230
|
+
1396182291,
|
|
231
|
+
1695183700,
|
|
232
|
+
1986661051,
|
|
233
|
+
2177026350,
|
|
234
|
+
2456956037,
|
|
235
|
+
2730485921,
|
|
236
|
+
2820302411,
|
|
237
|
+
3259730800,
|
|
238
|
+
3345764771,
|
|
239
|
+
3516065817,
|
|
240
|
+
3600352804,
|
|
241
|
+
4094571909,
|
|
242
|
+
275423344,
|
|
243
|
+
430227734,
|
|
244
|
+
506948616,
|
|
245
|
+
659060556,
|
|
246
|
+
883997877,
|
|
247
|
+
958139571,
|
|
248
|
+
1322822218,
|
|
249
|
+
1537002063,
|
|
250
|
+
1747873779,
|
|
251
|
+
1955562222,
|
|
252
|
+
2024104815,
|
|
253
|
+
2227730452,
|
|
254
|
+
2361852424,
|
|
255
|
+
2428436474,
|
|
256
|
+
2756734187,
|
|
257
|
+
3204031479,
|
|
258
|
+
3329325298
|
|
259
|
+
]);
|
|
260
|
+
var SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
|
261
|
+
var SHA256 = class extends HashMD {
|
|
262
|
+
constructor(outputLen = 32) {
|
|
263
|
+
super(64, outputLen, 8, false);
|
|
264
|
+
this.A = SHA256_IV[0] | 0;
|
|
265
|
+
this.B = SHA256_IV[1] | 0;
|
|
266
|
+
this.C = SHA256_IV[2] | 0;
|
|
267
|
+
this.D = SHA256_IV[3] | 0;
|
|
268
|
+
this.E = SHA256_IV[4] | 0;
|
|
269
|
+
this.F = SHA256_IV[5] | 0;
|
|
270
|
+
this.G = SHA256_IV[6] | 0;
|
|
271
|
+
this.H = SHA256_IV[7] | 0;
|
|
272
|
+
}
|
|
273
|
+
get() {
|
|
274
|
+
const { A, B, C, D, E, F, G, H } = this;
|
|
275
|
+
return [A, B, C, D, E, F, G, H];
|
|
276
|
+
}
|
|
277
|
+
// prettier-ignore
|
|
278
|
+
set(A, B, C, D, E, F, G, H) {
|
|
279
|
+
this.A = A | 0;
|
|
280
|
+
this.B = B | 0;
|
|
281
|
+
this.C = C | 0;
|
|
282
|
+
this.D = D | 0;
|
|
283
|
+
this.E = E | 0;
|
|
284
|
+
this.F = F | 0;
|
|
285
|
+
this.G = G | 0;
|
|
286
|
+
this.H = H | 0;
|
|
287
|
+
}
|
|
288
|
+
process(view, offset) {
|
|
289
|
+
for (let i = 0; i < 16; i++, offset += 4)
|
|
290
|
+
SHA256_W[i] = view.getUint32(offset, false);
|
|
291
|
+
for (let i = 16; i < 64; i++) {
|
|
292
|
+
const W15 = SHA256_W[i - 15];
|
|
293
|
+
const W2 = SHA256_W[i - 2];
|
|
294
|
+
const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3;
|
|
295
|
+
const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10;
|
|
296
|
+
SHA256_W[i] = s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16] | 0;
|
|
297
|
+
}
|
|
298
|
+
let { A, B, C, D, E, F, G, H } = this;
|
|
299
|
+
for (let i = 0; i < 64; i++) {
|
|
300
|
+
const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
|
|
301
|
+
const T1 = H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i] | 0;
|
|
302
|
+
const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
|
|
303
|
+
const T2 = sigma0 + Maj(A, B, C) | 0;
|
|
304
|
+
H = G;
|
|
305
|
+
G = F;
|
|
306
|
+
F = E;
|
|
307
|
+
E = D + T1 | 0;
|
|
308
|
+
D = C;
|
|
309
|
+
C = B;
|
|
310
|
+
B = A;
|
|
311
|
+
A = T1 + T2 | 0;
|
|
312
|
+
}
|
|
313
|
+
A = A + this.A | 0;
|
|
314
|
+
B = B + this.B | 0;
|
|
315
|
+
C = C + this.C | 0;
|
|
316
|
+
D = D + this.D | 0;
|
|
317
|
+
E = E + this.E | 0;
|
|
318
|
+
F = F + this.F | 0;
|
|
319
|
+
G = G + this.G | 0;
|
|
320
|
+
H = H + this.H | 0;
|
|
321
|
+
this.set(A, B, C, D, E, F, G, H);
|
|
322
|
+
}
|
|
323
|
+
roundClean() {
|
|
324
|
+
clean(SHA256_W);
|
|
325
|
+
}
|
|
326
|
+
destroy() {
|
|
327
|
+
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
|
328
|
+
clean(this.buffer);
|
|
329
|
+
}
|
|
330
|
+
};
|
|
178
331
|
var K512 = /* @__PURE__ */ (() => split([
|
|
179
332
|
"0x428a2f98d728ae22",
|
|
180
333
|
"0x7137449123ef65cd",
|
|
@@ -372,6 +525,7 @@ var SHA512 = class extends HashMD {
|
|
|
372
525
|
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
373
526
|
}
|
|
374
527
|
};
|
|
528
|
+
var sha256 = /* @__PURE__ */ createHasher(() => new SHA256());
|
|
375
529
|
var sha512 = /* @__PURE__ */ createHasher(() => new SHA512());
|
|
376
530
|
|
|
377
531
|
// node_modules/@noble/curves/esm/utils.js
|
|
@@ -2260,23 +2414,25 @@ var hashToCurve = /* @__PURE__ */ (() => ed25519_hasher.hashToCurve)();
|
|
|
2260
2414
|
var encodeToCurve = /* @__PURE__ */ (() => ed25519_hasher.encodeToCurve)();
|
|
2261
2415
|
var hashToRistretto255 = /* @__PURE__ */ (() => ristretto255_hasher.hashToCurve)();
|
|
2262
2416
|
var hash_to_ristretto255 = /* @__PURE__ */ (() => ristretto255_hasher.hashToCurve)();
|
|
2417
|
+
|
|
2263
2418
|
export {
|
|
2264
|
-
|
|
2265
|
-
RistrettoPoint,
|
|
2419
|
+
sha256,
|
|
2266
2420
|
ed25519,
|
|
2267
|
-
ed25519_hasher,
|
|
2268
2421
|
ed25519ctx,
|
|
2269
2422
|
ed25519ph,
|
|
2423
|
+
x25519,
|
|
2424
|
+
ed25519_hasher,
|
|
2425
|
+
ristretto255,
|
|
2426
|
+
ristretto255_hasher,
|
|
2427
|
+
ED25519_TORSION_SUBGROUP,
|
|
2428
|
+
edwardsToMontgomeryPub,
|
|
2270
2429
|
edwardsToMontgomery,
|
|
2271
2430
|
edwardsToMontgomeryPriv,
|
|
2272
|
-
|
|
2273
|
-
encodeToCurve,
|
|
2431
|
+
RistrettoPoint,
|
|
2274
2432
|
hashToCurve,
|
|
2433
|
+
encodeToCurve,
|
|
2275
2434
|
hashToRistretto255,
|
|
2276
|
-
hash_to_ristretto255
|
|
2277
|
-
ristretto255,
|
|
2278
|
-
ristretto255_hasher,
|
|
2279
|
-
x25519
|
|
2435
|
+
hash_to_ristretto255
|
|
2280
2436
|
};
|
|
2281
2437
|
/*! Bundled license information:
|
|
2282
2438
|
|
package/dist/cli.mjs
CHANGED
|
@@ -145,7 +145,7 @@ async function handleInit(argv) {
|
|
|
145
145
|
let keypair;
|
|
146
146
|
{
|
|
147
147
|
const { randomBytes } = await import("crypto");
|
|
148
|
-
const { ed25519 } = await import("./ed25519-
|
|
148
|
+
const { ed25519 } = await import("./ed25519-DZMMNNVE.mjs");
|
|
149
149
|
const { bytesToHex } = await import("./utils-6AYZFE5A.mjs");
|
|
150
150
|
const privateKey = randomBytes(32);
|
|
151
151
|
const publicKey = ed25519.getPublicKey(privateKey);
|
|
@@ -765,7 +765,7 @@ ${bold("protect-mcp quickstart")}
|
|
|
765
765
|
const { randomBytes } = await import("crypto");
|
|
766
766
|
let keypair;
|
|
767
767
|
try {
|
|
768
|
-
const { ed25519 } = await import("./ed25519-
|
|
768
|
+
const { ed25519 } = await import("./ed25519-DZMMNNVE.mjs");
|
|
769
769
|
const { bytesToHex } = await import("./utils-6AYZFE5A.mjs");
|
|
770
770
|
const privateKey = randomBytes(32);
|
|
771
771
|
const publicKey = ed25519.getPublicKey(privateKey);
|
|
@@ -1111,7 +1111,7 @@ ${bold("protect-mcp init-hooks")}
|
|
|
1111
1111
|
if (!existsSync(keysDir)) mkdirSync(keysDir, { recursive: true });
|
|
1112
1112
|
const { randomBytes: rb } = await import("crypto");
|
|
1113
1113
|
try {
|
|
1114
|
-
const { ed25519 } = await import("./ed25519-
|
|
1114
|
+
const { ed25519 } = await import("./ed25519-DZMMNNVE.mjs");
|
|
1115
1115
|
const { bytesToHex } = await import("./utils-6AYZFE5A.mjs");
|
|
1116
1116
|
const privateKey = rb(32);
|
|
1117
1117
|
const publicKey = ed25519.getPublicKey(privateKey);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ED25519_TORSION_SUBGROUP,
|
|
3
|
+
RistrettoPoint,
|
|
4
|
+
ed25519,
|
|
5
|
+
ed25519_hasher,
|
|
6
|
+
ed25519ctx,
|
|
7
|
+
ed25519ph,
|
|
8
|
+
edwardsToMontgomery,
|
|
9
|
+
edwardsToMontgomeryPriv,
|
|
10
|
+
edwardsToMontgomeryPub,
|
|
11
|
+
encodeToCurve,
|
|
12
|
+
hashToCurve,
|
|
13
|
+
hashToRistretto255,
|
|
14
|
+
hash_to_ristretto255,
|
|
15
|
+
ristretto255,
|
|
16
|
+
ristretto255_hasher,
|
|
17
|
+
x25519
|
|
18
|
+
} from "./chunk-LYKNULYU.mjs";
|
|
19
|
+
import "./chunk-D733KAPG.mjs";
|
|
20
|
+
import "./chunk-PQJP2ZCI.mjs";
|
|
21
|
+
export {
|
|
22
|
+
ED25519_TORSION_SUBGROUP,
|
|
23
|
+
RistrettoPoint,
|
|
24
|
+
ed25519,
|
|
25
|
+
ed25519_hasher,
|
|
26
|
+
ed25519ctx,
|
|
27
|
+
ed25519ph,
|
|
28
|
+
edwardsToMontgomery,
|
|
29
|
+
edwardsToMontgomeryPriv,
|
|
30
|
+
edwardsToMontgomeryPub,
|
|
31
|
+
encodeToCurve,
|
|
32
|
+
hashToCurve,
|
|
33
|
+
hashToRistretto255,
|
|
34
|
+
hash_to_ristretto255,
|
|
35
|
+
ristretto255,
|
|
36
|
+
ristretto255_hasher,
|
|
37
|
+
x25519
|
|
38
|
+
};
|
package/dist/index.d.mts
CHANGED
|
@@ -95,6 +95,29 @@ interface SigningConfig {
|
|
|
95
95
|
issuer?: string;
|
|
96
96
|
/** Whether signing is enabled (default: true when key_path is set) */
|
|
97
97
|
enabled?: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Commitment-mode signing.
|
|
100
|
+
*
|
|
101
|
+
* When enabled, listed fields are committed via SHA-256(salt || JCS({name, salt, value}))
|
|
102
|
+
* and the receipt payload carries a single committed_fields_root (Merkle root) instead
|
|
103
|
+
* of the cleartext field values. Per draft-farley-acta-signed-receipts-01 §commitment-mode.
|
|
104
|
+
*
|
|
105
|
+
* The receipt issuer keeps the openings (value + salt per field) for later selective
|
|
106
|
+
* disclosure. A receipt holder can prove a field's value to an auditor without
|
|
107
|
+
* revealing other committed fields.
|
|
108
|
+
*
|
|
109
|
+
* @since 0.6.0
|
|
110
|
+
*/
|
|
111
|
+
commitment_mode?: {
|
|
112
|
+
/** Whether commitment-mode signing is active. Default: false. */
|
|
113
|
+
enabled?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* Names of payload fields to commit.
|
|
116
|
+
* Recommended defaults: tool, scope, payload_digest, swarm.
|
|
117
|
+
* Other fields remain cleartext.
|
|
118
|
+
*/
|
|
119
|
+
committed_field_names?: string[];
|
|
120
|
+
};
|
|
98
121
|
}
|
|
99
122
|
interface RateLimit {
|
|
100
123
|
count: number;
|
|
@@ -825,6 +848,131 @@ declare function getSignerInfo(): {
|
|
|
825
848
|
*/
|
|
826
849
|
declare function isSigningEnabled(): boolean;
|
|
827
850
|
|
|
851
|
+
/**
|
|
852
|
+
* A Merkle inclusion proof for a single leaf.
|
|
853
|
+
*
|
|
854
|
+
* The siblings array lists the sibling hashes encountered while walking
|
|
855
|
+
* from the leaf up to the root. Each sibling is hex-encoded SHA-256.
|
|
856
|
+
* The (index, treeSize) pair determines whether the current node is
|
|
857
|
+
* left or right at each level during verification.
|
|
858
|
+
*/
|
|
859
|
+
interface MerkleProof {
|
|
860
|
+
/** Zero-based index of the leaf in the canonically-sorted leaf list. */
|
|
861
|
+
index: number;
|
|
862
|
+
/** Total number of leaves in the tree. */
|
|
863
|
+
treeSize: number;
|
|
864
|
+
/** Sibling hashes from leaf upward, hex-encoded SHA-256 (lowercase). */
|
|
865
|
+
siblings: string[];
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
/**
|
|
869
|
+
* @scopeblind/protect-mcp: Commitment-Mode Signing
|
|
870
|
+
*
|
|
871
|
+
* Produces commitment-mode signed receipts per draft-farley-acta-signed-receipts-01
|
|
872
|
+
* §commitment-mode. Each listed field is independently committed via
|
|
873
|
+
* SHA-256(0x00 || JCS({name, salt, value})), arranged into an RFC 6962-style
|
|
874
|
+
* Merkle tree with explicit one-byte domain separation, and the receipt payload
|
|
875
|
+
* carries a single committed_fields_root field instead of the cleartext values.
|
|
876
|
+
*
|
|
877
|
+
* The receipt holder retains openings (value + salt per field) and can selectively
|
|
878
|
+
* disclose any subset to auditors via Merkle inclusion proofs verifiable by
|
|
879
|
+
* @veritasacta/verify@>=0.6.0.
|
|
880
|
+
*
|
|
881
|
+
* This module sits alongside signing.ts (the legacy @veritasacta/artifacts-based
|
|
882
|
+
* cleartext path) and is invoked when SigningConfig.commitment_mode.enabled is
|
|
883
|
+
* true. The two paths are mutually exclusive on a per-receipt basis.
|
|
884
|
+
*
|
|
885
|
+
* @since 0.6.0
|
|
886
|
+
* @standard draft-farley-acta-signed-receipts-01 §commitment-mode
|
|
887
|
+
* @standard RFC 6962 (Certificate Transparency Merkle tree construction)
|
|
888
|
+
* @standard RFC 8032 (Ed25519)
|
|
889
|
+
* @standard RFC 8785 (JCS)
|
|
890
|
+
*/
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* The opening information for a single committed field. Held by the
|
|
894
|
+
* receipt issuer; never embedded in the published receipt. Required to
|
|
895
|
+
* later produce a selective-disclosure proof.
|
|
896
|
+
*/
|
|
897
|
+
interface CommittedFieldOpening {
|
|
898
|
+
/** Field name (matches one of committed_field_names). */
|
|
899
|
+
name: string;
|
|
900
|
+
/** Cleartext value of the field. */
|
|
901
|
+
value: unknown;
|
|
902
|
+
/** Salt bytes (32 random bytes per field per receipt). */
|
|
903
|
+
salt: Uint8Array;
|
|
904
|
+
/** Zero-based index of the field in the canonically-sorted leaf list. */
|
|
905
|
+
index: number;
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* The result of signing a decision in commitment mode.
|
|
909
|
+
*/
|
|
910
|
+
interface CommittedSignResult {
|
|
911
|
+
/** The signed receipt as a JSON string (canonical wire form). */
|
|
912
|
+
signed: string;
|
|
913
|
+
/** Receipt artifact type, e.g. "decision_receipt_committed_v1". */
|
|
914
|
+
artifact_type: string;
|
|
915
|
+
/**
|
|
916
|
+
* Per-field openings, indexed by field name. The issuer MUST persist
|
|
917
|
+
* these securely if it intends to support selective disclosure later.
|
|
918
|
+
* Storing them is the issuer's responsibility; this library does not
|
|
919
|
+
* write them to disk.
|
|
920
|
+
*/
|
|
921
|
+
openings: Record<string, CommittedFieldOpening>;
|
|
922
|
+
/** Lowercase hex SHA-256 of the canonical signed receipt. */
|
|
923
|
+
receipt_hash: string;
|
|
924
|
+
}
|
|
925
|
+
/**
|
|
926
|
+
* A minimal selective-disclosure envelope. Reveal a single committed field
|
|
927
|
+
* to an auditor by supplying its (name, value, salt, proof). The auditor
|
|
928
|
+
* recomputes the leaf hash and walks the proof to confirm it reconstructs
|
|
929
|
+
* the receipt's committed_fields_root.
|
|
930
|
+
*
|
|
931
|
+
* Compatible with @veritasacta/verify@>=0.6.0.
|
|
932
|
+
*/
|
|
933
|
+
interface MinimalDisclosure {
|
|
934
|
+
/** The receipt this disclosure targets, by canonical hash. */
|
|
935
|
+
parent_receipt_hash: string;
|
|
936
|
+
/** Disclosed field name. */
|
|
937
|
+
name: string;
|
|
938
|
+
/** Cleartext value of the disclosed field. */
|
|
939
|
+
value: unknown;
|
|
940
|
+
/** Salt as base64url (no padding). */
|
|
941
|
+
salt: string;
|
|
942
|
+
/** Merkle inclusion proof. */
|
|
943
|
+
proof: MerkleProof;
|
|
944
|
+
}
|
|
945
|
+
/**
|
|
946
|
+
* Sign a DecisionLog in commitment mode.
|
|
947
|
+
*
|
|
948
|
+
* @param entry - The decision log entry to sign.
|
|
949
|
+
* @param committedFieldNames - Names of fields to commit. Recommended:
|
|
950
|
+
* ["tool", "scope", "payload_digest", "swarm"]. Fields not listed
|
|
951
|
+
* remain cleartext in the signed payload.
|
|
952
|
+
* @param signingKey - Ed25519 private key (32 bytes hex or raw).
|
|
953
|
+
* @param publicKey - Ed25519 public key (32 bytes hex).
|
|
954
|
+
* @param kid - Key identifier (RFC 7638 JWK thumbprint or operator-chosen).
|
|
955
|
+
* @param issuer - Issuer identifier (e.g. "my-gateway.example.com").
|
|
956
|
+
*
|
|
957
|
+
* @returns Signed receipt JSON, openings (per field), and receipt hash.
|
|
958
|
+
*
|
|
959
|
+
* @standard draft-farley-acta-signed-receipts-01 §signature-scope
|
|
960
|
+
* The signature covers SHA-256(JCS(payload_minus_signature)).
|
|
961
|
+
*/
|
|
962
|
+
declare function signCommittedDecision(entry: DecisionLog, committedFieldNames: string[], signingKey: string, publicKey: string, kid: string, issuer: string): CommittedSignResult;
|
|
963
|
+
/**
|
|
964
|
+
* Build a minimal selective-disclosure envelope for a single committed
|
|
965
|
+
* field. The envelope can be verified offline by anyone who has the
|
|
966
|
+
* receipt's committed_fields_root (which the receipt itself carries).
|
|
967
|
+
*
|
|
968
|
+
* @param receiptHash - Canonical hash of the receipt the disclosure targets.
|
|
969
|
+
* @param fieldName - Which field to disclose.
|
|
970
|
+
* @param openings - The full openings map produced by signCommittedDecision.
|
|
971
|
+
*
|
|
972
|
+
* @standard draft-farley-acta-signed-receipts-01 §commitment-disclosure
|
|
973
|
+
*/
|
|
974
|
+
declare function discloseField(receiptHash: string, fieldName: string, openings: Record<string, CommittedFieldOpening>): MinimalDisclosure;
|
|
975
|
+
|
|
828
976
|
/**
|
|
829
977
|
* @scopeblind/protect-mcp — External PDP Adapter
|
|
830
978
|
*
|
|
@@ -2763,4 +2911,4 @@ declare function confidentialInference(_prompt: string, _config: ConfidentialInf
|
|
|
2763
2911
|
receipt: Record<string, unknown>;
|
|
2764
2912
|
}>;
|
|
2765
2913
|
|
|
2766
|
-
export { type ActionReceipt, type AdmissionResult, type AgentId, type AgentManifest, type ApprovalAssertion, type ApprovalChallenge, type ApprovalNotification, type ApprovalResult, type ArenaPayload, type ArenaReceipt, type AttestationDocument, type AttestationPayload, type AttestationProvider, type AttestationReceipt, type AttestationResult, type AuditBundle, type AuditBundleOptions, type BenchmarkPayload, type BenchmarkReceipt, type BuilderId, type C2PAAssertion, type C2PAIngredient, type C2PAManifest, type C2PAOptions, type CCRConnectorConfig, type CCRSessionContext, type CalibrationScore, type CedarEvalRequest, type CedarPolicySet, type CedarSchema, type CedarSchemaResult, type ComplianceReport, ConfidentialGate, type ConfidentialGateConfig, type ConfidentialInferenceConfig, type CredentialConfig, type DecisionContext, type DecisionLog, type DelegationReceipt, type DisclosureMode, type Ed25519PublicKey, type EvidenceAttestation, type EvidenceAttestationInput, type EvidenceIssuer, type EvidenceReceipt, type EvidenceReceiptBase, type EvidenceSummary, type EvidenceSummaryEntry, type EvidenceType, type ExternalDecision, type ExternalPDPConfig, type HFDatasetMetadata, type HFReceiptRow, type HookEventName, type HookInput, type HookResponse, type IssuerType, type JsonRpcRequest, type JsonRpcResponse, type LeaseCompatibility, type ManifestBuilder, type ManifestCapabilities, type ManifestConfig, type ManifestIdentity, type ManifestPresentation, type ManifestSignature, type ManifestStatus, type McpToolDescription, type NotificationConfig, type PassportTokenClaims, type PayloadDigest, type PlanReceipt, type PolicyEngineMode, type PredictionReceipt, type PredictionResolution, type PropagatorConfig, type ProtectConfig, ProtectGateway, type ProtectPolicy, type RateLimit, ReceiptPropagator, type RedactedResult, type RedactionSalt, type RekorAnchor, type RekorVerification, type RestraintPayload, type RestraintReceipt, type SHA256Hash, type SafetyTranscript, type Sandbox, type SandboxConfig, type SandboxReceipt, type SandboxResult, type SandboxToolCall, type SchemaGeneratorConfig, type SigningConfig, type SimulationResult, type SimulationSummary, type SwarmContext, type TierOverrides, type TimingMetrics, type ToolPolicy, type TrustTier, type WorkPayload, type WorkReceipt, anchorToRekor, buildDecisionContext, checkRateLimit, collectSignedReceipts, computeCalibration, confidentialInference, createApprovalChallenge, createApprovalReceiptPayload, createAttestationField, createAuditBundle, createC2PAManifest, createDisclosurePackage, createEvidenceAttestation, createLogAnchorField, createReceiptChannel, createSandbox, destroySandbox, ed25519ToDIDKey, evaluateCedar, evaluateTier, exportC2PAManifestJSON, exportJSONL, formatReportMarkdown, formatSimulation, generateC2PACommand, generateCedarSchema, generateDatasetCard, generateHFMetadata, generateReport, generateSafetyTranscript, generateSchemaStub, getSignerInfo, getToolPolicy, hashReceipt, hashResponseBody, initSigning, isAgentId, isCedarAvailable, isDisclosureMode, isEvidenceType, isManifestStatus, isSigningEnabled, listCredentialLabels, loadCedarPolicies, loadPolicy, manifestToVC, meetsMinTier, parseLogFile, parseNotificationConfigFromEnv, parseRateLimit, queryExternalPDP, receiptToVP, receiptsToHFRows, redactFields, resolveCredential, revealField, runInSandbox, sendApprovalNotification, signDecision, simulate, toCredentialRequestOptions, toManifoldFormat, toMetaculusFormat, validateCredentials, validateEvidenceReceipt, validateManifest, verifyActaC2PAAssertions, verifyAllCommitments, verifyApprovalAssertion, verifyCommitment, verifyEvidenceAttestation, verifyRekorAnchor };
|
|
2914
|
+
export { type ActionReceipt, type AdmissionResult, type AgentId, type AgentManifest, type ApprovalAssertion, type ApprovalChallenge, type ApprovalNotification, type ApprovalResult, type ArenaPayload, type ArenaReceipt, type AttestationDocument, type AttestationPayload, type AttestationProvider, type AttestationReceipt, type AttestationResult, type AuditBundle, type AuditBundleOptions, type BenchmarkPayload, type BenchmarkReceipt, type BuilderId, type C2PAAssertion, type C2PAIngredient, type C2PAManifest, type C2PAOptions, type CCRConnectorConfig, type CCRSessionContext, type CalibrationScore, type CedarEvalRequest, type CedarPolicySet, type CedarSchema, type CedarSchemaResult, type CommittedFieldOpening, type CommittedSignResult, type ComplianceReport, ConfidentialGate, type ConfidentialGateConfig, type ConfidentialInferenceConfig, type CredentialConfig, type DecisionContext, type DecisionLog, type DelegationReceipt, type DisclosureMode, type Ed25519PublicKey, type EvidenceAttestation, type EvidenceAttestationInput, type EvidenceIssuer, type EvidenceReceipt, type EvidenceReceiptBase, type EvidenceSummary, type EvidenceSummaryEntry, type EvidenceType, type ExternalDecision, type ExternalPDPConfig, type HFDatasetMetadata, type HFReceiptRow, type HookEventName, type HookInput, type HookResponse, type IssuerType, type JsonRpcRequest, type JsonRpcResponse, type LeaseCompatibility, type ManifestBuilder, type ManifestCapabilities, type ManifestConfig, type ManifestIdentity, type ManifestPresentation, type ManifestSignature, type ManifestStatus, type McpToolDescription, type MinimalDisclosure, type NotificationConfig, type PassportTokenClaims, type PayloadDigest, type PlanReceipt, type PolicyEngineMode, type PredictionReceipt, type PredictionResolution, type PropagatorConfig, type ProtectConfig, ProtectGateway, type ProtectPolicy, type RateLimit, ReceiptPropagator, type RedactedResult, type RedactionSalt, type RekorAnchor, type RekorVerification, type RestraintPayload, type RestraintReceipt, type SHA256Hash, type SafetyTranscript, type Sandbox, type SandboxConfig, type SandboxReceipt, type SandboxResult, type SandboxToolCall, type SchemaGeneratorConfig, type SigningConfig, type SimulationResult, type SimulationSummary, type SwarmContext, type TierOverrides, type TimingMetrics, type ToolPolicy, type TrustTier, type WorkPayload, type WorkReceipt, anchorToRekor, buildDecisionContext, checkRateLimit, collectSignedReceipts, computeCalibration, confidentialInference, createApprovalChallenge, createApprovalReceiptPayload, createAttestationField, createAuditBundle, createC2PAManifest, createDisclosurePackage, createEvidenceAttestation, createLogAnchorField, createReceiptChannel, createSandbox, destroySandbox, discloseField, ed25519ToDIDKey, evaluateCedar, evaluateTier, exportC2PAManifestJSON, exportJSONL, formatReportMarkdown, formatSimulation, generateC2PACommand, generateCedarSchema, generateDatasetCard, generateHFMetadata, generateReport, generateSafetyTranscript, generateSchemaStub, getSignerInfo, getToolPolicy, hashReceipt, hashResponseBody, initSigning, isAgentId, isCedarAvailable, isDisclosureMode, isEvidenceType, isManifestStatus, isSigningEnabled, listCredentialLabels, loadCedarPolicies, loadPolicy, manifestToVC, meetsMinTier, parseLogFile, parseNotificationConfigFromEnv, parseRateLimit, queryExternalPDP, receiptToVP, receiptsToHFRows, redactFields, resolveCredential, revealField, runInSandbox, sendApprovalNotification, signCommittedDecision, signDecision, simulate, toCredentialRequestOptions, toManifoldFormat, toMetaculusFormat, validateCredentials, validateEvidenceReceipt, validateManifest, verifyActaC2PAAssertions, verifyAllCommitments, verifyApprovalAssertion, verifyCommitment, verifyEvidenceAttestation, verifyRekorAnchor };
|