protect-mcp 0.2.1 → 0.3.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/dist/chunk-3WCA7O4D.mjs +977 -0
- package/dist/cli.js +760 -163
- package/dist/cli.mjs +241 -5
- package/dist/demo-server.d.mts +1 -0
- package/dist/demo-server.d.ts +1 -0
- package/dist/demo-server.js +137 -0
- package/dist/demo-server.mjs +136 -0
- package/dist/index.d.mts +75 -60
- package/dist/index.d.ts +75 -60
- package/dist/index.js +507 -269
- package/dist/index.mjs +3 -123
- package/package.json +4 -4
- package/dist/chunk-ZCKNFULF.mjs +0 -613
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ProtectGateway,
|
|
3
|
+
buildDecisionContext,
|
|
3
4
|
checkRateLimit,
|
|
4
5
|
evaluateTier,
|
|
5
6
|
getSignerInfo,
|
|
@@ -10,132 +11,11 @@ import {
|
|
|
10
11
|
loadPolicy,
|
|
11
12
|
meetsMinTier,
|
|
12
13
|
parseRateLimit,
|
|
14
|
+
queryExternalPDP,
|
|
13
15
|
resolveCredential,
|
|
14
16
|
signDecision,
|
|
15
17
|
validateCredentials
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
|
|
18
|
-
// src/external-pdp.ts
|
|
19
|
-
async function queryExternalPDP(context, config) {
|
|
20
|
-
const timeout = config.timeout_ms || 500;
|
|
21
|
-
const controller = new AbortController();
|
|
22
|
-
const timer = setTimeout(() => controller.abort(), timeout);
|
|
23
|
-
try {
|
|
24
|
-
const body = formatRequest(context, config.format || "generic");
|
|
25
|
-
const response = await fetch(config.endpoint, {
|
|
26
|
-
method: "POST",
|
|
27
|
-
headers: { "Content-Type": "application/json" },
|
|
28
|
-
body: JSON.stringify(body),
|
|
29
|
-
signal: controller.signal
|
|
30
|
-
});
|
|
31
|
-
clearTimeout(timer);
|
|
32
|
-
if (!response.ok) {
|
|
33
|
-
return fallbackDecision(config, `PDP returned HTTP ${response.status}`);
|
|
34
|
-
}
|
|
35
|
-
const result = await response.json();
|
|
36
|
-
return parseResponse(result, config.format || "generic");
|
|
37
|
-
} catch (err) {
|
|
38
|
-
clearTimeout(timer);
|
|
39
|
-
if (err instanceof Error && err.name === "AbortError") {
|
|
40
|
-
return fallbackDecision(config, `PDP timeout after ${timeout}ms`);
|
|
41
|
-
}
|
|
42
|
-
return fallbackDecision(config, `PDP error: ${err instanceof Error ? err.message : "unknown"}`);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
function formatRequest(context, format) {
|
|
46
|
-
switch (format) {
|
|
47
|
-
case "opa":
|
|
48
|
-
return {
|
|
49
|
-
input: {
|
|
50
|
-
actor: context.actor,
|
|
51
|
-
action: context.action,
|
|
52
|
-
target: context.target,
|
|
53
|
-
credential_ref: context.credential_ref,
|
|
54
|
-
mode: context.mode,
|
|
55
|
-
metadata: context.request_metadata
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
case "cerbos":
|
|
59
|
-
return {
|
|
60
|
-
principal: {
|
|
61
|
-
id: context.actor.id || "unknown",
|
|
62
|
-
roles: [context.actor.tier],
|
|
63
|
-
attr: {
|
|
64
|
-
manifest_hash: context.actor.manifest_hash
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
resource: {
|
|
68
|
-
kind: "tool",
|
|
69
|
-
id: context.action.tool,
|
|
70
|
-
attr: context.target
|
|
71
|
-
},
|
|
72
|
-
actions: [context.action.operation || "call"]
|
|
73
|
-
};
|
|
74
|
-
case "generic":
|
|
75
|
-
default:
|
|
76
|
-
return context;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
function parseResponse(result, format) {
|
|
80
|
-
switch (format) {
|
|
81
|
-
case "opa":
|
|
82
|
-
if (typeof result.result === "boolean") {
|
|
83
|
-
return { allowed: result.result };
|
|
84
|
-
}
|
|
85
|
-
if (result.result && typeof result.result === "object") {
|
|
86
|
-
const r = result.result;
|
|
87
|
-
return {
|
|
88
|
-
allowed: Boolean(r.allow),
|
|
89
|
-
reason: r.reason,
|
|
90
|
-
metadata: r
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
return { allowed: false, reason: "unrecognized OPA response" };
|
|
94
|
-
case "cerbos":
|
|
95
|
-
if (Array.isArray(result.results) && result.results.length > 0) {
|
|
96
|
-
const actions = result.results[0].actions;
|
|
97
|
-
if (actions) {
|
|
98
|
-
const effect = Object.values(actions)[0];
|
|
99
|
-
return { allowed: effect === "EFFECT_ALLOW" };
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return { allowed: false, reason: "unrecognized Cerbos response" };
|
|
103
|
-
case "generic":
|
|
104
|
-
default:
|
|
105
|
-
return {
|
|
106
|
-
allowed: Boolean(result.allowed),
|
|
107
|
-
reason: result.reason,
|
|
108
|
-
metadata: result.metadata
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
function fallbackDecision(config, reason) {
|
|
113
|
-
const fallback = config.fallback || "deny";
|
|
114
|
-
return {
|
|
115
|
-
allowed: fallback === "allow",
|
|
116
|
-
reason: `fallback_${fallback}: ${reason}`
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
function buildDecisionContext(toolName, tier, opts) {
|
|
120
|
-
return {
|
|
121
|
-
v: 1,
|
|
122
|
-
actor: {
|
|
123
|
-
id: opts.agentId,
|
|
124
|
-
tier,
|
|
125
|
-
manifest_hash: opts.manifestHash
|
|
126
|
-
},
|
|
127
|
-
action: {
|
|
128
|
-
tool: toolName,
|
|
129
|
-
operation: "call"
|
|
130
|
-
},
|
|
131
|
-
target: {
|
|
132
|
-
service: opts.slug || "default"
|
|
133
|
-
},
|
|
134
|
-
credential_ref: opts.credentialRef,
|
|
135
|
-
mode: opts.mode,
|
|
136
|
-
request_metadata: opts.requestMetadata || {}
|
|
137
|
-
};
|
|
138
|
-
}
|
|
18
|
+
} from "./chunk-3WCA7O4D.mjs";
|
|
139
19
|
|
|
140
20
|
// src/bundle.ts
|
|
141
21
|
function createAuditBundle(opts) {
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "protect-mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Security gateway for MCP servers. Shadow-mode logs by default, per-tool policies,
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Security gateway for MCP servers. Shadow-mode logs by default, per-tool policies, trust-tier gating, credential isolation, BYOPE (OPA/Cerbos), signed receipts, offline verification.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"module": "dist/index.mjs",
|
|
8
8
|
"bin": {
|
|
9
|
-
"protect-mcp": "
|
|
9
|
+
"protect-mcp": "dist/cli.js"
|
|
10
10
|
},
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
|
-
"build": "tsup src/index.ts src/cli.ts --format cjs,esm --dts --clean",
|
|
19
|
+
"build": "tsup src/index.ts src/cli.ts src/demo-server.ts --format cjs,esm --dts --clean",
|
|
20
20
|
"test": "vitest run",
|
|
21
21
|
"prepublishOnly": "npm run build"
|
|
22
22
|
},
|