protect-mcp 0.5.0 → 0.5.2
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 +152 -161
- package/dist/{chunk-IUFFDQYZ.mjs → chunk-IWDR5WU3.mjs} +1 -1
- package/dist/{chunk-V52W3XIN.mjs → chunk-N4F76LTC.mjs} +12 -8
- package/dist/{chunk-IAJJA5IW.mjs → chunk-Q4KOQUKV.mjs} +1 -1
- package/dist/{chunk-YKM6W6T7.mjs → chunk-W4U5VNEC.mjs} +2 -2
- package/dist/cli.js +12 -8
- package/dist/cli.mjs +4 -4
- package/dist/hook-server.js +12 -8
- package/dist/hook-server.mjs +2 -2
- package/dist/{http-transport-GXIXLVJQ.mjs → http-transport-PWCK7JHZ.mjs} +2 -2
- package/dist/index.d.mts +118 -1
- package/dist/index.d.ts +118 -1
- package/dist/index.js +289 -8
- package/dist/index.mjs +279 -4
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -1,62 +1,127 @@
|
|
|
1
1
|
# protect-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Enterprise security gateway for MCP servers and Claude Code hooks. Signed receipts, Cedar policies, and swarm-aware audit trails.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Quick Start — Claude Code
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Two commands. Every tool call is receipted.
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
#
|
|
11
|
-
npx
|
|
10
|
+
# 1. Generate hooks, keys, Cedar policy, and /verify-receipt skill
|
|
11
|
+
npx protect-mcp init-hooks
|
|
12
12
|
|
|
13
|
-
#
|
|
14
|
-
npx protect-mcp
|
|
13
|
+
# 2. Start the hook server
|
|
14
|
+
npx protect-mcp serve
|
|
15
|
+
```
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
npx protect-mcp init
|
|
17
|
+
Open Claude Code in the same project. Every tool call is now intercepted, evaluated, and signed.
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
npx protect-mcp --policy protect-mcp.json -- node my-server.js
|
|
19
|
+
### What `init-hooks` creates
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
| File | Purpose |
|
|
22
|
+
|------|---------|
|
|
23
|
+
| `.claude/settings.json` | Hook config (PreToolUse, PostToolUse, + 9 lifecycle events) |
|
|
24
|
+
| `keys/gateway.json` | Ed25519 signing keypair (auto-gitignored) |
|
|
25
|
+
| `policies/agent.cedar` | Starter Cedar policy — customize to your needs |
|
|
26
|
+
| `protect-mcp.json` | JSON policy with signing + rate limits |
|
|
27
|
+
| `.claude/skills/verify-receipt/SKILL.md` | `/verify-receipt` skill for Claude Code |
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
### Architecture
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
Claude Code → POST /hook → protect-mcp (Cedar + sign) → response
|
|
33
|
+
↓
|
|
34
|
+
.protect-mcp-log.jsonl
|
|
35
|
+
.protect-mcp-receipts.jsonl
|
|
27
36
|
```
|
|
28
37
|
|
|
29
|
-
|
|
38
|
+
- **PreToolUse**: synchronous Cedar policy check → deny blocks the tool
|
|
39
|
+
- **PostToolUse**: async receipt signing → zero latency impact
|
|
40
|
+
- **deny is architecturally final** — it cannot be overridden by the model or other hooks
|
|
41
|
+
|
|
42
|
+
### Endpoints
|
|
43
|
+
|
|
44
|
+
| Method | Path | Description |
|
|
45
|
+
|--------|------|-------------|
|
|
46
|
+
| POST | `/hook` | Claude Code hook endpoint |
|
|
47
|
+
| GET | `/health` | Server status, policy info, signer info |
|
|
48
|
+
| GET | `/receipts` | Recent signed receipts |
|
|
49
|
+
| GET | `/receipts/latest` | Most recent receipt |
|
|
50
|
+
| GET | `/suggestions` | Auto-generated Cedar policy fix suggestions |
|
|
51
|
+
| GET | `/alerts` | Config tamper detection alerts |
|
|
30
52
|
|
|
31
|
-
|
|
53
|
+
### Verify receipts
|
|
32
54
|
|
|
55
|
+
```bash
|
|
56
|
+
# Inside Claude Code:
|
|
57
|
+
/verify-receipt
|
|
58
|
+
|
|
59
|
+
# From terminal:
|
|
60
|
+
curl http://127.0.0.1:9377/receipts/latest | jq .
|
|
61
|
+
npx protect-mcp receipts
|
|
62
|
+
|
|
63
|
+
# Check policy suggestions:
|
|
64
|
+
curl http://127.0.0.1:9377/suggestions | jq .
|
|
33
65
|
```
|
|
34
|
-
|
|
66
|
+
|
|
67
|
+
## Quick Start — MCP Server Wrapper
|
|
68
|
+
|
|
69
|
+
Wrap any stdio MCP server as a transparent proxy:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Shadow mode — log every tool call, enforce nothing
|
|
73
|
+
npx protect-mcp -- node my-server.js
|
|
74
|
+
|
|
75
|
+
# Enforce mode with policy
|
|
76
|
+
npx protect-mcp --policy protect-mcp.json --enforce -- node my-server.js
|
|
77
|
+
|
|
78
|
+
# Generate keys + config template
|
|
79
|
+
npx protect-mcp init
|
|
35
80
|
```
|
|
36
81
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
|
|
82
|
+
## How It Works
|
|
83
|
+
|
|
84
|
+
protect-mcp evaluates every tool call against a policy (JSON, Cedar, or external PDP), signs the decision as an Ed25519 receipt, and logs the result.
|
|
85
|
+
|
|
86
|
+
**Two integration modes:**
|
|
41
87
|
|
|
42
|
-
|
|
88
|
+
| Mode | Transport | Use Case |
|
|
89
|
+
|------|-----------|----------|
|
|
90
|
+
| Hook Server | HTTP (`npx protect-mcp serve`) | Claude Code, agent swarms |
|
|
91
|
+
| Stdio Proxy | stdin/stdout (`npx protect-mcp -- ...`) | Claude Desktop, Cursor, any MCP client |
|
|
43
92
|
|
|
44
|
-
|
|
93
|
+
**Three policy engines:**
|
|
45
94
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
95
|
+
| Engine | Config | Notes |
|
|
96
|
+
|--------|--------|-------|
|
|
97
|
+
| JSON | `--policy policy.json` | Simple per-tool rules |
|
|
98
|
+
| Cedar | `--cedar ./policies/` | Local WASM evaluation via `@cedar-policy/cedar-wasm` |
|
|
99
|
+
| External PDP | `policy_engine: "external"` | OPA, Cerbos, or any HTTP PDP |
|
|
51
100
|
|
|
52
|
-
##
|
|
101
|
+
## Swarm Tracking
|
|
53
102
|
|
|
54
|
-
|
|
103
|
+
In multi-agent sessions, protect-mcp automatically tracks the swarm topology.
|
|
55
104
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
105
|
+
**11 hook events handled:**
|
|
106
|
+
|
|
107
|
+
| Event | Type | Description |
|
|
108
|
+
|-------|------|-------------|
|
|
109
|
+
| `PreToolUse` | Sync | Cedar/policy evaluation before tool execution |
|
|
110
|
+
| `PostToolUse` | Async | Receipt signing after tool execution |
|
|
111
|
+
| `SubagentStart` / `SubagentStop` | Lifecycle | Worker agent spawn/completion |
|
|
112
|
+
| `TaskCreated` / `TaskCompleted` | Lifecycle | Coordinator task assignment |
|
|
113
|
+
| `SessionStart` / `SessionEnd` | Lifecycle | Session lifecycle with sandbox detection |
|
|
114
|
+
| `TeammateIdle` | Lifecycle | Agent utilization monitoring |
|
|
115
|
+
| `ConfigChange` | Security | Tamper detection for `.claude/settings.json` |
|
|
116
|
+
| `Stop` | Lifecycle | Finalization + policy suggestion summary |
|
|
117
|
+
|
|
118
|
+
Each receipt includes:
|
|
119
|
+
- `swarm.agent_id`, `swarm.agent_type`, `swarm.team_name`
|
|
120
|
+
- `timing.tool_duration_ms`, `timing.hook_latency_ms`
|
|
121
|
+
- `payload_digest` (SHA-256 hash for payloads >1KB)
|
|
122
|
+
- `deny_iteration` (retry count after denial)
|
|
123
|
+
- `sandbox_state` (enabled/disabled/unavailable)
|
|
124
|
+
- OpenTelemetry `otel_trace_id` and `otel_span_id`
|
|
60
125
|
|
|
61
126
|
## Policy File
|
|
62
127
|
|
|
@@ -73,34 +138,50 @@ These are important before you roll this out or talk to users:
|
|
|
73
138
|
"key_path": "./keys/gateway.json",
|
|
74
139
|
"issuer": "protect-mcp",
|
|
75
140
|
"enabled": true
|
|
76
|
-
},
|
|
77
|
-
"credentials": {
|
|
78
|
-
"internal_api": {
|
|
79
|
-
"inject": "env",
|
|
80
|
-
"name": "INTERNAL_API_KEY",
|
|
81
|
-
"value_env": "INTERNAL_API_KEY"
|
|
82
|
-
}
|
|
83
141
|
}
|
|
84
142
|
}
|
|
85
143
|
```
|
|
86
144
|
|
|
87
|
-
###
|
|
145
|
+
### Cedar Policies
|
|
146
|
+
|
|
147
|
+
Cedar deny decisions are **authoritative** — they cannot be overridden.
|
|
148
|
+
|
|
149
|
+
```cedar
|
|
150
|
+
// Allow read-only tools
|
|
151
|
+
permit(
|
|
152
|
+
principal,
|
|
153
|
+
action == Action::"MCP::Tool::call",
|
|
154
|
+
resource == Tool::"Read"
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
// Block destructive tools
|
|
158
|
+
forbid(
|
|
159
|
+
principal,
|
|
160
|
+
action == Action::"MCP::Tool::call",
|
|
161
|
+
resource == Tool::"delete_file"
|
|
162
|
+
);
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
When a tool is denied, protect-mcp auto-suggests the minimal Cedar `permit()` rule via `GET /suggestions`.
|
|
166
|
+
|
|
167
|
+
## CVE-Anchored Policy Packs
|
|
88
168
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
|
92
|
-
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
169
|
+
Each prevents a real attack:
|
|
170
|
+
|
|
171
|
+
| Policy | Incident | OWASP |
|
|
172
|
+
|--------|----------|-------|
|
|
173
|
+
| `clinejection.json` | CVE-2025-6514: MCP OAuth proxy hijack (437K environments) | A01, A03 |
|
|
174
|
+
| `terraform-destroy.json` | Autonomous Terraform agent destroys production | A05, A06 |
|
|
175
|
+
| `github-mcp-hijack.json` | Prompt injection via crafted GitHub issue | A01, A02, A03 |
|
|
176
|
+
| `data-exfiltration.json` | Agent data theft via outbound tool abuse | A02, A04 |
|
|
177
|
+
| `financial-safe.json` | Unauthorized financial transaction | A05, A06 |
|
|
95
178
|
|
|
96
|
-
|
|
179
|
+
Cedar equivalents available in `policies/cedar/`.
|
|
97
180
|
|
|
98
181
|
## MCP Client Configuration
|
|
99
182
|
|
|
100
183
|
### Claude Desktop
|
|
101
184
|
|
|
102
|
-
Add to `claude_desktop_config.json`:
|
|
103
|
-
|
|
104
185
|
```json
|
|
105
186
|
{
|
|
106
187
|
"mcpServers": {
|
|
@@ -121,146 +202,56 @@ Add to `claude_desktop_config.json`:
|
|
|
121
202
|
|
|
122
203
|
Same pattern — replace the server command with `protect-mcp` wrapping it.
|
|
123
204
|
|
|
124
|
-
## CLI
|
|
205
|
+
## CLI Commands
|
|
125
206
|
|
|
126
207
|
```
|
|
127
|
-
protect-mcp [options] -- <command> [args...]
|
|
128
|
-
protect-mcp init
|
|
129
|
-
|
|
130
208
|
Commands:
|
|
209
|
+
serve Start HTTP hook server for Claude Code (port 9377)
|
|
210
|
+
init-hooks Generate Claude Code hook config + skill + sample Cedar policy
|
|
211
|
+
quickstart Zero-config onboarding: init + demo + show receipts
|
|
131
212
|
init Generate Ed25519 keypair + config template
|
|
132
|
-
|
|
133
|
-
|
|
213
|
+
demo Start a demo server wrapped with protect-mcp
|
|
214
|
+
doctor Check your setup: keys, policies, verifier, connectivity
|
|
215
|
+
trace <id> Visualize the receipt DAG from a given receipt_id
|
|
216
|
+
status Show tool call statistics from the decision log
|
|
217
|
+
digest Generate a human-readable summary of agent activity
|
|
134
218
|
receipts Show recent persisted signed receipts
|
|
135
219
|
bundle Export an offline-verifiable audit bundle
|
|
220
|
+
simulate Dry-run a policy against recorded tool calls
|
|
221
|
+
report Generate a compliance report from an audit bundle
|
|
136
222
|
|
|
137
223
|
Options:
|
|
138
224
|
--policy <path> Policy/config JSON file
|
|
139
|
-
--
|
|
225
|
+
--cedar <dir> Cedar policy directory
|
|
140
226
|
--enforce Enable enforcement mode (default: shadow)
|
|
227
|
+
--port <port> HTTP server port (default: 9377 for serve)
|
|
141
228
|
--verbose Enable debug logging
|
|
142
|
-
--help Show help
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
## Programmatic Hooks
|
|
146
|
-
|
|
147
|
-
The library also exposes the primitives that are not yet wired into the default CLI path:
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
import {
|
|
151
|
-
ProtectGateway,
|
|
152
|
-
loadPolicy,
|
|
153
|
-
evaluateTier,
|
|
154
|
-
meetsMinTier,
|
|
155
|
-
resolveCredential,
|
|
156
|
-
initSigning,
|
|
157
|
-
signDecision,
|
|
158
|
-
queryExternalPDP,
|
|
159
|
-
buildDecisionContext,
|
|
160
|
-
createAuditBundle,
|
|
161
|
-
} from 'protect-mcp';
|
|
162
229
|
```
|
|
163
230
|
|
|
164
|
-
|
|
165
|
-
- manifest admission before a session starts
|
|
166
|
-
- an external PDP (OPA, Cerbos, or a generic HTTP webhook)
|
|
167
|
-
- custom credential-brokered integrations
|
|
168
|
-
- audit bundle export around your own receipt store
|
|
169
|
-
|
|
170
|
-
## Decision Logs and Receipts
|
|
231
|
+
## Decision Logs
|
|
171
232
|
|
|
172
233
|
Every tool call emits structured JSON to `stderr`:
|
|
173
234
|
|
|
174
235
|
```json
|
|
175
|
-
[PROTECT_MCP] {"v":2,"tool":"read_file","decision":"allow","reason_code":"
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
When signing is configured, a signed receipt follows:
|
|
179
|
-
|
|
180
|
-
```json
|
|
181
|
-
[PROTECT_MCP_RECEIPT] {"v":2,"type":"decision_receipt","algorithm":"ed25519","kid":"...","issuer":"protect-mcp","issued_at":"2026-03-22T00:00:00Z","payload":{"tool":"read_file","decision":"allow","policy_digest":"...","mode":"shadow","request_id":"..."},"signature":"..."}
|
|
236
|
+
[PROTECT_MCP] {"v":2,"tool":"read_file","decision":"allow","reason_code":"cedar_allow","policy_digest":"a1b2c3...","mode":"enforce","hook_event":"PreToolUse","timing":{"hook_latency_ms":1},"otel_trace_id":"..."}
|
|
182
237
|
```
|
|
183
238
|
|
|
184
|
-
|
|
185
|
-
Verify in browser: [scopeblind.com/verify](https://scopeblind.com/verify)
|
|
239
|
+
When signing is configured, a signed receipt is persisted to `.protect-mcp-receipts.jsonl`.
|
|
186
240
|
|
|
187
241
|
## Audit Bundles
|
|
188
242
|
|
|
189
|
-
The package exports a helper for self-contained audit bundles:
|
|
190
|
-
|
|
191
|
-
```json
|
|
192
|
-
{
|
|
193
|
-
"format": "scopeblind:audit-bundle",
|
|
194
|
-
"version": 1,
|
|
195
|
-
"tenant": "my-service",
|
|
196
|
-
"receipts": ["..."],
|
|
197
|
-
"verification": {
|
|
198
|
-
"algorithm": "ed25519",
|
|
199
|
-
"signing_keys": ["..."]
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
Use `createAuditBundle()` around your own collected signed receipts.
|
|
205
|
-
|
|
206
|
-
## Philosophy
|
|
207
|
-
|
|
208
|
-
- **Shadow first.** See what agents are doing before you enforce anything.
|
|
209
|
-
- **Receipts beat dashboard-only logs.** Signed artifacts should be independently verifiable.
|
|
210
|
-
- **Keep the claims tight.** The default CLI path does not yet do everything the long-term architecture will support.
|
|
211
|
-
- **Layer on top of existing auth.** Don't rip out your stack just to add control and evidence.
|
|
212
|
-
|
|
213
|
-
## Incident-Anchored Policy Packs
|
|
214
|
-
|
|
215
|
-
Ship with protect-mcp — each prevents a real attack:
|
|
216
|
-
|
|
217
|
-
| Policy | Incident | OWASP Categories |
|
|
218
|
-
|--------|----------|-----------------|
|
|
219
|
-
| `clinejection.json` | CVE-2025-6514: MCP OAuth proxy hijack (437K environments) | A01, A03 |
|
|
220
|
-
| `terraform-destroy.json` | Autonomous Terraform agent destroys production | A05, A06 |
|
|
221
|
-
| `github-mcp-hijack.json` | Prompt injection via crafted GitHub issue | A01, A02, A03 |
|
|
222
|
-
| `data-exfiltration.json` | Agent data theft via outbound tool abuse | A02, A04 |
|
|
223
|
-
| `financial-safe.json` | Unauthorized financial transaction | A05, A06 |
|
|
224
|
-
|
|
225
|
-
Cedar-native policies are also available in `policies/cedar/`:
|
|
226
|
-
|
|
227
|
-
| Policy | Purpose |
|
|
228
|
-
|--------|---------|
|
|
229
|
-
| `clinejection.cedar` | Cedar equivalent of the clinejection JSON policy |
|
|
230
|
-
| `terraform-destroy.cedar` | Cedar equivalent of the terraform-destroy JSON policy |
|
|
231
|
-
| `spending-authority.cedar` | Spending authority controls — caps per-tool transaction amounts and requires elevated tiers for high-value operations |
|
|
232
|
-
|
|
233
243
|
```bash
|
|
234
|
-
|
|
235
|
-
npx protect-mcp --policy node_modules/protect-mcp/policies/clinejection.json -- node server.js
|
|
236
|
-
|
|
237
|
-
# Cedar policy (requires @cedar-policy/cedar-wasm)
|
|
238
|
-
npx protect-mcp --policy node_modules/protect-mcp/policies/cedar/spending-authority.cedar --enforce -- node server.js
|
|
244
|
+
npx protect-mcp bundle --output audit.json
|
|
239
245
|
```
|
|
240
246
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
## BYOPE: External Policy Engines
|
|
244
|
-
|
|
245
|
-
Supports OPA, Cerbos, Cedar (AWS AgentCore), and generic HTTP endpoints:
|
|
246
|
-
|
|
247
|
-
```json
|
|
248
|
-
{
|
|
249
|
-
"policy_engine": "hybrid",
|
|
250
|
-
"external": {
|
|
251
|
-
"endpoint": "http://localhost:8181/v1/data/mcp/allow",
|
|
252
|
-
"format": "cedar",
|
|
253
|
-
"timeout_ms": 200,
|
|
254
|
-
"fallback": "deny"
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
```
|
|
247
|
+
Self-contained offline-verifiable bundle with receipts + signing keys. Verify with `npx @veritasacta/verify`.
|
|
258
248
|
|
|
259
249
|
## Standards & IP
|
|
260
250
|
|
|
261
251
|
- **IETF Internet-Draft**: [draft-farley-acta-signed-receipts-00](https://datatracker.ietf.org/doc/draft-farley-acta-signed-receipts/) — Signed Decision Receipts for Machine-to-Machine Access Control
|
|
262
252
|
- **Patent Status**: 4 Australian provisional patents pending (2025-2026) covering decision receipts with configurable disclosure, tool-calling gateway, agent manifests, and portable identity
|
|
263
253
|
- **Verification**: MIT-licensed — `npx @veritasacta/verify --self-test`
|
|
254
|
+
- **Microsoft AGT Integration**: [PR #667](https://github.com/microsoft/agent-governance-toolkit/pull/667) — Cedar policy bridge for Agent Governance Toolkit
|
|
264
255
|
|
|
265
256
|
## License
|
|
266
257
|
|
|
@@ -232,7 +232,7 @@ function buildEntities(req) {
|
|
|
232
232
|
}
|
|
233
233
|
];
|
|
234
234
|
}
|
|
235
|
-
async function evaluateCedar(policySet, req) {
|
|
235
|
+
async function evaluateCedar(policySet, req, schema) {
|
|
236
236
|
const available = await ensureCedarWasm();
|
|
237
237
|
if (!available) {
|
|
238
238
|
return {
|
|
@@ -243,16 +243,21 @@ async function evaluateCedar(policySet, req) {
|
|
|
243
243
|
}
|
|
244
244
|
try {
|
|
245
245
|
const agentId = req.agentId || req.tier;
|
|
246
|
+
const context = {
|
|
247
|
+
tier: req.tier,
|
|
248
|
+
...req.context || {}
|
|
249
|
+
};
|
|
250
|
+
if (req.toolInput && Object.keys(req.toolInput).length > 0) {
|
|
251
|
+
context.input = req.toolInput;
|
|
252
|
+
}
|
|
246
253
|
const authRequest = {
|
|
247
254
|
principal: { type: "Agent", id: agentId },
|
|
248
255
|
action: { type: "Action", id: "MCP::Tool::call" },
|
|
249
256
|
resource: { type: "Tool", id: req.tool },
|
|
250
|
-
context
|
|
251
|
-
tier: req.tier,
|
|
252
|
-
...req.context || {}
|
|
253
|
-
}
|
|
257
|
+
context
|
|
254
258
|
};
|
|
255
259
|
const entities = buildEntities(req);
|
|
260
|
+
const cedarSchema = schema?.schemaJson ?? null;
|
|
256
261
|
let result;
|
|
257
262
|
if (typeof cedarWasm.isAuthorized === "function") {
|
|
258
263
|
result = cedarWasm.isAuthorized({
|
|
@@ -262,8 +267,7 @@ async function evaluateCedar(policySet, req) {
|
|
|
262
267
|
action: authRequest.action,
|
|
263
268
|
resource: authRequest.resource,
|
|
264
269
|
context: authRequest.context,
|
|
265
|
-
schema:
|
|
266
|
-
// No schema enforcement — Cedar still evaluates correctly
|
|
270
|
+
schema: cedarSchema
|
|
267
271
|
});
|
|
268
272
|
} else if (typeof cedarWasm.checkAuthorization === "function") {
|
|
269
273
|
result = cedarWasm.checkAuthorization(
|
|
@@ -281,7 +285,7 @@ async function evaluateCedar(policySet, req) {
|
|
|
281
285
|
action: authRequest.action,
|
|
282
286
|
resource: authRequest.resource,
|
|
283
287
|
context: authRequest.context,
|
|
284
|
-
schema:
|
|
288
|
+
schema: cedarSchema
|
|
285
289
|
});
|
|
286
290
|
} else {
|
|
287
291
|
return {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
meetsMinTier
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-IWDR5WU3.mjs";
|
|
4
4
|
import {
|
|
5
5
|
checkRateLimit,
|
|
6
6
|
getToolPolicy,
|
|
7
7
|
parseRateLimit
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-N4F76LTC.mjs";
|
|
9
9
|
|
|
10
10
|
// src/simulate.ts
|
|
11
11
|
import { readFileSync } from "fs";
|
package/dist/cli.js
CHANGED
|
@@ -682,7 +682,7 @@ function buildEntities(req) {
|
|
|
682
682
|
}
|
|
683
683
|
];
|
|
684
684
|
}
|
|
685
|
-
async function evaluateCedar(policySet, req) {
|
|
685
|
+
async function evaluateCedar(policySet, req, schema) {
|
|
686
686
|
const available = await ensureCedarWasm();
|
|
687
687
|
if (!available) {
|
|
688
688
|
return {
|
|
@@ -693,16 +693,21 @@ async function evaluateCedar(policySet, req) {
|
|
|
693
693
|
}
|
|
694
694
|
try {
|
|
695
695
|
const agentId = req.agentId || req.tier;
|
|
696
|
+
const context = {
|
|
697
|
+
tier: req.tier,
|
|
698
|
+
...req.context || {}
|
|
699
|
+
};
|
|
700
|
+
if (req.toolInput && Object.keys(req.toolInput).length > 0) {
|
|
701
|
+
context.input = req.toolInput;
|
|
702
|
+
}
|
|
696
703
|
const authRequest = {
|
|
697
704
|
principal: { type: "Agent", id: agentId },
|
|
698
705
|
action: { type: "Action", id: "MCP::Tool::call" },
|
|
699
706
|
resource: { type: "Tool", id: req.tool },
|
|
700
|
-
context
|
|
701
|
-
tier: req.tier,
|
|
702
|
-
...req.context || {}
|
|
703
|
-
}
|
|
707
|
+
context
|
|
704
708
|
};
|
|
705
709
|
const entities = buildEntities(req);
|
|
710
|
+
const cedarSchema = schema?.schemaJson ?? null;
|
|
706
711
|
let result;
|
|
707
712
|
if (typeof cedarWasm.isAuthorized === "function") {
|
|
708
713
|
result = cedarWasm.isAuthorized({
|
|
@@ -712,8 +717,7 @@ async function evaluateCedar(policySet, req) {
|
|
|
712
717
|
action: authRequest.action,
|
|
713
718
|
resource: authRequest.resource,
|
|
714
719
|
context: authRequest.context,
|
|
715
|
-
schema:
|
|
716
|
-
// No schema enforcement — Cedar still evaluates correctly
|
|
720
|
+
schema: cedarSchema
|
|
717
721
|
});
|
|
718
722
|
} else if (typeof cedarWasm.checkAuthorization === "function") {
|
|
719
723
|
result = cedarWasm.checkAuthorization(
|
|
@@ -731,7 +735,7 @@ async function evaluateCedar(policySet, req) {
|
|
|
731
735
|
action: authRequest.action,
|
|
732
736
|
resource: authRequest.resource,
|
|
733
737
|
context: authRequest.context,
|
|
734
|
-
schema:
|
|
738
|
+
schema: cedarSchema
|
|
735
739
|
});
|
|
736
740
|
} else {
|
|
737
741
|
return {
|
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-W4U5VNEC.mjs";
|
|
7
7
|
import {
|
|
8
8
|
ProtectGateway,
|
|
9
9
|
validateCredentials
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-IWDR5WU3.mjs";
|
|
11
11
|
import {
|
|
12
12
|
initSigning,
|
|
13
13
|
isCedarAvailable,
|
|
14
14
|
loadCedarPolicies,
|
|
15
15
|
loadPolicy
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-N4F76LTC.mjs";
|
|
17
17
|
import "./chunk-PQJP2ZCI.mjs";
|
|
18
18
|
|
|
19
19
|
// src/cli.ts
|
|
@@ -1282,7 +1282,7 @@ async function main() {
|
|
|
1282
1282
|
if (useHttp) {
|
|
1283
1283
|
const portIdx = args.indexOf("--port");
|
|
1284
1284
|
const httpPort = portIdx >= 0 && args[portIdx + 1] ? parseInt(args[portIdx + 1]) : 3e3;
|
|
1285
|
-
const { startHttpTransport } = await import("./http-transport-
|
|
1285
|
+
const { startHttpTransport } = await import("./http-transport-PWCK7JHZ.mjs");
|
|
1286
1286
|
startHttpTransport({ port: httpPort, config, serverCommand: childCommand });
|
|
1287
1287
|
return;
|
|
1288
1288
|
}
|
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 {
|
package/dist/hook-server.mjs
CHANGED