protect-mcp 0.9.2 → 0.9.4
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/CHANGELOG.md +49 -0
- package/README.md +41 -0
- package/dist/{chunk-CXW2EIRM.mjs → chunk-7MHK5RF4.mjs} +2 -2
- package/dist/{chunk-744JMCY4.mjs → chunk-H332ZNJ6.mjs} +2 -2
- package/dist/{chunk-GHR65WVD.mjs → chunk-PB3TC7E3.mjs} +1 -1
- package/dist/{chunk-KMNXHGGT.mjs → chunk-WWPQNIVF.mjs} +35 -2
- package/dist/{chunk-IDUH2O4Q.mjs → chunk-XLJUZ4WO.mjs} +7 -1
- package/dist/{claim-TUDH2WPB.mjs → claim-RIXFOQM7.mjs} +168 -16
- package/dist/cli.js +471 -33
- package/dist/cli.mjs +268 -21
- package/dist/hook-server.js +42 -3
- package/dist/hook-server.mjs +3 -3
- package/dist/{http-transport-D7C64PIA.mjs → http-transport-HLSMVBI6.mjs} +2 -2
- package/dist/index.d.mts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +42 -3
- package/dist/index.mjs +5 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -35540,7 +35540,13 @@ function signDecision(entry) {
|
|
|
35540
35540
|
// - scopeblind:verified = issued via ScopeBlind VOPRF backend (paid tier)
|
|
35541
35541
|
// - self-signed = signed with local Ed25519 key (free tier, protect-mcp default)
|
|
35542
35542
|
// - uncertified = unsigned receipt (shadow mode, no signing configured)
|
|
35543
|
-
issuer_certification: signerState ? "self-signed" : "uncertified"
|
|
35543
|
+
issuer_certification: signerState ? "self-signed" : "uncertified",
|
|
35544
|
+
// The signer's PUBLIC key, inside the signed payload, so a receipt is
|
|
35545
|
+
// self-contained: any verifier (including the record viewer, in-browser)
|
|
35546
|
+
// can check the signature without a side channel. Binding the key inside
|
|
35547
|
+
// the signature means it cannot be swapped without breaking the signature;
|
|
35548
|
+
// authenticity (that the key is YOUR gate's) still comes from pinning it.
|
|
35549
|
+
public_key: signerState.publicKey
|
|
35544
35550
|
};
|
|
35545
35551
|
if (entry.tier) payload.tier = entry.tier;
|
|
35546
35552
|
if (entry.credential_ref) payload.credential_ref = entry.credential_ref;
|
|
@@ -40362,7 +40368,7 @@ function forwardReceipt(signedReceipt) {
|
|
|
40362
40368
|
}
|
|
40363
40369
|
|
|
40364
40370
|
// src/receipt-enrichment.ts
|
|
40365
|
-
var ENRICHMENT_VERSION =
|
|
40371
|
+
var ENRICHMENT_VERSION = 2;
|
|
40366
40372
|
function canonicalJson(value) {
|
|
40367
40373
|
const seen = /* @__PURE__ */ new WeakSet();
|
|
40368
40374
|
const enc = (v) => {
|
|
@@ -40399,7 +40405,11 @@ var RULES = [
|
|
|
40399
40405
|
{ cap: "secret.adjacent", text: /\.env\b|secret|credential|passwd|password|api[_-]?key|private[_-]?key|\.pem\b|\.key\b|id_rsa|bearer\s|aws_(access|secret)|authorization/ },
|
|
40400
40406
|
{ cap: "destructive", text: /rm\s+-[a-z]*[rf]|\brmdir\b|drop\s+table|truncate\s+table|delete\s+from|reset\s+--hard|--force\b|\bmkfs\b|\bdd\s+if=|shutdown|reboot|kill\s+-9|>\s*\/dev\/sd/ },
|
|
40401
40407
|
{ cap: "financial", text: /\b(order|trade|buy|sell|transfer|wire|payment|withdraw|deposit|swap|invoice|charge|refund|settle)\b/ },
|
|
40402
|
-
{ cap: "data.query", text: /\bselect\s+[\s\S]+\bfrom\b|\binsert\s+into\b|\bupdate\s+[\s\S]+\bset\b|\bdelete\s+from\b/ }
|
|
40408
|
+
{ cap: "data.query", text: /\bselect\s+[\s\S]+\bfrom\b|\binsert\s+into\b|\bupdate\s+[\s\S]+\bset\b|\bdelete\s+from\b/ },
|
|
40409
|
+
// Agent payments (x402 / value transfer). Deliberately BROAD: a false positive
|
|
40410
|
+
// only makes a `claim --no payment` harder to assert (conservative); a false
|
|
40411
|
+
// negative would let a real payment escape the record's payment claims.
|
|
40412
|
+
{ cap: "payment", tool: /(^|[_.-])(pay|payment|x402|checkout)($|[_.-])|wallet.*send|send.*payment/, text: /x402|x-payment|paymentrequirements|maxamountrequired|payto|"pay_to"|eip-3009|transferwithauthorization|payment_intent|send_payment|create_payment/ }
|
|
40403
40413
|
];
|
|
40404
40414
|
function deriveCapabilities(tool, input) {
|
|
40405
40415
|
const t = String(tool || "").toLowerCase();
|
|
@@ -40433,6 +40443,33 @@ function deriveResource(input) {
|
|
|
40433
40443
|
}
|
|
40434
40444
|
return void 0;
|
|
40435
40445
|
}
|
|
40446
|
+
function findField(input, names, depth = 0) {
|
|
40447
|
+
if (depth > 4 || input === null || typeof input !== "object") return void 0;
|
|
40448
|
+
const o = input;
|
|
40449
|
+
const keys = Object.keys(o).sort();
|
|
40450
|
+
for (const k of keys) {
|
|
40451
|
+
if (names.indexOf(k.toLowerCase()) >= 0 && o[k] !== void 0 && o[k] !== null) return o[k];
|
|
40452
|
+
}
|
|
40453
|
+
for (const k of keys) {
|
|
40454
|
+
const v = findField(o[k], names, depth + 1);
|
|
40455
|
+
if (v !== void 0) return v;
|
|
40456
|
+
}
|
|
40457
|
+
return void 0;
|
|
40458
|
+
}
|
|
40459
|
+
function derivePayment(tool, input) {
|
|
40460
|
+
if (deriveCapabilities(tool, input).indexOf("payment") < 0) return void 0;
|
|
40461
|
+
const p = { amount: null, asset: null, recipient_digest: null };
|
|
40462
|
+
const amt = findField(input, ["amount"]);
|
|
40463
|
+
if (typeof amt === "number" && Number.isFinite(amt) && amt >= 0) p.amount = amt;
|
|
40464
|
+
else if (typeof amt === "string" && /^\d{1,15}(\.\d{1,18})?$/.test(amt.trim()) && amt.indexOf(".") >= 0) p.amount = parseFloat(amt);
|
|
40465
|
+
const asset = findField(input, ["asset", "currency", "token"]);
|
|
40466
|
+
if (typeof asset === "string" && asset.trim()) p.asset = asset.trim().slice(0, 64);
|
|
40467
|
+
const to = findField(input, ["payto", "pay_to", "recipient", "destination", "to"]);
|
|
40468
|
+
if (typeof to === "string" && to.trim()) p.recipient_digest = sha256Hex(to.trim().toLowerCase());
|
|
40469
|
+
const scheme = findField(input, ["scheme"]);
|
|
40470
|
+
if (typeof scheme === "string" && scheme.trim()) p.scheme = scheme.trim().slice(0, 32);
|
|
40471
|
+
return p;
|
|
40472
|
+
}
|
|
40436
40473
|
function buildEnrichment(tool, input) {
|
|
40437
40474
|
const e = {
|
|
40438
40475
|
v: ENRICHMENT_VERSION,
|
|
@@ -40441,6 +40478,8 @@ function buildEnrichment(tool, input) {
|
|
|
40441
40478
|
};
|
|
40442
40479
|
const resource = deriveResource(input);
|
|
40443
40480
|
if (resource) e.resource = resource;
|
|
40481
|
+
const payment = derivePayment(tool, input);
|
|
40482
|
+
if (payment) e.payment = payment;
|
|
40444
40483
|
return e;
|
|
40445
40484
|
}
|
|
40446
40485
|
|
package/dist/index.mjs
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
readInstalledConnectorPilots,
|
|
28
28
|
simulate,
|
|
29
29
|
writeConnectorPilots
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-7MHK5RF4.mjs";
|
|
31
31
|
import {
|
|
32
32
|
ProtectGateway,
|
|
33
33
|
buildDecisionContext,
|
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
resolveCredential,
|
|
40
40
|
sendApprovalNotification,
|
|
41
41
|
validateCredentials
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-PB3TC7E3.mjs";
|
|
43
43
|
import {
|
|
44
44
|
createSandboxServer
|
|
45
45
|
} from "./chunk-SETXVE2K.mjs";
|
|
@@ -54,8 +54,8 @@ import {
|
|
|
54
54
|
forwardReceipt,
|
|
55
55
|
getScopeBlindBridge,
|
|
56
56
|
startHookServer
|
|
57
|
-
} from "./chunk-
|
|
58
|
-
import "./chunk-
|
|
57
|
+
} from "./chunk-H332ZNJ6.mjs";
|
|
58
|
+
import "./chunk-WWPQNIVF.mjs";
|
|
59
59
|
import {
|
|
60
60
|
sha256 as sha2562
|
|
61
61
|
} from "./chunk-AYNQIEN7.mjs";
|
|
@@ -73,7 +73,7 @@ import {
|
|
|
73
73
|
policySetFromSource,
|
|
74
74
|
runEvaluatorSelfTest,
|
|
75
75
|
signDecision
|
|
76
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-XLJUZ4WO.mjs";
|
|
77
77
|
import {
|
|
78
78
|
Field,
|
|
79
79
|
_abool2,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "protect-mcp",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
4
4
|
"mcpName": "com.scopeblind/protect-mcp",
|
|
5
5
|
"description": "Fail-closed Cedar policy gate + Ed25519 signed receipts for AI agent tool calls. Denies on any policy error, proves the gate is live with a startup self-test, and turns every decision into a local searchable record you own. The open gate behind Legate by ScopeBlind. scopeblind.com",
|
|
6
6
|
"main": "dist/index.js",
|