protect-mcp 0.5.1 → 0.5.3
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 +2 -2
- package/dist/{chunk-IUFFDQYZ.mjs → chunk-BYYWYSHM.mjs} +1 -1
- package/dist/{chunk-YKM6W6T7.mjs → chunk-GQWJCHQV.mjs} +2 -2
- package/dist/{chunk-IAJJA5IW.mjs → chunk-HFM6K7E4.mjs} +1 -1
- package/dist/{chunk-UEHLYOJY.mjs → chunk-NMZPXXL3.mjs} +2 -0
- package/dist/{chunk-V52W3XIN.mjs → chunk-YTBC72JJ.mjs} +26 -9
- package/dist/cli.js +188 -14
- package/dist/cli.mjs +163 -9
- package/dist/hook-patterns.js +2 -0
- package/dist/hook-patterns.mjs +1 -1
- package/dist/hook-server.js +26 -9
- package/dist/hook-server.mjs +2 -2
- package/dist/{http-transport-GXIXLVJQ.mjs → http-transport-LNBENGXD.mjs} +2 -2
- package/dist/index.d.mts +125 -1
- package/dist/index.d.ts +125 -1
- package/dist/index.js +305 -9
- package/dist/index.mjs +280 -5
- package/package.json +2 -2
- package/policies/cedar/secrets-detection.cedar +113 -0
package/dist/cli.mjs
CHANGED
|
@@ -3,17 +3,17 @@ import {
|
|
|
3
3
|
formatSimulation,
|
|
4
4
|
parseLogFile,
|
|
5
5
|
simulate
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-GQWJCHQV.mjs";
|
|
7
7
|
import {
|
|
8
8
|
ProtectGateway,
|
|
9
9
|
validateCredentials
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-BYYWYSHM.mjs";
|
|
11
11
|
import {
|
|
12
12
|
initSigning,
|
|
13
13
|
isCedarAvailable,
|
|
14
14
|
loadCedarPolicies,
|
|
15
15
|
loadPolicy
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-YTBC72JJ.mjs";
|
|
17
17
|
import "./chunk-PQJP2ZCI.mjs";
|
|
18
18
|
|
|
19
19
|
// src/cli.ts
|
|
@@ -25,7 +25,8 @@ Usage:
|
|
|
25
25
|
protect-mcp [options] -- <command> [args...]
|
|
26
26
|
protect-mcp serve [--port <port>] [--enforce] [--policy <path>] [--cedar <dir>]
|
|
27
27
|
protect-mcp init-hooks [--dir <path>] [--port <port>]
|
|
28
|
-
protect-mcp quickstart
|
|
28
|
+
protect-mcp quickstart [--connect]
|
|
29
|
+
protect-mcp connect
|
|
29
30
|
protect-mcp init [--dir <path>]
|
|
30
31
|
protect-mcp demo
|
|
31
32
|
protect-mcp trace <receipt_id> [--endpoint <url>] [--depth <n>]
|
|
@@ -50,6 +51,7 @@ Commands:
|
|
|
50
51
|
serve Start HTTP hook server for Claude Code integration (port 9377)
|
|
51
52
|
init-hooks Generate Claude Code hook config + skill + sample Cedar policy
|
|
52
53
|
quickstart Zero-config onboarding: init + demo + show receipts in one command
|
|
54
|
+
connect Create a ScopeBlind sandbox dashboard and configure receipt upload
|
|
53
55
|
init Generate config template, Ed25519 keypair, and sample policy
|
|
54
56
|
demo Start a demo server wrapped with protect-mcp (see receipts instantly)
|
|
55
57
|
doctor Check your setup: keys, policies, verifier, API connectivity
|
|
@@ -64,6 +66,8 @@ Examples:
|
|
|
64
66
|
protect-mcp serve --enforce --cedar ./cedar # Enforce Cedar policies
|
|
65
67
|
protect-mcp init-hooks # One-command Claude Code setup
|
|
66
68
|
protect-mcp quickstart
|
|
69
|
+
protect-mcp quickstart --connect # Quickstart + create dashboard
|
|
70
|
+
protect-mcp connect # Connect existing setup to dashboard
|
|
67
71
|
protect-mcp -- node my-server.js
|
|
68
72
|
protect-mcp init
|
|
69
73
|
protect-mcp demo
|
|
@@ -645,7 +649,83 @@ ${bold("protect-mcp bundle")}
|
|
|
645
649
|
|
|
646
650
|
`);
|
|
647
651
|
}
|
|
648
|
-
async function
|
|
652
|
+
async function createSandbox() {
|
|
653
|
+
const { mkdirSync, writeFileSync, existsSync, readFileSync } = await import("fs");
|
|
654
|
+
const { join } = await import("path");
|
|
655
|
+
const { homedir } = await import("os");
|
|
656
|
+
let response;
|
|
657
|
+
try {
|
|
658
|
+
response = await fetch("https://api.scopeblind.com/sandbox/create", { method: "POST" });
|
|
659
|
+
} catch {
|
|
660
|
+
process.stderr.write(yellow(" \u26A0 Could not create dashboard (offline or server unavailable).\n"));
|
|
661
|
+
process.stderr.write(` Run 'npx protect-mcp connect' later to set up the dashboard.
|
|
662
|
+
|
|
663
|
+
`);
|
|
664
|
+
return null;
|
|
665
|
+
}
|
|
666
|
+
if (!response.ok) {
|
|
667
|
+
process.stderr.write(yellow(" \u26A0 Could not create dashboard (offline or server unavailable).\n"));
|
|
668
|
+
process.stderr.write(` Run 'npx protect-mcp connect' later to set up the dashboard.
|
|
669
|
+
|
|
670
|
+
`);
|
|
671
|
+
return null;
|
|
672
|
+
}
|
|
673
|
+
let data;
|
|
674
|
+
try {
|
|
675
|
+
data = await response.json();
|
|
676
|
+
} catch {
|
|
677
|
+
process.stderr.write(yellow(" \u26A0 Could not create dashboard (unexpected response).\n"));
|
|
678
|
+
process.stderr.write(` Run 'npx protect-mcp connect' later to set up the dashboard.
|
|
679
|
+
|
|
680
|
+
`);
|
|
681
|
+
return null;
|
|
682
|
+
}
|
|
683
|
+
const dashboardUrl = `https://scopeblind.com/t/${data.slug}`;
|
|
684
|
+
const configDir = join(homedir(), ".protect-mcp");
|
|
685
|
+
if (!existsSync(configDir)) {
|
|
686
|
+
mkdirSync(configDir, { recursive: true });
|
|
687
|
+
}
|
|
688
|
+
const configPath = join(configDir, "config.json");
|
|
689
|
+
let existing = {};
|
|
690
|
+
if (existsSync(configPath)) {
|
|
691
|
+
try {
|
|
692
|
+
existing = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
693
|
+
} catch {
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
writeFileSync(configPath, JSON.stringify({
|
|
697
|
+
...existing,
|
|
698
|
+
sandbox_slug: data.slug,
|
|
699
|
+
dashboard_url: dashboardUrl
|
|
700
|
+
}, null, 2) + "\n");
|
|
701
|
+
return dashboardUrl;
|
|
702
|
+
}
|
|
703
|
+
async function handleConnect() {
|
|
704
|
+
process.stderr.write(`
|
|
705
|
+
${bold("protect-mcp connect")}
|
|
706
|
+
`);
|
|
707
|
+
process.stderr.write(`${"\u2500".repeat(50)}
|
|
708
|
+
|
|
709
|
+
`);
|
|
710
|
+
process.stderr.write(` Creating ScopeBlind sandbox dashboard...
|
|
711
|
+
|
|
712
|
+
`);
|
|
713
|
+
const dashboardUrl = await createSandbox();
|
|
714
|
+
if (dashboardUrl) {
|
|
715
|
+
process.stderr.write(green(` \u2713 Dashboard created: ${dashboardUrl}
|
|
716
|
+
`));
|
|
717
|
+
process.stderr.write(` Receipts will be uploaded automatically.
|
|
718
|
+
`);
|
|
719
|
+
process.stderr.write(dim(` Free tier: 20,000 receipts/month \u2014 no credit card required.
|
|
720
|
+
`));
|
|
721
|
+
process.stderr.write(`
|
|
722
|
+
${"\u2500".repeat(50)}
|
|
723
|
+
|
|
724
|
+
`);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
async function handleQuickstart(argv) {
|
|
728
|
+
const connectFlag = argv.includes("--connect");
|
|
649
729
|
const { mkdtempSync, writeFileSync, existsSync, mkdirSync, readFileSync } = await import("fs");
|
|
650
730
|
const { join } = await import("path");
|
|
651
731
|
const { tmpdir } = await import("os");
|
|
@@ -665,9 +745,13 @@ ${bold("protect-mcp quickstart")}
|
|
|
665
745
|
process.stdout.write(` 3. Start a demo MCP server with protect-mcp wrapping it
|
|
666
746
|
`);
|
|
667
747
|
process.stdout.write(` 4. Log signed receipts for every tool call
|
|
668
|
-
|
|
669
748
|
`);
|
|
670
|
-
|
|
749
|
+
if (connectFlag) {
|
|
750
|
+
process.stdout.write(` 5. Create a ScopeBlind dashboard for receipt viewing
|
|
751
|
+
`);
|
|
752
|
+
}
|
|
753
|
+
process.stdout.write(`
|
|
754
|
+
Working dir: ${dir}
|
|
671
755
|
|
|
672
756
|
`);
|
|
673
757
|
const keysDir = join(dir, "keys");
|
|
@@ -718,6 +802,24 @@ ${bold("protect-mcp quickstart")}
|
|
|
718
802
|
process.stdout.write(` \u2713 Signing enabled (Ed25519)
|
|
719
803
|
|
|
720
804
|
`);
|
|
805
|
+
if (connectFlag) {
|
|
806
|
+
process.stdout.write(`${bold("Connecting to ScopeBlind dashboard...")}
|
|
807
|
+
|
|
808
|
+
`);
|
|
809
|
+
const dashboardUrl = await createSandbox();
|
|
810
|
+
if (dashboardUrl) {
|
|
811
|
+
const updatedConfig = { ...config, dashboard_url: dashboardUrl };
|
|
812
|
+
writeFileSync(configPath, JSON.stringify(updatedConfig, null, 2) + "\n");
|
|
813
|
+
process.stdout.write(green(` \u2713 Dashboard created: ${dashboardUrl}
|
|
814
|
+
`));
|
|
815
|
+
process.stdout.write(` Receipts will be uploaded automatically.
|
|
816
|
+
`);
|
|
817
|
+
process.stdout.write(dim(` Free tier: 20,000 receipts/month \u2014 no credit card required.
|
|
818
|
+
`));
|
|
819
|
+
process.stdout.write(`
|
|
820
|
+
`);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
721
823
|
process.stdout.write(`${bold("Starting demo server...")}
|
|
722
824
|
|
|
723
825
|
`);
|
|
@@ -1119,7 +1221,55 @@ ${bold("protect-mcp init-hooks")}
|
|
|
1119
1221
|
|
|
1120
1222
|
`);
|
|
1121
1223
|
}
|
|
1224
|
+
async function sendInstallTelemetry() {
|
|
1225
|
+
try {
|
|
1226
|
+
const { existsSync, mkdirSync, writeFileSync, readFileSync } = await import("fs");
|
|
1227
|
+
const { join, dirname } = await import("path");
|
|
1228
|
+
const { homedir } = await import("os");
|
|
1229
|
+
const { fileURLToPath } = await import("url");
|
|
1230
|
+
const markerDir = join(homedir(), ".protect-mcp");
|
|
1231
|
+
const markerFile = join(markerDir, ".telemetry-sent");
|
|
1232
|
+
if (existsSync(markerFile) || process.env.PROTECT_MCP_TELEMETRY === "off") {
|
|
1233
|
+
return;
|
|
1234
|
+
}
|
|
1235
|
+
let version = "unknown";
|
|
1236
|
+
try {
|
|
1237
|
+
const thisDir = dirname(fileURLToPath(import.meta.url));
|
|
1238
|
+
const pkgPath = join(thisDir, "..", "package.json");
|
|
1239
|
+
if (existsSync(pkgPath)) {
|
|
1240
|
+
version = JSON.parse(readFileSync(pkgPath, "utf-8")).version;
|
|
1241
|
+
}
|
|
1242
|
+
} catch {
|
|
1243
|
+
}
|
|
1244
|
+
const controller = new AbortController();
|
|
1245
|
+
const timeout = setTimeout(() => controller.abort(), 3e3);
|
|
1246
|
+
fetch("https://api.scopeblind.com/telemetry/install", {
|
|
1247
|
+
method: "POST",
|
|
1248
|
+
headers: { "Content-Type": "application/json" },
|
|
1249
|
+
body: JSON.stringify({
|
|
1250
|
+
package: "protect-mcp",
|
|
1251
|
+
version,
|
|
1252
|
+
os: process.platform,
|
|
1253
|
+
arch: process.arch,
|
|
1254
|
+
node: process.version,
|
|
1255
|
+
ts: Date.now()
|
|
1256
|
+
}),
|
|
1257
|
+
signal: controller.signal
|
|
1258
|
+
}).catch(() => {
|
|
1259
|
+
}).finally(() => clearTimeout(timeout));
|
|
1260
|
+
if (!existsSync(markerDir)) {
|
|
1261
|
+
mkdirSync(markerDir, { recursive: true });
|
|
1262
|
+
}
|
|
1263
|
+
writeFileSync(markerFile, String(Date.now()), "utf-8");
|
|
1264
|
+
process.stderr.write(
|
|
1265
|
+
"[protect-mcp] Anonymous install telemetry sent (disable: PROTECT_MCP_TELEMETRY=off)\n"
|
|
1266
|
+
);
|
|
1267
|
+
} catch {
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1122
1270
|
async function main() {
|
|
1271
|
+
sendInstallTelemetry().catch(() => {
|
|
1272
|
+
});
|
|
1123
1273
|
const args = process.argv.slice(2);
|
|
1124
1274
|
if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
|
|
1125
1275
|
printHelp();
|
|
@@ -1147,9 +1297,13 @@ async function main() {
|
|
|
1147
1297
|
process.exit(0);
|
|
1148
1298
|
}
|
|
1149
1299
|
if (args[0] === "quickstart") {
|
|
1150
|
-
await handleQuickstart();
|
|
1300
|
+
await handleQuickstart(args.slice(1));
|
|
1151
1301
|
return;
|
|
1152
1302
|
}
|
|
1303
|
+
if (args[0] === "connect") {
|
|
1304
|
+
await handleConnect();
|
|
1305
|
+
process.exit(0);
|
|
1306
|
+
}
|
|
1153
1307
|
if (args[0] === "init") {
|
|
1154
1308
|
await handleInit(args.slice(1));
|
|
1155
1309
|
process.exit(0);
|
|
@@ -1282,7 +1436,7 @@ async function main() {
|
|
|
1282
1436
|
if (useHttp) {
|
|
1283
1437
|
const portIdx = args.indexOf("--port");
|
|
1284
1438
|
const httpPort = portIdx >= 0 && args[portIdx + 1] ? parseInt(args[portIdx + 1]) : 3e3;
|
|
1285
|
-
const { startHttpTransport } = await import("./http-transport-
|
|
1439
|
+
const { startHttpTransport } = await import("./http-transport-LNBENGXD.mjs");
|
|
1286
1440
|
startHttpTransport({ port: httpPort, config, serverCommand: childCommand });
|
|
1287
1441
|
return;
|
|
1288
1442
|
}
|
package/dist/hook-patterns.js
CHANGED
|
@@ -299,6 +299,8 @@ context: inline
|
|
|
299
299
|
|
|
300
300
|
# ScopeBlind Receipt Verification
|
|
301
301
|
|
|
302
|
+
Every AI agent tool call gets a cryptographic receipt. Verify offline. No vendor trust required.
|
|
303
|
+
|
|
302
304
|
When the user asks to verify receipts or check the audit trail:
|
|
303
305
|
|
|
304
306
|
1. **Check for receipt files:**
|
package/dist/hook-patterns.mjs
CHANGED
package/dist/hook-server.js
CHANGED
|
@@ -89,7 +89,7 @@ function buildEntities(req) {
|
|
|
89
89
|
}
|
|
90
90
|
];
|
|
91
91
|
}
|
|
92
|
-
async function evaluateCedar(policySet, req) {
|
|
92
|
+
async function evaluateCedar(policySet, req, schema) {
|
|
93
93
|
const available = await ensureCedarWasm();
|
|
94
94
|
if (!available) {
|
|
95
95
|
return {
|
|
@@ -100,16 +100,21 @@ async function evaluateCedar(policySet, req) {
|
|
|
100
100
|
}
|
|
101
101
|
try {
|
|
102
102
|
const agentId = req.agentId || req.tier;
|
|
103
|
+
const context = {
|
|
104
|
+
tier: req.tier,
|
|
105
|
+
...req.context || {}
|
|
106
|
+
};
|
|
107
|
+
if (req.toolInput && Object.keys(req.toolInput).length > 0) {
|
|
108
|
+
context.input = req.toolInput;
|
|
109
|
+
}
|
|
103
110
|
const authRequest = {
|
|
104
111
|
principal: { type: "Agent", id: agentId },
|
|
105
112
|
action: { type: "Action", id: "MCP::Tool::call" },
|
|
106
113
|
resource: { type: "Tool", id: req.tool },
|
|
107
|
-
context
|
|
108
|
-
tier: req.tier,
|
|
109
|
-
...req.context || {}
|
|
110
|
-
}
|
|
114
|
+
context
|
|
111
115
|
};
|
|
112
116
|
const entities = buildEntities(req);
|
|
117
|
+
const cedarSchema = schema?.schemaJson ?? null;
|
|
113
118
|
let result;
|
|
114
119
|
if (typeof cedarWasm.isAuthorized === "function") {
|
|
115
120
|
result = cedarWasm.isAuthorized({
|
|
@@ -119,8 +124,7 @@ async function evaluateCedar(policySet, req) {
|
|
|
119
124
|
action: authRequest.action,
|
|
120
125
|
resource: authRequest.resource,
|
|
121
126
|
context: authRequest.context,
|
|
122
|
-
schema:
|
|
123
|
-
// No schema enforcement — Cedar still evaluates correctly
|
|
127
|
+
schema: cedarSchema
|
|
124
128
|
});
|
|
125
129
|
} else if (typeof cedarWasm.checkAuthorization === "function") {
|
|
126
130
|
result = cedarWasm.checkAuthorization(
|
|
@@ -138,7 +142,7 @@ async function evaluateCedar(policySet, req) {
|
|
|
138
142
|
action: authRequest.action,
|
|
139
143
|
resource: authRequest.resource,
|
|
140
144
|
context: authRequest.context,
|
|
141
|
-
schema:
|
|
145
|
+
schema: cedarSchema
|
|
142
146
|
});
|
|
143
147
|
} else {
|
|
144
148
|
return {
|
|
@@ -253,7 +257,14 @@ function signDecision(entry) {
|
|
|
253
257
|
scope: entry.request_id,
|
|
254
258
|
// request scope
|
|
255
259
|
mode: entry.mode,
|
|
256
|
-
request_id: entry.request_id
|
|
260
|
+
request_id: entry.request_id,
|
|
261
|
+
// Spec version: ties every receipt to the IETF standard
|
|
262
|
+
spec: "draft-farley-acta-signed-receipts-01",
|
|
263
|
+
// Issuer certification: distinguishes VOPRF-backed receipts from self-signed ones
|
|
264
|
+
// - scopeblind:verified = issued via ScopeBlind VOPRF backend (paid tier)
|
|
265
|
+
// - self-signed = signed with local Ed25519 key (free tier, protect-mcp default)
|
|
266
|
+
// - uncertified = unsigned receipt (shadow mode, no signing configured)
|
|
267
|
+
issuer_certification: signerState ? "self-signed" : "uncertified"
|
|
257
268
|
};
|
|
258
269
|
if (entry.tier) payload.tier = entry.tier;
|
|
259
270
|
if (entry.credential_ref) payload.credential_ref = entry.credential_ref;
|
|
@@ -261,6 +272,12 @@ function signDecision(entry) {
|
|
|
261
272
|
payload.rate_limit_remaining = entry.rate_limit_remaining;
|
|
262
273
|
}
|
|
263
274
|
if (entry.policy_engine) payload.policy_engine = entry.policy_engine;
|
|
275
|
+
if (entry.hook_event) payload.hook_event = entry.hook_event;
|
|
276
|
+
if (entry.sandbox_state) payload.sandbox_state = entry.sandbox_state;
|
|
277
|
+
if (entry.timing) payload.timing = entry.timing;
|
|
278
|
+
if (entry.swarm) payload.swarm = entry.swarm;
|
|
279
|
+
if (entry.payload_digest) payload.payload_digest = entry.payload_digest;
|
|
280
|
+
if (entry.deny_iteration) payload.deny_iteration = entry.deny_iteration;
|
|
264
281
|
const result = artifactsModule.createSignedArtifact(
|
|
265
282
|
artifactType,
|
|
266
283
|
payload,
|
package/dist/hook-server.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -167,6 +167,13 @@ interface DecisionLog {
|
|
|
167
167
|
plan_receipt_id?: string;
|
|
168
168
|
/** Hook event that triggered this log entry */
|
|
169
169
|
hook_event?: HookEventName;
|
|
170
|
+
/** IETF specification version — ties every receipt to the standard */
|
|
171
|
+
spec?: string;
|
|
172
|
+
/** Issuer certification level:
|
|
173
|
+
* - "scopeblind:verified" = VOPRF-backed issuance (paid tier)
|
|
174
|
+
* - "self-signed" = local Ed25519 key (free tier, protect-mcp default)
|
|
175
|
+
* - "uncertified" = unsigned receipt (shadow mode) */
|
|
176
|
+
issuer_certification?: 'scopeblind:verified' | 'self-signed' | 'uncertified';
|
|
170
177
|
}
|
|
171
178
|
interface SwarmContext {
|
|
172
179
|
/** Team name from CLAUDE_CODE_TEAM_NAME env var */
|
|
@@ -539,6 +546,45 @@ interface CedarPolicySet {
|
|
|
539
546
|
/** Filenames loaded */
|
|
540
547
|
files: string[];
|
|
541
548
|
}
|
|
549
|
+
interface CedarEvalRequest {
|
|
550
|
+
/** Tool name being called */
|
|
551
|
+
tool: string;
|
|
552
|
+
/** Trust tier of the agent */
|
|
553
|
+
tier: TrustTier;
|
|
554
|
+
/** Agent ID (optional) */
|
|
555
|
+
agentId?: string;
|
|
556
|
+
/** Additional context fields */
|
|
557
|
+
context?: Record<string, unknown>;
|
|
558
|
+
/** Tool input (for schema-validated evaluation) */
|
|
559
|
+
toolInput?: Record<string, unknown>;
|
|
560
|
+
}
|
|
561
|
+
/** Cedar schema for typed policy evaluation (generated by cedar-schema.ts) */
|
|
562
|
+
interface CedarSchema {
|
|
563
|
+
/** The schema as a JSON object for Cedar WASM */
|
|
564
|
+
schemaJson: Record<string, unknown> | null;
|
|
565
|
+
/** Namespace used in the schema */
|
|
566
|
+
namespace?: string;
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Load all .cedar files from a directory and return a compiled policy set.
|
|
570
|
+
*
|
|
571
|
+
* Files are sorted alphabetically for deterministic digest computation.
|
|
572
|
+
* Throws if the directory doesn't exist or contains no .cedar files.
|
|
573
|
+
*/
|
|
574
|
+
declare function loadCedarPolicies(dirPath: string): CedarPolicySet;
|
|
575
|
+
/**
|
|
576
|
+
* Evaluate a Cedar policy set against a tool call.
|
|
577
|
+
*
|
|
578
|
+
* Returns a standard ExternalDecision compatible with the gateway's
|
|
579
|
+
* decision pipeline. If Cedar WASM is not available, returns a
|
|
580
|
+
* fallback allow decision (fail-open, logged).
|
|
581
|
+
*/
|
|
582
|
+
declare function evaluateCedar(policySet: CedarPolicySet, req: CedarEvalRequest, schema?: CedarSchema): Promise<ExternalDecision>;
|
|
583
|
+
/**
|
|
584
|
+
* Validate that Cedar WASM is available.
|
|
585
|
+
* Useful for CLI startup diagnostics.
|
|
586
|
+
*/
|
|
587
|
+
declare function isCedarAvailable(): Promise<boolean>;
|
|
542
588
|
|
|
543
589
|
/**
|
|
544
590
|
* MCP tool-calling gateway that intercepts JSON-RPC requests,
|
|
@@ -1313,6 +1359,84 @@ declare function validateManifest(manifest: unknown): string[];
|
|
|
1313
1359
|
*/
|
|
1314
1360
|
declare function validateEvidenceReceipt(receipt: unknown): string[];
|
|
1315
1361
|
|
|
1362
|
+
/**
|
|
1363
|
+
* @scopeblind/protect-mcp — Cedar Schema Generator for MCP Tools
|
|
1364
|
+
*
|
|
1365
|
+
* Auto-generates a Cedar authorization schema from MCP tool descriptions.
|
|
1366
|
+
* This enables typed Cedar policies that reference tool input attributes:
|
|
1367
|
+
*
|
|
1368
|
+
* permit(principal, action == Action::"read_file", resource)
|
|
1369
|
+
* when { context.input.path like "./workspace/*" };
|
|
1370
|
+
*
|
|
1371
|
+
* Compatible with cedar-policy/cedar-for-agents schema format.
|
|
1372
|
+
* Designed to replace `schema: null` in Cedar WASM evaluations.
|
|
1373
|
+
*
|
|
1374
|
+
* @see https://github.com/cedar-policy/cedar-for-agents
|
|
1375
|
+
* @standard RFC 8785 (JCS), Cedar Policy Language v4
|
|
1376
|
+
*/
|
|
1377
|
+
/** MCP tool description from tools/list response */
|
|
1378
|
+
interface McpToolDescription {
|
|
1379
|
+
name: string;
|
|
1380
|
+
description?: string;
|
|
1381
|
+
inputSchema?: JsonSchema;
|
|
1382
|
+
}
|
|
1383
|
+
/** Subset of JSON Schema that MCP tools use */
|
|
1384
|
+
interface JsonSchema {
|
|
1385
|
+
type?: string | string[];
|
|
1386
|
+
properties?: Record<string, JsonSchema>;
|
|
1387
|
+
required?: string[];
|
|
1388
|
+
items?: JsonSchema;
|
|
1389
|
+
enum?: (string | number | boolean)[];
|
|
1390
|
+
format?: string;
|
|
1391
|
+
description?: string;
|
|
1392
|
+
additionalProperties?: boolean | JsonSchema;
|
|
1393
|
+
anyOf?: JsonSchema[];
|
|
1394
|
+
oneOf?: JsonSchema[];
|
|
1395
|
+
}
|
|
1396
|
+
/** Generated Cedar schema components */
|
|
1397
|
+
interface CedarSchemaResult {
|
|
1398
|
+
/** The .cedarschema text (human-readable Cedar schema format) */
|
|
1399
|
+
schemaText: string;
|
|
1400
|
+
/** The schema as a JSON object (for passing to Cedar WASM) */
|
|
1401
|
+
schemaJson: Record<string, unknown>;
|
|
1402
|
+
/** Number of tools mapped */
|
|
1403
|
+
toolCount: number;
|
|
1404
|
+
/** Tool names included */
|
|
1405
|
+
tools: string[];
|
|
1406
|
+
}
|
|
1407
|
+
interface SchemaGeneratorConfig {
|
|
1408
|
+
/** Namespace for generated types (default: "ScopeBlind") */
|
|
1409
|
+
namespace?: string;
|
|
1410
|
+
/** Include agent tier as principal attribute (default: true) */
|
|
1411
|
+
includeTier?: boolean;
|
|
1412
|
+
/** Include timestamp context (default: true) */
|
|
1413
|
+
includeTimestamp?: boolean;
|
|
1414
|
+
/** Include agent_id as principal attribute (default: true) */
|
|
1415
|
+
includeAgentId?: boolean;
|
|
1416
|
+
}
|
|
1417
|
+
/**
|
|
1418
|
+
* Generate a Cedar schema from MCP tool descriptions.
|
|
1419
|
+
*
|
|
1420
|
+
* Produces both human-readable .cedarschema text and the JSON
|
|
1421
|
+
* representation that Cedar WASM accepts.
|
|
1422
|
+
*
|
|
1423
|
+
* The generated schema defines:
|
|
1424
|
+
* - Agent entity type (principal) with tier and agent_id attributes
|
|
1425
|
+
* - Tool entity type (resource)
|
|
1426
|
+
* - One action per MCP tool, with typed input context
|
|
1427
|
+
* - A parent action "MCP::Tool::call" for blanket policies
|
|
1428
|
+
*
|
|
1429
|
+
* This enables policies like:
|
|
1430
|
+
* forbid(principal, action == Action::"execute_command", resource)
|
|
1431
|
+
* when { context.input has "command" && context.input.command like "rm *" };
|
|
1432
|
+
*/
|
|
1433
|
+
declare function generateCedarSchema(tools: McpToolDescription[], config?: SchemaGeneratorConfig): CedarSchemaResult;
|
|
1434
|
+
/**
|
|
1435
|
+
* Generate a Cedar schema stub file for customization.
|
|
1436
|
+
* This is the starting point for users who want to extend the auto-generated schema.
|
|
1437
|
+
*/
|
|
1438
|
+
declare function generateSchemaStub(namespace?: string): string;
|
|
1439
|
+
|
|
1316
1440
|
/**
|
|
1317
1441
|
* Sigstore Rekor Transparency Log Anchoring
|
|
1318
1442
|
*
|
|
@@ -2639,4 +2763,4 @@ declare function confidentialInference(_prompt: string, _config: ConfidentialInf
|
|
|
2639
2763
|
receipt: Record<string, unknown>;
|
|
2640
2764
|
}>;
|
|
2641
2765
|
|
|
2642
|
-
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 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 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 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, evaluateTier, exportC2PAManifestJSON, exportJSONL, formatReportMarkdown, formatSimulation, generateC2PACommand, generateDatasetCard, generateHFMetadata, generateReport, generateSafetyTranscript, getSignerInfo, getToolPolicy, hashReceipt, hashResponseBody, initSigning, isAgentId, isDisclosureMode, isEvidenceType, isManifestStatus, isSigningEnabled, listCredentialLabels, 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 };
|
|
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 };
|