protect-mcp 0.7.3 → 0.7.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 +48 -0
- package/README.md +155 -7
- package/dist/{bundle-XTR3YMPO.mjs → bundle-YUUHAG7O.mjs} +1 -1
- package/dist/chunk-36UID5WY.mjs +662 -0
- package/dist/{chunk-546U3A7R.mjs → chunk-D2RDY2JR.mjs} +92 -1
- package/dist/chunk-F2FKQ4XN.mjs +410 -0
- package/dist/{chunk-J6L4XCTE.mjs → chunk-KPSICBAJ.mjs} +75 -0
- package/dist/{chunk-G67NUBML.mjs → chunk-NVJHGXXG.mjs} +10 -2
- package/dist/{chunk-5JXFV37Y.mjs → chunk-PM2ZO57M.mjs} +10 -2
- package/dist/{chunk-OHUTUFTC.mjs → chunk-UBZJ3VI2.mjs} +19 -15
- package/dist/cli.js +4022 -512
- package/dist/cli.mjs +2027 -8
- package/dist/demo-server.d.mts +3 -0
- package/dist/demo-server.d.ts +3 -0
- package/dist/demo-server.js +75 -0
- package/dist/demo-server.mjs +1 -1
- package/dist/hook-server.js +117 -20
- package/dist/hook-server.mjs +2 -2
- package/dist/{http-transport-R5AO7X6D.mjs → http-transport-4GMMRPW7.mjs} +2 -2
- package/dist/index.d.mts +115 -1
- package/dist/index.d.ts +115 -1
- package/dist/index.js +961 -75
- package/dist/index.mjs +48 -249
- package/dist/receipt-registry-6CAOY6RP.mjs +279 -0
- package/dist/signing-committed-MMLJ6OGG.mjs +15 -0
- package/package.json +1 -1
- package/dist/chunk-ZBKJANP7.mjs +0 -145
package/dist/demo-server.d.mts
CHANGED
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
* - delete_file (destructive, blocked by default policy)
|
|
13
13
|
* - web_search (rate-limited)
|
|
14
14
|
* - deploy (high-privilege)
|
|
15
|
+
* - github_create_pr (source-control mutation)
|
|
16
|
+
* - send_email (external communication)
|
|
17
|
+
* - pms_book_fill (mock portfolio-management booking)
|
|
15
18
|
*/
|
|
16
19
|
/**
|
|
17
20
|
* Smithery sandbox server — returns a McpServer instance
|
package/dist/demo-server.d.ts
CHANGED
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
* - delete_file (destructive, blocked by default policy)
|
|
13
13
|
* - web_search (rate-limited)
|
|
14
14
|
* - deploy (high-privilege)
|
|
15
|
+
* - github_create_pr (source-control mutation)
|
|
16
|
+
* - send_email (external communication)
|
|
17
|
+
* - pms_book_fill (mock portfolio-management booking)
|
|
15
18
|
*/
|
|
16
19
|
/**
|
|
17
20
|
* Smithery sandbox server — returns a McpServer instance
|
package/dist/demo-server.js
CHANGED
|
@@ -35064,6 +35064,48 @@ var TOOLS = [
|
|
|
35064
35064
|
},
|
|
35065
35065
|
required: ["environment"]
|
|
35066
35066
|
}
|
|
35067
|
+
},
|
|
35068
|
+
{
|
|
35069
|
+
name: "github_create_pr",
|
|
35070
|
+
description: "Create a GitHub pull request",
|
|
35071
|
+
inputSchema: {
|
|
35072
|
+
type: "object",
|
|
35073
|
+
properties: {
|
|
35074
|
+
repo: { type: "string", description: "Repository name" },
|
|
35075
|
+
branch: { type: "string", description: "Source branch" },
|
|
35076
|
+
title: { type: "string", description: "Pull request title" }
|
|
35077
|
+
},
|
|
35078
|
+
required: ["repo", "branch", "title"]
|
|
35079
|
+
}
|
|
35080
|
+
},
|
|
35081
|
+
{
|
|
35082
|
+
name: "send_email",
|
|
35083
|
+
description: "Send an email",
|
|
35084
|
+
inputSchema: {
|
|
35085
|
+
type: "object",
|
|
35086
|
+
properties: {
|
|
35087
|
+
to: { type: "string", description: "Recipient email address" },
|
|
35088
|
+
subject: { type: "string", description: "Subject line" },
|
|
35089
|
+
body: { type: "string", description: "Message body" }
|
|
35090
|
+
},
|
|
35091
|
+
required: ["to", "subject"]
|
|
35092
|
+
}
|
|
35093
|
+
},
|
|
35094
|
+
{
|
|
35095
|
+
name: "pms_book_fill",
|
|
35096
|
+
description: "Book a fill into the mock portfolio management system",
|
|
35097
|
+
inputSchema: {
|
|
35098
|
+
type: "object",
|
|
35099
|
+
properties: {
|
|
35100
|
+
account: { type: "string", description: "Portfolio or fund account" },
|
|
35101
|
+
symbol: { type: "string", description: "Instrument symbol" },
|
|
35102
|
+
side: { type: "string", enum: ["BUY", "SELL"] },
|
|
35103
|
+
quantity: { type: "number" },
|
|
35104
|
+
price: { type: "number" },
|
|
35105
|
+
strategy: { type: "string" }
|
|
35106
|
+
},
|
|
35107
|
+
required: ["account", "symbol", "side", "quantity", "price"]
|
|
35108
|
+
}
|
|
35067
35109
|
}
|
|
35068
35110
|
];
|
|
35069
35111
|
function handleRequest(request) {
|
|
@@ -35111,6 +35153,15 @@ Contents: Hello from protect-mcp demo server!`;
|
|
|
35111
35153
|
case "deploy":
|
|
35112
35154
|
resultText = `[demo] Deployed to ${args.environment || "staging"}${args.reason ? ` (reason: ${args.reason})` : ""}`;
|
|
35113
35155
|
break;
|
|
35156
|
+
case "github_create_pr":
|
|
35157
|
+
resultText = `[demo] Created PR in ${args.repo || "scopeblind/demo"} from ${args.branch || "agent/demo"}: ${args.title || "Agent change"}`;
|
|
35158
|
+
break;
|
|
35159
|
+
case "send_email":
|
|
35160
|
+
resultText = `[demo] Drafted email to ${args.to || "pm@example.com"}: ${args.subject || "Agent update"}`;
|
|
35161
|
+
break;
|
|
35162
|
+
case "pms_book_fill":
|
|
35163
|
+
resultText = `[demo] Booked ${args.side || "BUY"} ${args.quantity || 0} ${args.symbol || "AAPL"} @ ${args.price || 0} into ${args.account || "Demo Fund"} (${args.strategy || "Unassigned"})`;
|
|
35164
|
+
break;
|
|
35114
35165
|
default:
|
|
35115
35166
|
resultText = `[demo] Unknown tool: ${toolName}`;
|
|
35116
35167
|
}
|
|
@@ -35183,6 +35234,30 @@ function createSandboxServer() {
|
|
|
35183
35234
|
{ environment: z.enum(["staging", "production"]).describe("Target environment"), reason: z.string().optional().describe("Deployment reason") },
|
|
35184
35235
|
async (args) => ({ content: [{ type: "text", text: `[demo] Deployed to ${args.environment}` }] })
|
|
35185
35236
|
);
|
|
35237
|
+
server.tool("github_create_pr", "Create a GitHub pull request", {
|
|
35238
|
+
repo: z.string(),
|
|
35239
|
+
branch: z.string(),
|
|
35240
|
+
title: z.string()
|
|
35241
|
+
}, async (args) => ({
|
|
35242
|
+
content: [{ type: "text", text: `[demo] PR created in ${args.repo} from ${args.branch}: ${args.title}` }]
|
|
35243
|
+
}));
|
|
35244
|
+
server.tool("send_email", "Send an email", {
|
|
35245
|
+
to: z.string(),
|
|
35246
|
+
subject: z.string(),
|
|
35247
|
+
body: z.string().optional()
|
|
35248
|
+
}, async (args) => ({
|
|
35249
|
+
content: [{ type: "text", text: `[demo] Email prepared for ${args.to}: ${args.subject}` }]
|
|
35250
|
+
}));
|
|
35251
|
+
server.tool("pms_book_fill", "Book a fill into a mock PMS", {
|
|
35252
|
+
account: z.string(),
|
|
35253
|
+
symbol: z.string(),
|
|
35254
|
+
side: z.enum(["BUY", "SELL"]),
|
|
35255
|
+
quantity: z.number(),
|
|
35256
|
+
price: z.number(),
|
|
35257
|
+
strategy: z.string().optional()
|
|
35258
|
+
}, async (args) => ({
|
|
35259
|
+
content: [{ type: "text", text: `[demo] Booked ${args.side} ${args.quantity} ${args.symbol} @ ${args.price} into ${args.account}` }]
|
|
35260
|
+
}));
|
|
35186
35261
|
return server;
|
|
35187
35262
|
}
|
|
35188
35263
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/demo-server.mjs
CHANGED
package/dist/hook-server.js
CHANGED
|
@@ -24,7 +24,7 @@ __export(hook_server_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(hook_server_exports);
|
|
26
26
|
var import_node_http2 = require("http");
|
|
27
|
-
var
|
|
27
|
+
var import_node_crypto4 = require("crypto");
|
|
28
28
|
var import_node_fs5 = require("fs");
|
|
29
29
|
var import_node_path3 = require("path");
|
|
30
30
|
|
|
@@ -320,6 +320,7 @@ function signDecision(entry) {
|
|
|
320
320
|
if (entry.timing) payload.timing = entry.timing;
|
|
321
321
|
if (entry.swarm) payload.swarm = entry.swarm;
|
|
322
322
|
if (entry.payload_digest) payload.payload_digest = entry.payload_digest;
|
|
323
|
+
if (entry.action_readback) payload.action_readback = entry.action_readback;
|
|
323
324
|
if (entry.deny_iteration) payload.deny_iteration = entry.deny_iteration;
|
|
324
325
|
const result = artifactsModule.createSignedArtifact(
|
|
325
326
|
artifactType,
|
|
@@ -613,6 +614,95 @@ function getScopeBlindBridge() {
|
|
|
613
614
|
return singleton;
|
|
614
615
|
}
|
|
615
616
|
|
|
617
|
+
// src/action-readback.ts
|
|
618
|
+
var import_node_crypto3 = require("crypto");
|
|
619
|
+
var SECRET_KEY_RE = /(api[_-]?key|authorization|bearer|credential|password|secret|session|token|private[_-]?key)/i;
|
|
620
|
+
var DESTINATION_KEYS = [
|
|
621
|
+
"path",
|
|
622
|
+
"file_path",
|
|
623
|
+
"filePath",
|
|
624
|
+
"url",
|
|
625
|
+
"uri",
|
|
626
|
+
"endpoint",
|
|
627
|
+
"host",
|
|
628
|
+
"hostname",
|
|
629
|
+
"repo",
|
|
630
|
+
"repository",
|
|
631
|
+
"branch",
|
|
632
|
+
"channel",
|
|
633
|
+
"to",
|
|
634
|
+
"recipient",
|
|
635
|
+
"symbol",
|
|
636
|
+
"account",
|
|
637
|
+
"bucket",
|
|
638
|
+
"database",
|
|
639
|
+
"table",
|
|
640
|
+
"service"
|
|
641
|
+
];
|
|
642
|
+
function stableStringify(value) {
|
|
643
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
644
|
+
if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
|
|
645
|
+
const obj = value;
|
|
646
|
+
return `{${Object.keys(obj).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(obj[key])}`).join(",")}}`;
|
|
647
|
+
}
|
|
648
|
+
function redact(value, path = [], redacted = [], disclosed = [], depth = 0) {
|
|
649
|
+
if (depth > 4) return "[truncated-depth]";
|
|
650
|
+
if (value === null || value === void 0) return value;
|
|
651
|
+
if (typeof value !== "object") {
|
|
652
|
+
if (path.length > 0) disclosed.push(path.join("."));
|
|
653
|
+
if (typeof value === "string" && value.length > 240) return `${value.slice(0, 240)}...`;
|
|
654
|
+
return value;
|
|
655
|
+
}
|
|
656
|
+
if (Array.isArray(value)) {
|
|
657
|
+
return value.slice(0, 20).map((item, idx) => redact(item, [...path, String(idx)], redacted, disclosed, depth + 1));
|
|
658
|
+
}
|
|
659
|
+
const out = {};
|
|
660
|
+
for (const [key, child] of Object.entries(value)) {
|
|
661
|
+
const childPath = [...path, key];
|
|
662
|
+
if (SECRET_KEY_RE.test(key)) {
|
|
663
|
+
redacted.push(childPath.join("."));
|
|
664
|
+
out[key] = "[redacted]";
|
|
665
|
+
continue;
|
|
666
|
+
}
|
|
667
|
+
out[key] = redact(child, childPath, redacted, disclosed, depth + 1);
|
|
668
|
+
}
|
|
669
|
+
return out;
|
|
670
|
+
}
|
|
671
|
+
function firstStringValue(input, keys) {
|
|
672
|
+
for (const key of keys) {
|
|
673
|
+
const value = input[key];
|
|
674
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
675
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
676
|
+
}
|
|
677
|
+
return void 0;
|
|
678
|
+
}
|
|
679
|
+
function actionFor(tool, input) {
|
|
680
|
+
const explicit = firstStringValue(input, ["action", "operation", "method", "verb", "command"]);
|
|
681
|
+
if (explicit) return explicit.length > 90 ? `${explicit.slice(0, 90)}...` : explicit;
|
|
682
|
+
return tool;
|
|
683
|
+
}
|
|
684
|
+
function buildActionReadback(tool, input) {
|
|
685
|
+
const normalized = input && typeof input === "object" && !Array.isArray(input) ? input : { value: input };
|
|
686
|
+
const canonical = stableStringify(normalized);
|
|
687
|
+
const redactedFields = [];
|
|
688
|
+
const disclosedFields = [];
|
|
689
|
+
const payloadPreview = redact(normalized, [], redactedFields, disclosedFields);
|
|
690
|
+
const action = actionFor(tool, normalized);
|
|
691
|
+
const destination = firstStringValue(normalized, DESTINATION_KEYS);
|
|
692
|
+
const summary = destination ? `${tool} -> ${destination}` : `${tool} request`;
|
|
693
|
+
return {
|
|
694
|
+
tool,
|
|
695
|
+
action,
|
|
696
|
+
destination,
|
|
697
|
+
payload_preview: payloadPreview,
|
|
698
|
+
payload_hash: (0, import_node_crypto3.createHash)("sha256").update(canonical).digest("hex"),
|
|
699
|
+
payload_bytes: Buffer.byteLength(canonical, "utf-8"),
|
|
700
|
+
disclosed_fields: [...new Set(disclosedFields)].slice(0, 80),
|
|
701
|
+
redacted_fields: [...new Set(redactedFields)].slice(0, 80),
|
|
702
|
+
summary
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
|
|
616
706
|
// src/hook-server.ts
|
|
617
707
|
var DEFAULT_PORT = 9377;
|
|
618
708
|
var LOG_FILE = ".protect-mcp-log.jsonl";
|
|
@@ -641,7 +731,7 @@ function computePayloadDigest(input) {
|
|
|
641
731
|
return void 0;
|
|
642
732
|
}
|
|
643
733
|
return {
|
|
644
|
-
input_hash: (0,
|
|
734
|
+
input_hash: (0, import_node_crypto4.createHash)("sha256").update(content).digest("hex"),
|
|
645
735
|
input_size: size,
|
|
646
736
|
truncated: true,
|
|
647
737
|
preview: content.slice(0, 256)
|
|
@@ -654,7 +744,7 @@ function computeOutputDigest(output) {
|
|
|
654
744
|
return void 0;
|
|
655
745
|
}
|
|
656
746
|
return {
|
|
657
|
-
output_hash: (0,
|
|
747
|
+
output_hash: (0, import_node_crypto4.createHash)("sha256").update(content).digest("hex"),
|
|
658
748
|
output_size: size
|
|
659
749
|
};
|
|
660
750
|
}
|
|
@@ -677,13 +767,14 @@ function detectSandboxState() {
|
|
|
677
767
|
async function handlePreToolUse(input, state) {
|
|
678
768
|
const hookStart = Date.now();
|
|
679
769
|
const toolName = input.toolName || "unknown";
|
|
680
|
-
const requestId = input.toolUseId || (0,
|
|
770
|
+
const requestId = input.toolUseId || (0, import_node_crypto4.randomUUID)().slice(0, 12);
|
|
681
771
|
state.inflightTools.set(requestId, {
|
|
682
772
|
tool: toolName,
|
|
683
773
|
startedAt: hookStart,
|
|
684
774
|
requestId
|
|
685
775
|
});
|
|
686
776
|
const payloadDigest = computePayloadDigest(input.toolInput);
|
|
777
|
+
const actionReadback = buildActionReadback(toolName, input.toolInput || {});
|
|
687
778
|
const swarm = {
|
|
688
779
|
...state.swarmContext,
|
|
689
780
|
...input.agentId && { agent_id: input.agentId },
|
|
@@ -723,6 +814,7 @@ async function handlePreToolUse(input, state) {
|
|
|
723
814
|
swarm: swarm.team_name ? swarm : void 0,
|
|
724
815
|
timing: { hook_latency_ms: hookLatency2, started_at: hookStart },
|
|
725
816
|
payload_digest: payloadDigest,
|
|
817
|
+
action_readback: actionReadback,
|
|
726
818
|
deny_iteration: denyCount,
|
|
727
819
|
sandbox_state: detectSandboxState(),
|
|
728
820
|
plan_receipt_id: state.activePlanReceiptId || void 0
|
|
@@ -757,6 +849,7 @@ async function handlePreToolUse(input, state) {
|
|
|
757
849
|
swarm: swarm.team_name ? swarm : void 0,
|
|
758
850
|
timing: { hook_latency_ms: hookLatency2, started_at: hookStart },
|
|
759
851
|
payload_digest: payloadDigest,
|
|
852
|
+
action_readback: actionReadback,
|
|
760
853
|
sandbox_state: detectSandboxState()
|
|
761
854
|
});
|
|
762
855
|
return {
|
|
@@ -781,6 +874,7 @@ async function handlePreToolUse(input, state) {
|
|
|
781
874
|
swarm: swarm.team_name ? swarm : void 0,
|
|
782
875
|
timing: { hook_latency_ms: hookLatency2, started_at: hookStart },
|
|
783
876
|
payload_digest: payloadDigest,
|
|
877
|
+
action_readback: actionReadback,
|
|
784
878
|
sandbox_state: detectSandboxState()
|
|
785
879
|
});
|
|
786
880
|
return {
|
|
@@ -801,13 +895,15 @@ async function handlePreToolUse(input, state) {
|
|
|
801
895
|
hook_event: "PreToolUse",
|
|
802
896
|
swarm: swarm.team_name ? swarm : void 0,
|
|
803
897
|
timing: { hook_latency_ms: hookLatency2, started_at: hookStart },
|
|
898
|
+
payload_digest: payloadDigest,
|
|
899
|
+
action_readback: actionReadback,
|
|
804
900
|
sandbox_state: detectSandboxState()
|
|
805
901
|
});
|
|
806
902
|
return {
|
|
807
903
|
hookSpecificOutput: {
|
|
808
904
|
hookEventName: "PreToolUse",
|
|
809
905
|
permissionDecision: "ask",
|
|
810
|
-
permissionDecisionReason: `[ScopeBlind]
|
|
906
|
+
permissionDecisionReason: `[ScopeBlind] Approval required for exactly this action: ${actionReadback.summary}. Payload hash: ${actionReadback.payload_hash.slice(0, 16)}\u2026 Policy: ${state.policyDigest}`
|
|
811
907
|
}
|
|
812
908
|
};
|
|
813
909
|
}
|
|
@@ -852,6 +948,7 @@ async function handlePreToolUse(input, state) {
|
|
|
852
948
|
swarm: swarm.team_name ? swarm : void 0,
|
|
853
949
|
timing: { hook_latency_ms: hookLatency, started_at: hookStart },
|
|
854
950
|
payload_digest: payloadDigest,
|
|
951
|
+
action_readback: actionReadback,
|
|
855
952
|
sandbox_state: detectSandboxState(),
|
|
856
953
|
plan_receipt_id: state.activePlanReceiptId || void 0
|
|
857
954
|
});
|
|
@@ -868,7 +965,7 @@ async function handlePreToolUse(input, state) {
|
|
|
868
965
|
}
|
|
869
966
|
async function handlePostToolUse(input, state) {
|
|
870
967
|
const toolName = input.toolName || "unknown";
|
|
871
|
-
const requestId = input.toolUseId || (0,
|
|
968
|
+
const requestId = input.toolUseId || (0, import_node_crypto4.randomUUID)().slice(0, 12);
|
|
872
969
|
const now = Date.now();
|
|
873
970
|
const inflight = state.inflightTools.get(requestId);
|
|
874
971
|
const timing = {
|
|
@@ -880,7 +977,7 @@ async function handlePostToolUse(input, state) {
|
|
|
880
977
|
state.inflightTools.delete(requestId);
|
|
881
978
|
}
|
|
882
979
|
const outputDigest = computeOutputDigest(input.toolResult);
|
|
883
|
-
const receiptId = (0,
|
|
980
|
+
const receiptId = (0, import_node_crypto4.randomUUID)().slice(0, 8);
|
|
884
981
|
const policyName = state.cedarPolicies ? `cedar:${state.policyDigest}` : state.policyDigest;
|
|
885
982
|
const additionalContext = `[ScopeBlind] Tool call receipted. Policy: ${policyName}. Decision: allow. Receipt: #${receiptId}.` + (timing.tool_duration_ms !== void 0 ? ` Duration: ${timing.tool_duration_ms}ms.` : "") + (timing.hook_latency_ms !== void 0 ? ` Overhead: ${timing.hook_latency_ms}ms.` : "");
|
|
886
983
|
emitDecisionLog(state, {
|
|
@@ -912,7 +1009,7 @@ function handleSubagentStart(input, state) {
|
|
|
912
1009
|
tool: `subagent:${agentId}`,
|
|
913
1010
|
decision: "allow",
|
|
914
1011
|
reason_code: "subagent_started",
|
|
915
|
-
request_id: (0,
|
|
1012
|
+
request_id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
|
|
916
1013
|
hook_event: "SubagentStart",
|
|
917
1014
|
swarm: {
|
|
918
1015
|
...state.swarmContext,
|
|
@@ -933,7 +1030,7 @@ function handleSubagentStop(input, state) {
|
|
|
933
1030
|
tool: `subagent:${agentId}`,
|
|
934
1031
|
decision: "allow",
|
|
935
1032
|
reason_code: "subagent_stopped",
|
|
936
|
-
request_id: (0,
|
|
1033
|
+
request_id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
|
|
937
1034
|
hook_event: "SubagentStop",
|
|
938
1035
|
swarm: {
|
|
939
1036
|
...state.swarmContext,
|
|
@@ -948,7 +1045,7 @@ function handleTaskCreated(input, state) {
|
|
|
948
1045
|
tool: `task:${input.taskId || "unknown"}`,
|
|
949
1046
|
decision: "allow",
|
|
950
1047
|
reason_code: "task_created",
|
|
951
|
-
request_id: (0,
|
|
1048
|
+
request_id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
|
|
952
1049
|
hook_event: "TaskCreated",
|
|
953
1050
|
swarm: {
|
|
954
1051
|
...state.swarmContext,
|
|
@@ -962,7 +1059,7 @@ function handleTaskCompleted(input, state) {
|
|
|
962
1059
|
tool: `task:${input.taskId || "unknown"}`,
|
|
963
1060
|
decision: "allow",
|
|
964
1061
|
reason_code: "task_completed",
|
|
965
|
-
request_id: (0,
|
|
1062
|
+
request_id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
|
|
966
1063
|
hook_event: "TaskCompleted",
|
|
967
1064
|
swarm: state.swarmContext
|
|
968
1065
|
});
|
|
@@ -973,7 +1070,7 @@ function handleSessionStart(input, state) {
|
|
|
973
1070
|
tool: "session",
|
|
974
1071
|
decision: "allow",
|
|
975
1072
|
reason_code: "session_started",
|
|
976
|
-
request_id: input.sessionId || (0,
|
|
1073
|
+
request_id: input.sessionId || (0, import_node_crypto4.randomUUID)().slice(0, 12),
|
|
977
1074
|
hook_event: "SessionStart",
|
|
978
1075
|
swarm: state.swarmContext,
|
|
979
1076
|
sandbox_state: detectSandboxState()
|
|
@@ -996,7 +1093,7 @@ function handleSessionEnd(input, state) {
|
|
|
996
1093
|
tool: "session",
|
|
997
1094
|
decision: "allow",
|
|
998
1095
|
reason_code: "session_ended",
|
|
999
|
-
request_id: input.sessionId || (0,
|
|
1096
|
+
request_id: input.sessionId || (0, import_node_crypto4.randomUUID)().slice(0, 12),
|
|
1000
1097
|
hook_event: "SessionEnd",
|
|
1001
1098
|
swarm: state.swarmContext
|
|
1002
1099
|
});
|
|
@@ -1007,7 +1104,7 @@ function handleTeammateIdle(input, state) {
|
|
|
1007
1104
|
tool: `teammate:${input.agentId || "unknown"}`,
|
|
1008
1105
|
decision: "allow",
|
|
1009
1106
|
reason_code: "teammate_idle",
|
|
1010
|
-
request_id: (0,
|
|
1107
|
+
request_id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
|
|
1011
1108
|
hook_event: "TeammateIdle",
|
|
1012
1109
|
swarm: {
|
|
1013
1110
|
...state.swarmContext,
|
|
@@ -1035,7 +1132,7 @@ function handleConfigChange(input, state) {
|
|
|
1035
1132
|
tool: "config",
|
|
1036
1133
|
decision: "deny",
|
|
1037
1134
|
reason_code: "config_tamper_detected",
|
|
1038
|
-
request_id: (0,
|
|
1135
|
+
request_id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
|
|
1039
1136
|
hook_event: "ConfigChange",
|
|
1040
1137
|
swarm: state.swarmContext
|
|
1041
1138
|
});
|
|
@@ -1044,7 +1141,7 @@ function handleConfigChange(input, state) {
|
|
|
1044
1141
|
tool: "config",
|
|
1045
1142
|
decision: "allow",
|
|
1046
1143
|
reason_code: "config_changed",
|
|
1047
|
-
request_id: (0,
|
|
1144
|
+
request_id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
|
|
1048
1145
|
hook_event: "ConfigChange"
|
|
1049
1146
|
});
|
|
1050
1147
|
}
|
|
@@ -1066,7 +1163,7 @@ function handleStop(input, state) {
|
|
|
1066
1163
|
tool: "session",
|
|
1067
1164
|
decision: "allow",
|
|
1068
1165
|
reason_code: "agent_stopped",
|
|
1069
|
-
request_id: (0,
|
|
1166
|
+
request_id: (0, import_node_crypto4.randomUUID)().slice(0, 12),
|
|
1070
1167
|
hook_event: "Stop",
|
|
1071
1168
|
swarm: state.swarmContext
|
|
1072
1169
|
});
|
|
@@ -1074,8 +1171,8 @@ function handleStop(input, state) {
|
|
|
1074
1171
|
}
|
|
1075
1172
|
function emitDecisionLog(state, entry) {
|
|
1076
1173
|
const mode = state.enforce ? "enforce" : "shadow";
|
|
1077
|
-
const otelTraceId = (0,
|
|
1078
|
-
const otelSpanId = (0,
|
|
1174
|
+
const otelTraceId = (0, import_node_crypto4.randomBytes)(16).toString("hex");
|
|
1175
|
+
const otelSpanId = (0, import_node_crypto4.randomBytes)(8).toString("hex");
|
|
1079
1176
|
const log = {
|
|
1080
1177
|
v: 2,
|
|
1081
1178
|
tool: entry.tool || "unknown",
|
|
@@ -1083,7 +1180,7 @@ function emitDecisionLog(state, entry) {
|
|
|
1083
1180
|
reason_code: entry.reason_code || "default_allow",
|
|
1084
1181
|
policy_digest: state.policyDigest,
|
|
1085
1182
|
policy_engine: state.cedarPolicies ? "cedar" : "built-in",
|
|
1086
|
-
request_id: entry.request_id || (0,
|
|
1183
|
+
request_id: entry.request_id || (0, import_node_crypto4.randomUUID)().slice(0, 12),
|
|
1087
1184
|
timestamp: Date.now(),
|
|
1088
1185
|
mode,
|
|
1089
1186
|
otel_trace_id: otelTraceId,
|
package/dist/hook-server.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -190,6 +190,18 @@ interface DecisionLog {
|
|
|
190
190
|
plan_receipt_id?: string;
|
|
191
191
|
/** Hook event that triggered this log entry */
|
|
192
192
|
hook_event?: HookEventName;
|
|
193
|
+
/** Redacted exact-action readback shown to humans before approving */
|
|
194
|
+
action_readback?: {
|
|
195
|
+
tool: string;
|
|
196
|
+
action: string;
|
|
197
|
+
destination?: string;
|
|
198
|
+
payload_preview: unknown;
|
|
199
|
+
payload_hash: string;
|
|
200
|
+
payload_bytes: number;
|
|
201
|
+
disclosed_fields: string[];
|
|
202
|
+
redacted_fields: string[];
|
|
203
|
+
summary: string;
|
|
204
|
+
};
|
|
193
205
|
/** IETF specification version — ties every receipt to the standard */
|
|
194
206
|
spec?: string;
|
|
195
207
|
/** Issuer certification level:
|
|
@@ -977,6 +989,31 @@ interface MinimalDisclosure {
|
|
|
977
989
|
/** Merkle inclusion proof. */
|
|
978
990
|
proof: MerkleProof;
|
|
979
991
|
}
|
|
992
|
+
interface SelectiveDisclosurePackageV0 {
|
|
993
|
+
type: 'scopeblind.selective_disclosure.v0';
|
|
994
|
+
version: 0;
|
|
995
|
+
parent_receipt_hash: string;
|
|
996
|
+
committed_fields_root: string;
|
|
997
|
+
disclosed_fields: string[];
|
|
998
|
+
hidden_fields: string[];
|
|
999
|
+
disclosures: MinimalDisclosure[];
|
|
1000
|
+
verifier_explanation: {
|
|
1001
|
+
summary: string;
|
|
1002
|
+
disclosed: string;
|
|
1003
|
+
hidden: string;
|
|
1004
|
+
limitation: string;
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
interface SelectiveDisclosureVerification {
|
|
1008
|
+
valid: boolean;
|
|
1009
|
+
receipt_hash_valid: boolean;
|
|
1010
|
+
signature_valid: boolean | null;
|
|
1011
|
+
commitment_root_valid: boolean;
|
|
1012
|
+
disclosed_fields: string[];
|
|
1013
|
+
hidden_fields: string[];
|
|
1014
|
+
errors: string[];
|
|
1015
|
+
explanation: string[];
|
|
1016
|
+
}
|
|
980
1017
|
/**
|
|
981
1018
|
* Sign a DecisionLog in commitment mode.
|
|
982
1019
|
*
|
|
@@ -1007,6 +1044,8 @@ declare function signCommittedDecision(entry: DecisionLog, committedFieldNames:
|
|
|
1007
1044
|
* @standard draft-farley-acta-signed-receipts-01 §commitment-disclosure
|
|
1008
1045
|
*/
|
|
1009
1046
|
declare function discloseField(receiptHash: string, fieldName: string, openings: Record<string, CommittedFieldOpening>): MinimalDisclosure;
|
|
1047
|
+
declare function createSelectiveDisclosurePackage(receipt: Record<string, unknown>, fieldNames: string[], openings: Record<string, CommittedFieldOpening>): SelectiveDisclosurePackageV0;
|
|
1048
|
+
declare function verifySelectiveDisclosurePackage(receipt: Record<string, unknown>, disclosure: SelectiveDisclosurePackageV0): SelectiveDisclosureVerification;
|
|
1010
1049
|
|
|
1011
1050
|
/**
|
|
1012
1051
|
* @scopeblind/protect-mcp — External PDP Adapter
|
|
@@ -1076,6 +1115,8 @@ interface AuditBundleOptions {
|
|
|
1076
1115
|
receipts: Record<string, unknown>[];
|
|
1077
1116
|
/** Optional audit anchors */
|
|
1078
1117
|
anchors?: Record<string, unknown>[];
|
|
1118
|
+
/** Optional selective-disclosure packages opening selected committed fields */
|
|
1119
|
+
selectiveDisclosures?: SelectiveDisclosurePackageV0[];
|
|
1079
1120
|
/** JWK signing keys used by the receipts */
|
|
1080
1121
|
signingKeys: Array<{
|
|
1081
1122
|
kty: string;
|
|
@@ -1096,6 +1137,14 @@ interface AuditBundle {
|
|
|
1096
1137
|
} | null;
|
|
1097
1138
|
receipts: Record<string, unknown>[];
|
|
1098
1139
|
anchors: Record<string, unknown>[];
|
|
1140
|
+
selective_disclosures: SelectiveDisclosurePackageV0[];
|
|
1141
|
+
privacy: {
|
|
1142
|
+
selective_disclosure: {
|
|
1143
|
+
supported: true;
|
|
1144
|
+
model: 'salted_commitments_merkle_v0';
|
|
1145
|
+
statement: string;
|
|
1146
|
+
};
|
|
1147
|
+
};
|
|
1099
1148
|
verification: {
|
|
1100
1149
|
algorithm: 'ed25519';
|
|
1101
1150
|
signing_keys: Array<{
|
|
@@ -1620,6 +1669,71 @@ declare function generateCedarSchema(tools: McpToolDescription[], config?: Schem
|
|
|
1620
1669
|
*/
|
|
1621
1670
|
declare function generateSchemaStub(namespace?: string): string;
|
|
1622
1671
|
|
|
1672
|
+
interface PolicyPack {
|
|
1673
|
+
id: string;
|
|
1674
|
+
name: string;
|
|
1675
|
+
description: string;
|
|
1676
|
+
recommendedMode: 'shadow-first' | 'enforce-ready';
|
|
1677
|
+
files: Array<{
|
|
1678
|
+
path: string;
|
|
1679
|
+
contents: string;
|
|
1680
|
+
}>;
|
|
1681
|
+
}
|
|
1682
|
+
declare const POLICY_PACKS: PolicyPack[];
|
|
1683
|
+
declare function getPolicyPack(id: string): PolicyPack | undefined;
|
|
1684
|
+
declare function policyPackIds(): string[];
|
|
1685
|
+
|
|
1686
|
+
type ConnectorPilotId = 'github' | 'email-gmail' | 'filesystem-git' | 'slack-teams' | 'finance-pms';
|
|
1687
|
+
interface ConnectorEnvVar {
|
|
1688
|
+
name: string;
|
|
1689
|
+
required: boolean;
|
|
1690
|
+
description: string;
|
|
1691
|
+
}
|
|
1692
|
+
interface ConnectorAction {
|
|
1693
|
+
name: string;
|
|
1694
|
+
tool: string;
|
|
1695
|
+
risk: 'low' | 'medium' | 'high';
|
|
1696
|
+
mode: 'observe' | 'require_approval' | 'deny';
|
|
1697
|
+
description: string;
|
|
1698
|
+
}
|
|
1699
|
+
interface ConnectorPilot {
|
|
1700
|
+
id: ConnectorPilotId;
|
|
1701
|
+
category: string;
|
|
1702
|
+
name: string;
|
|
1703
|
+
status: 'usable-pilot';
|
|
1704
|
+
description: string;
|
|
1705
|
+
value: string;
|
|
1706
|
+
env: ConnectorEnvVar[];
|
|
1707
|
+
tools: string[];
|
|
1708
|
+
actions: ConnectorAction[];
|
|
1709
|
+
setup: string[];
|
|
1710
|
+
config: Record<string, unknown>;
|
|
1711
|
+
cedar: string;
|
|
1712
|
+
}
|
|
1713
|
+
interface InstalledConnectorPilot {
|
|
1714
|
+
id: string;
|
|
1715
|
+
name: string;
|
|
1716
|
+
category: string;
|
|
1717
|
+
status: string;
|
|
1718
|
+
config_path: string;
|
|
1719
|
+
policy_path: string;
|
|
1720
|
+
}
|
|
1721
|
+
declare const CONNECTOR_PILOTS: ConnectorPilot[];
|
|
1722
|
+
declare function connectorPilotIds(): ConnectorPilotId[];
|
|
1723
|
+
declare function getConnectorPilot(id: string): ConnectorPilot | undefined;
|
|
1724
|
+
declare function connectorDirectory(dir: string): string;
|
|
1725
|
+
declare function writeConnectorPilots(opts: {
|
|
1726
|
+
dir: string;
|
|
1727
|
+
ids?: string[];
|
|
1728
|
+
force?: boolean;
|
|
1729
|
+
}): {
|
|
1730
|
+
written: string[];
|
|
1731
|
+
pilots: ConnectorPilot[];
|
|
1732
|
+
directory: string;
|
|
1733
|
+
};
|
|
1734
|
+
declare function readInstalledConnectorPilots(dir: string): InstalledConnectorPilot[];
|
|
1735
|
+
declare function connectorDoctor(dir: string, env?: NodeJS.ProcessEnv): Array<Record<string, unknown>>;
|
|
1736
|
+
|
|
1623
1737
|
/**
|
|
1624
1738
|
* Sigstore Rekor Transparency Log Anchoring
|
|
1625
1739
|
*
|
|
@@ -3015,4 +3129,4 @@ declare function getScopeBlindBridge(): ScopeBlindBridge;
|
|
|
3015
3129
|
/** Convenience: forward a signed receipt without instantiating yourself. */
|
|
3016
3130
|
declare function forwardReceipt(signedReceipt: any): void;
|
|
3017
3131
|
|
|
3018
|
-
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 CedarEvalOptions, 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, ScopeBlindBridge, type SelfTestCase, type SelfTestReport, 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, forwardReceipt, generateC2PACommand, generateCedarSchema, generateDatasetCard, generateHFMetadata, generateReport, generateSafetyTranscript, generateSchemaStub, getScopeBlindBridge, getSignerInfo, getToolPolicy, hashReceipt, hashResponseBody, initSigning, isAgentId, isCedarAvailable, isDisclosureMode, isEvidenceType, isManifestStatus, isSigningEnabled, listCredentialLabels, loadCedarPolicies, loadPolicy, manifestToVC, meetsMinTier, parseLogFile, parseNotificationConfigFromEnv, parseRateLimit, policySetFromSource, queryExternalPDP, receiptToVP, receiptsToHFRows, redactFields, resolveCredential, revealField, runEvaluatorSelfTest, runInSandbox, sendApprovalNotification, signCommittedDecision, signDecision, simulate, toCredentialRequestOptions, toManifoldFormat, toMetaculusFormat, validateCredentials, validateEvidenceReceipt, validateManifest, verifyActaC2PAAssertions, verifyAllCommitments, verifyApprovalAssertion, verifyCommitment, verifyEvidenceAttestation, verifyRekorAnchor };
|
|
3132
|
+
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, CONNECTOR_PILOTS, type CalibrationScore, type CedarEvalOptions, type CedarEvalRequest, type CedarPolicySet, type CedarSchema, type CedarSchemaResult, type CommittedFieldOpening, type CommittedSignResult, type ComplianceReport, ConfidentialGate, type ConfidentialGateConfig, type ConfidentialInferenceConfig, type ConnectorAction, type ConnectorEnvVar, type ConnectorPilot, type ConnectorPilotId, 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 InstalledConnectorPilot, 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, POLICY_PACKS, type PassportTokenClaims, type PayloadDigest, type PlanReceipt, type PolicyEngineMode, type PolicyPack, 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, ScopeBlindBridge, type SelectiveDisclosurePackageV0, type SelectiveDisclosureVerification, type SelfTestCase, type SelfTestReport, 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, connectorDirectory, connectorDoctor, connectorPilotIds, createApprovalChallenge, createApprovalReceiptPayload, createAttestationField, createAuditBundle, createC2PAManifest, createDisclosurePackage, createEvidenceAttestation, createLogAnchorField, createReceiptChannel, createSandbox, createSelectiveDisclosurePackage, destroySandbox, discloseField, ed25519ToDIDKey, evaluateCedar, evaluateTier, exportC2PAManifestJSON, exportJSONL, formatReportMarkdown, formatSimulation, forwardReceipt, generateC2PACommand, generateCedarSchema, generateDatasetCard, generateHFMetadata, generateReport, generateSafetyTranscript, generateSchemaStub, getConnectorPilot, getPolicyPack, getScopeBlindBridge, getSignerInfo, getToolPolicy, hashReceipt, hashResponseBody, initSigning, isAgentId, isCedarAvailable, isDisclosureMode, isEvidenceType, isManifestStatus, isSigningEnabled, listCredentialLabels, loadCedarPolicies, loadPolicy, manifestToVC, meetsMinTier, parseLogFile, parseNotificationConfigFromEnv, parseRateLimit, policyPackIds, policySetFromSource, queryExternalPDP, readInstalledConnectorPilots, receiptToVP, receiptsToHFRows, redactFields, resolveCredential, revealField, runEvaluatorSelfTest, runInSandbox, sendApprovalNotification, signCommittedDecision, signDecision, simulate, toCredentialRequestOptions, toManifoldFormat, toMetaculusFormat, validateCredentials, validateEvidenceReceipt, validateManifest, verifyActaC2PAAssertions, verifyAllCommitments, verifyApprovalAssertion, verifyCommitment, verifyEvidenceAttestation, verifyRekorAnchor, verifySelectiveDisclosurePackage, writeConnectorPilots };
|