agentgate-runtime-control 2.13.8
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 +229 -0
- package/LICENSE +21 -0
- package/README.md +534 -0
- package/SECURITY.md +19 -0
- package/bin/agentgate.js +303 -0
- package/docs/case-study-technical-validation.md +25 -0
- package/docs/case-study-template.md +37 -0
- package/docs/data-protection.md +49 -0
- package/docs/design-partner-checklist.md +32 -0
- package/docs/design-partner-kit.md +51 -0
- package/docs/design-partner-rollout.md +35 -0
- package/docs/design-partner.md +67 -0
- package/docs/external-security-review-test-pack.md +132 -0
- package/docs/external-security-review.md +33 -0
- package/docs/incident-response.md +54 -0
- package/docs/integration-matrix.md +17 -0
- package/docs/managed-postgres-acceptance-test.md +138 -0
- package/docs/marketing-plan.md +33 -0
- package/docs/observability-alerting.md +44 -0
- package/docs/outreach.md +26 -0
- package/docs/partner-intake-template.md +26 -0
- package/docs/performance-baseline.md +23 -0
- package/docs/performance.md +27 -0
- package/docs/pricing.md +53 -0
- package/docs/production-deployment.md +70 -0
- package/docs/production-quickstart.md +58 -0
- package/docs/production-readiness.md +29 -0
- package/docs/quickstart.md +115 -0
- package/docs/release-checklist.md +33 -0
- package/docs/security-hardening-release-report.md +69 -0
- package/docs/threat-model.md +47 -0
- package/docs/website-copy.md +44 -0
- package/examples/basic.mjs +14 -0
- package/examples/control-plane.mjs +17 -0
- package/examples/design-partner-refund.mjs +33 -0
- package/examples/design-partner-shadow.mjs +27 -0
- package/examples/mcp-gateway.mjs +26 -0
- package/examples/policy-bundle.mjs +18 -0
- package/examples/refund-agent.mjs +20 -0
- package/examples/runtime.mjs +12 -0
- package/package.json +49 -0
- package/schema/postgres.sql +17 -0
- package/src/admin-rbac.js +3 -0
- package/src/agentgate.js +85 -0
- package/src/approval.js +30 -0
- package/src/attack-lab.js +94 -0
- package/src/auth.js +27 -0
- package/src/behavior.js +146 -0
- package/src/control-plane.js +215 -0
- package/src/egress-guard.js +132 -0
- package/src/event-bus.js +10 -0
- package/src/identity.js +109 -0
- package/src/index.js +44 -0
- package/src/local-experience.js +46 -0
- package/src/mcp-gateway.js +383 -0
- package/src/mcp-scanner.js +45 -0
- package/src/middleware.js +17 -0
- package/src/multi-tenant.js +29 -0
- package/src/observability.js +395 -0
- package/src/oidc.js +38 -0
- package/src/persistent-store.js +56 -0
- package/src/policy-builder.js +74 -0
- package/src/policy-bundles.js +17 -0
- package/src/policy-engine.js +67 -0
- package/src/policy-packs.js +115 -0
- package/src/policy-registry.js +58 -0
- package/src/postgres-adapter.js +76 -0
- package/src/runtime.js +138 -0
- package/src/saas.js +67 -0
- package/src/security-report.js +42 -0
- package/src/security-validation.js +92 -0
- package/src/shadow-mode.js +47 -0
- package/src/telemetry.js +28 -0
- package/src/webhook-delivery.js +70 -0
- package/standalone.html +86 -0
package/README.md
ADDED
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
# AgentGate v2.13.8 — First-Client Hardening
|
|
2
|
+
|
|
3
|
+
**The runtime control plane for AI agents.**
|
|
4
|
+
|
|
5
|
+
AgentGate sits between an agent and its tools and makes runtime decisions:
|
|
6
|
+
|
|
7
|
+
`ALLOW` → execute · `ASK` → require approval · `BLOCK` → stop
|
|
8
|
+
|
|
9
|
+
### Security-aware observability
|
|
10
|
+
|
|
11
|
+
AgentGate does not attempt to replace generic tracing platforms. Its observability layer joins runtime behavior to the controls that protect the agent:
|
|
12
|
+
|
|
13
|
+
- Unified trace: LLM → tool → policy → approval → execution → egress → behavior → cost
|
|
14
|
+
- Deterministic Agent Efficiency Score with transparent breakdown
|
|
15
|
+
- Behavior × Cost × Security correlation
|
|
16
|
+
- Cost analytics by agent, model, tool, action, tenant and customer/user
|
|
17
|
+
- Security cost: blocked calls, approvals, attack tests and egress blocks
|
|
18
|
+
- Deterministic month-end cost forecast from month-to-date run-rate
|
|
19
|
+
- Cost Guardrails can produce ALLOW / ASK / BLOCK decisions before tool execution
|
|
20
|
+
|
|
21
|
+
Useful control-plane endpoints include `/api/observability`, `/api/trace?runId=...`, `/api/efficiency`, `/api/behavior/correlation`, `/api/cost/analytics`, and `/api/cost/forecast`.
|
|
22
|
+
|
|
23
|
+
## Developer loop
|
|
24
|
+
|
|
25
|
+
**Observe → Attack → Enforce → Replay → Report → Govern**
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## Design Partner Edition
|
|
29
|
+
|
|
30
|
+
AgentGate 2.13.8 focuses on controlled design-partner adoption before public marketing. Start with one sensitive tool, use Observe/Shadow mode, then move to Enforce only after the acceptance gates pass.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install agentgate-runtime-control
|
|
34
|
+
npx agentgate pack list
|
|
35
|
+
npx agentgate pack test support-refund-safety
|
|
36
|
+
npx agentgate attack
|
|
37
|
+
npx agentgate demo refund
|
|
38
|
+
npx agentgate doctor
|
|
39
|
+
npx agentgate simulate
|
|
40
|
+
npx agentgate validate-security
|
|
41
|
+
npx agentgate dev
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Then read [`docs/quickstart.md`](docs/quickstart.md) for the recommended observe → attack → enforce rollout, or [`docs/design-partner.md`](docs/design-partner.md) for the first-partner workflow.
|
|
45
|
+
|
|
46
|
+
### Docker
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
docker build -t agentgate .
|
|
50
|
+
docker run --rm -p 8787:8787 agentgate
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Examples
|
|
54
|
+
|
|
55
|
+
- `examples/refund-agent.mjs` — protect a real side-effecting refund tool.
|
|
56
|
+
- `examples/policy-bundle.mjs` — test and activate a versioned policy bundle.
|
|
57
|
+
|
|
58
|
+
## Production readiness
|
|
59
|
+
|
|
60
|
+
See [`docs/production-readiness.md`](docs/production-readiness.md), [`docs/production-deployment.md`](docs/production-deployment.md), and [`docs/release-checklist.md`](docs/release-checklist.md) for deployment, operational, performance, and release gates.
|
|
61
|
+
|
|
62
|
+
## Security
|
|
63
|
+
|
|
64
|
+
See [`SECURITY.md`](SECURITY.md) for the security model and vulnerability-reporting guidance. AgentGate provides a deterministic control layer; it does not replace application-level identity, secret management, network isolation, or threat-model testing.
|
|
65
|
+
|
|
66
|
+
## Agent Observability
|
|
67
|
+
|
|
68
|
+
AgentGate adds security-aware observability on top of the same runtime runs used for enforcement and replay. It reports decision counts, success/error rates, P50/P95/P99 latency, tool/agent/model breakdowns, unified security traces, deterministic Agent Efficiency scores, behavior×cost×security correlation, cost analytics, and deterministic cost forecasting.
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
const gateway = createMCPGateway({
|
|
72
|
+
pricing: {
|
|
73
|
+
'my-model': { inputPer1M: 1, outputPer1M: 2, cachedInputPer1M: 0.25 }
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const report = gateway.observability.analyze(gateway.runs());
|
|
78
|
+
console.log(report.latency.p95);
|
|
79
|
+
console.log(report.security);
|
|
80
|
+
console.log(report.cost);
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Pricing is intentionally explicit and provider-neutral because model pricing changes over time.
|
|
84
|
+
|
|
85
|
+
## Cost Control
|
|
86
|
+
|
|
87
|
+
Cost thresholds can become runtime controls instead of passive dashboard alerts:
|
|
88
|
+
|
|
89
|
+
```js
|
|
90
|
+
const gateway = createMCPGateway({
|
|
91
|
+
budgets: {
|
|
92
|
+
daily: { ask: 50, hard: 100 },
|
|
93
|
+
monthly: { ask: 1000, hard: 1500 }
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
When an estimated action cost crosses `ask`, AgentGate enters the normal approval path. When it crosses `hard`, the action is blocked. The control is deterministic and separate from the security policy engine.
|
|
99
|
+
|
|
100
|
+
The Control Plane exposes `/api/observability`, `/api/trace`, `/api/efficiency`, `/api/behavior/correlation`, `/api/cost`, `/api/cost/analytics`, `/api/cost/forecast`, `/api/cost/pricing`, and `/api/cost/budgets`.
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
## Install
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npm install agentgate-runtime-control
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Protect a tool
|
|
110
|
+
|
|
111
|
+
```js
|
|
112
|
+
import { protect } from 'agentgate-runtime-control';
|
|
113
|
+
|
|
114
|
+
const refund = protect(myRefundTool, {
|
|
115
|
+
approvalActions: ['refund'],
|
|
116
|
+
approvalAmount: 5000
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Runtime
|
|
121
|
+
|
|
122
|
+
```js
|
|
123
|
+
import { createRuntime } from 'agentgate-runtime-control';
|
|
124
|
+
|
|
125
|
+
const gate = createRuntime({
|
|
126
|
+
mode: 'enforce',
|
|
127
|
+
policies: { productionBlock: true }
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
await gate.execute(myTool, {
|
|
131
|
+
agent: 'support-agent',
|
|
132
|
+
tool: 'delete_customer',
|
|
133
|
+
action: 'delete',
|
|
134
|
+
environment: 'production'
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
console.log(gate.runs());
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Observe mode records what AgentGate **would** block/ask without interrupting production. Enforce mode applies the decision.
|
|
141
|
+
|
|
142
|
+
## Attack Lab
|
|
143
|
+
|
|
144
|
+
```js
|
|
145
|
+
import { runAttackLab } from 'agentgate-runtime-control';
|
|
146
|
+
console.table(runAttackLab({ productionBlock: true }));
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The built-in lab covers prompt injection, privilege escalation, destructive actions, high-value refunds, and unsafe tool chaining. It is a testing aid, not a guarantee of security.
|
|
150
|
+
|
|
151
|
+
## CLI
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
agentgate test refund 1200
|
|
155
|
+
agentgate attack
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## MCP Gateway
|
|
159
|
+
|
|
160
|
+
AgentGate can now sit between an MCP client/agent and tool handlers. It supports MCP-style JSON-RPC methods for `initialize`, `ping`, `tools/list`, and `tools/call`.
|
|
161
|
+
|
|
162
|
+
```js
|
|
163
|
+
import { createMCPGatewayServer } from 'agentgate-runtime-control/mcp-gateway';
|
|
164
|
+
|
|
165
|
+
const { server } = createMCPGatewayServer({
|
|
166
|
+
mode: 'enforce',
|
|
167
|
+
policies: { blockActions: ['export_all'] },
|
|
168
|
+
tools: [{ name: 'read', handler: async () => 'ok' }]
|
|
169
|
+
});
|
|
170
|
+
server.listen(8787);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Every tool call is evaluated before execution and recorded with a run ID, decision, risk, reason, and execution result/error. In `observe` mode, risky calls are recorded but still execute, making it possible to test policies before enforcement.
|
|
174
|
+
|
|
175
|
+
Run the example with:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
node examples/mcp-gateway.mjs
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## MCP Gateway Attack Lab
|
|
182
|
+
|
|
183
|
+
AgentGate can now execute its built-in attack scenarios through the MCP gateway itself:
|
|
184
|
+
|
|
185
|
+
```js
|
|
186
|
+
import { createMCPGateway, runGatewayAttackLab } from 'agentgate-runtime-control';
|
|
187
|
+
|
|
188
|
+
const gateway = createMCPGateway({
|
|
189
|
+
mode: 'enforce',
|
|
190
|
+
policies: { productionBlock: true },
|
|
191
|
+
tools: [
|
|
192
|
+
{ name: 'refund', handler: async (input) => refundCustomer(input) },
|
|
193
|
+
{ name: 'delete', handler: async (input) => deleteWorkspace(input) },
|
|
194
|
+
{ name: 'export_all', handler: async (input) => exportRecords(input) }
|
|
195
|
+
]
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
const results = await runGatewayAttackLab(gateway);
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Each scenario is sent through the same authorization path used by real MCP calls. Results include the decision, risk, replay run ID, and whether the gateway prevented or paused the attack.
|
|
202
|
+
|
|
203
|
+
> Attack Lab is a controlled testing aid. Passing the built-in scenarios is not a security guarantee.
|
|
204
|
+
|
|
205
|
+
## Policy Builder
|
|
206
|
+
|
|
207
|
+
Turn Attack Lab results into reviewable policy suggestions:
|
|
208
|
+
|
|
209
|
+
```js
|
|
210
|
+
import { generatePolicySuggestions, mergePolicies } from 'agentgate-runtime-control';
|
|
211
|
+
|
|
212
|
+
const report = await runGatewayAttackLab(gateway);
|
|
213
|
+
const generated = generatePolicySuggestions(report);
|
|
214
|
+
const nextPolicy = mergePolicies(currentPolicy, generated.policy);
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Policy generation is deterministic and reviewable. Generated suggestions do not automatically authorize or block traffic until the resulting policy is explicitly applied to a gateway.
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
## Approval Flow
|
|
221
|
+
|
|
222
|
+
Sensitive tool calls that evaluate to `ASK` enter a pending approval state and are never executed automatically in enforce mode.
|
|
223
|
+
|
|
224
|
+
```js
|
|
225
|
+
const result = await gateway.handle({
|
|
226
|
+
jsonrpc: '2.0',
|
|
227
|
+
id: 1,
|
|
228
|
+
method: 'tools/call',
|
|
229
|
+
params: { name: 'refund', action: 'refund', arguments: { amount: 1200 } }
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
const approvalId = result.result._agentgate.approvalId;
|
|
233
|
+
const approved = await gateway.approve(approvalId);
|
|
234
|
+
// approved.status === 'executed'
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
You can also deny with an auditable reason:
|
|
238
|
+
|
|
239
|
+
```js
|
|
240
|
+
await gateway.deny(approvalId, 'Not authorized for this request');
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Approval state is queryable through `gateway.approvals()` and JSON-RPC methods:
|
|
244
|
+
- `agentgate/approvals/list`
|
|
245
|
+
- `agentgate/approvals/approve`
|
|
246
|
+
- `agentgate/approvals/deny`
|
|
247
|
+
|
|
248
|
+
The approval layer is intentionally separate from policy evaluation: policy decides `ALLOW`, `ASK`, or `BLOCK`; approval resolves only the `ASK` path.
|
|
249
|
+
|
|
250
|
+
## v1.1 — Developer Integration
|
|
251
|
+
|
|
252
|
+
AgentGate now exposes a single developer-facing runtime:
|
|
253
|
+
|
|
254
|
+
```js
|
|
255
|
+
import { createAgentGate } from 'agentgate-runtime-control';
|
|
256
|
+
|
|
257
|
+
const gate = createAgentGate({
|
|
258
|
+
agent: 'SupportBot',
|
|
259
|
+
mode: 'enforce',
|
|
260
|
+
policies: { productionBlock: true }
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
const refund = gate.protect(
|
|
264
|
+
async ({ amount }) => ({ refunded: amount }),
|
|
265
|
+
{ tool: 'refund', action: 'refund' }
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
const result = await refund({ amount: 900 });
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
The protected tool receives deterministic `ALLOW`, `ASK`, or `BLOCK` decisions. In `observe` mode risky actions are executed but recorded as simulated decisions.
|
|
272
|
+
|
|
273
|
+
### CLI
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
npx agentgate init
|
|
277
|
+
npx agentgate doctor
|
|
278
|
+
npx agentgate simulate
|
|
279
|
+
npx agentgate validate-security
|
|
280
|
+
npx agentgate dev
|
|
281
|
+
npx agentgate test refund 900
|
|
282
|
+
npx agentgate attack
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
`agentgate dev` starts the local Control Plane at `http://localhost:8787`.
|
|
286
|
+
|
|
287
|
+
### MCP
|
|
288
|
+
|
|
289
|
+
Use `gate.withMCP()` to create an AgentGate-protected MCP gateway while keeping policy evaluation and approval handling in the same runtime.
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
## Attack Runner
|
|
293
|
+
|
|
294
|
+
Run the built-in attacks through the real MCP gateway:
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
agentgate attack
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
The runner records replayable run IDs and reports blocked, approval-required, and allowed outcomes. A non-zero exit code indicates at least one attack was not prevented.
|
|
301
|
+
|
|
302
|
+
## Behavior Detection & Blast Radius (v1.4)
|
|
303
|
+
|
|
304
|
+
AgentGate can analyze recorded runtime activity for deterministic behavior patterns such as suspicious tool chaining, repeated controlled actions, escalation attempts, and broad data access attempts. It also estimates blast radius from request metadata including scope, target count, environment, privilege, destructive behavior, exports, and transaction value. These are risk-analysis signals, not guarantees of actual impact.
|
|
305
|
+
|
|
306
|
+
```js
|
|
307
|
+
const behavior = gate.behavior();
|
|
308
|
+
const blastRadius = gate.blastRadius();
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
The control plane exposes:
|
|
312
|
+
- `GET /api/behavior`
|
|
313
|
+
- `GET /api/blast-radius`
|
|
314
|
+
|
|
315
|
+
Security reports now include `behavior` and `blastRadius` sections.
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
## Persistent Control Plane (v1.5)
|
|
319
|
+
|
|
320
|
+
AgentGate can persist runtime state without requiring a hosted database:
|
|
321
|
+
|
|
322
|
+
```js
|
|
323
|
+
const gate = createAgentGate({
|
|
324
|
+
agent: 'CheckoutAgent',
|
|
325
|
+
mode: 'enforce',
|
|
326
|
+
persistence: '.agentgate',
|
|
327
|
+
policies: { productionBlock: true }
|
|
328
|
+
});
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Persistent state includes runs and approvals. The control plane also exposes an agent registry:
|
|
332
|
+
|
|
333
|
+
- `GET /api/agents`
|
|
334
|
+
- `POST /api/agents/register` with `{ "name": "CheckoutAgent", "environment": "production" }`
|
|
335
|
+
|
|
336
|
+
The storage layer is an adapter, so a later Postgres/Supabase implementation can replace the local JSON store without changing the security API.
|
|
337
|
+
|
|
338
|
+
## Identity & Authorization
|
|
339
|
+
|
|
340
|
+
AgentGate v1.6 adds deterministic runtime authorization based on agent/user identity, roles, attributes, actions, tools, resources, and environment. Authorization is evaluated before the existing risk/policy engine. Explicit denies win, and configured authorization can use deny-by-default.
|
|
341
|
+
|
|
342
|
+
```js
|
|
343
|
+
const gateway = createMCPGateway({
|
|
344
|
+
policies: {
|
|
345
|
+
authorization: {
|
|
346
|
+
requireIdentity: true,
|
|
347
|
+
rules: [
|
|
348
|
+
{ id: "billing-refunds", effect: "allow", roles: ["billing"], actions: ["refund"] },
|
|
349
|
+
{ id: "deny-production", effect: "deny", resources: ["production/*"] }
|
|
350
|
+
]
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
The authorization result is included in the run audit record so operators can see the identity, matched rule, and reason for an allow/block decision.
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
## Policy Management & Versioning (v1.7)
|
|
361
|
+
|
|
362
|
+
Policies are first-class, versioned artifacts. Versions are immutable after testing/activation and move through:
|
|
363
|
+
|
|
364
|
+
`draft → tested → active → archived`
|
|
365
|
+
|
|
366
|
+
```js
|
|
367
|
+
import { createPolicyRegistry } from 'agentgate-runtime-control/policy-registry';
|
|
368
|
+
|
|
369
|
+
const registry = createPolicyRegistry({ filePath: '.agentgate/policies.json' });
|
|
370
|
+
const v1 = registry.create('payments', {
|
|
371
|
+
autoApproveAmount: 500,
|
|
372
|
+
approvalAmount: 5000,
|
|
373
|
+
blockActions: ['export_all']
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
registry.test('payments', v1.version, [
|
|
377
|
+
{ input: { action: 'export_all' }, expected: 'BLOCK' },
|
|
378
|
+
{ input: { action: 'refund', amount: 200 }, expected: 'ASK' }
|
|
379
|
+
]);
|
|
380
|
+
|
|
381
|
+
registry.activate('payments', v1.version);
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
The registry supports:
|
|
385
|
+
- immutable versions
|
|
386
|
+
- deterministic policy tests
|
|
387
|
+
- diff between versions
|
|
388
|
+
- activation and rollback
|
|
389
|
+
- persistent audit history
|
|
390
|
+
|
|
391
|
+
The Control Plane exposes policy management through `/api/policies`, `/api/policies/create`, `/api/policies/test`, `/api/policies/activate`, `/api/policies/rollback`, `/api/policies/diff`, and `/api/policies/audit`.
|
|
392
|
+
|
|
393
|
+
CLI examples:
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
agentgate policy create payments '{"blockActions":["refund"]}'
|
|
397
|
+
agentgate policy list payments
|
|
398
|
+
agentgate policy test payments 1 '[{"input":{"action":"refund"},"expected":"BLOCK"}]'
|
|
399
|
+
agentgate policy activate payments 1
|
|
400
|
+
agentgate policy diff payments 1 2
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
The active policy is synchronized into the gateway before it evaluates subsequent tool calls.
|
|
404
|
+
|
|
405
|
+
## Identity & Authorization
|
|
406
|
+
|
|
407
|
+
AgentGate supports deterministic RBAC and ABAC authorization using agent/user identity, roles, attributes, resource, action, tool, and environment. Explicit deny and deny-by-default can be enforced before normal risk policy evaluation.
|
|
408
|
+
|
|
409
|
+
## Persistence
|
|
410
|
+
|
|
411
|
+
Runs, approvals, agents, and policy versions can be persisted locally through the built-in storage adapters. For production multi-tenant deployments, use the Postgres/Supabase adapters with tenant-scoped sessions and RLS; local JSON persistence is intended for development or single-process deployments. Storage is provider-neutral so a database adapter can be introduced without changing the policy API.
|
|
412
|
+
|
|
413
|
+
## Multi-Tenant Control Plane (v1.8)
|
|
414
|
+
AgentGate v1.8 adds tenant isolation, scoped API keys, key rotation/revocation, and tenant-scoped webhook registrations.
|
|
415
|
+
|
|
416
|
+
### Tenant CLI
|
|
417
|
+
```bash
|
|
418
|
+
agentgate tenant create Acme
|
|
419
|
+
agentgate tenant list
|
|
420
|
+
agentgate tenant key <tenant-id> runs:read,policies:read
|
|
421
|
+
agentgate tenant rotate <key-id>
|
|
422
|
+
agentgate tenant revoke <key-id>
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### API key security
|
|
426
|
+
- API key secrets are returned only at issuance/rotation and are stored as SHA-256 hashes.
|
|
427
|
+
- Keys support expiry, revocation, rotation, and scoped permissions.
|
|
428
|
+
- Tenant ID is part of the authorization boundary; a valid key for tenant A cannot authorize access to tenant B.
|
|
429
|
+
|
|
430
|
+
### Webhooks
|
|
431
|
+
Webhooks are tenant-scoped and event-filtered. AgentGate records delivery attempts with event, payload, status, and attempt metadata for later delivery workers.
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
## Production Hardening (v2.1)
|
|
435
|
+
- API-key authentication middleware with tenant binding and scope enforcement
|
|
436
|
+
- Real signed webhook delivery with timeout/retry metadata
|
|
437
|
+
- Postgres storage adapter and Supabase adapter hooks
|
|
438
|
+
- Portable Postgres schema with tenant index and RLS enabled
|
|
439
|
+
- Invalid JSON handling and fail-closed protected control-plane routes
|
|
440
|
+
|
|
441
|
+
### HTTP authentication
|
|
442
|
+
Send `Authorization: Bearer <agentgate-key>` or `X-AgentGate-Key: <agentgate-key>`.
|
|
443
|
+
Use `X-AgentGate-Tenant` when explicitly selecting a tenant; mismatches are rejected.
|
|
444
|
+
|
|
445
|
+
For first-tenant bootstrap over HTTP, set `AGENTGATE_BOOTSTRAP_TOKEN` and send `X-AgentGate-Bootstrap` on the first `/api/tenants/create` request. After the first tenant exists, normal API-key authentication applies.
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
## Enterprise Runtime v2.1
|
|
449
|
+
- Multi-tenant runtime control plane
|
|
450
|
+
- Scoped API keys and production authentication
|
|
451
|
+
- Signed webhooks with retries
|
|
452
|
+
- PostgreSQL/Supabase adapters
|
|
453
|
+
- Runtime event bus and real-time event subscriptions
|
|
454
|
+
- Atomic policy bundles with test-before-activate
|
|
455
|
+
- OIDC claim mapping and tenant-bound identity
|
|
456
|
+
- Administrative RBAC for owner/admin/operator/viewer roles
|
|
457
|
+
- Deterministic authorization remains the security authority
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
### Production Operations v2.1
|
|
461
|
+
- `/api/health` and `/api/ready` health/readiness probes
|
|
462
|
+
- `/api/metrics` deterministic runtime counters and latency telemetry
|
|
463
|
+
- `/api/events` Server-Sent Events stream for runtime events
|
|
464
|
+
- Sliding-window HTTP rate limiting with 429 responses
|
|
465
|
+
- OIDC JWT signature, issuer, audience, expiry, and not-before validation for HS256/RS256/ES256
|
|
466
|
+
- Telemetry and event bus are exposed through the SDK
|
|
467
|
+
|
|
468
|
+
## Security hardening in v2.4
|
|
469
|
+
|
|
470
|
+
For authenticated multi-tenant deployments, AgentGate treats the authenticated tenant identity as authoritative. Runtime runs and approvals carry `tenantId` and Control Plane reads, replay, approvals, behavior analysis, blast-radius analysis, webhooks and SSE are tenant-scoped. Request-body or query-string tenant overrides are rejected.
|
|
471
|
+
|
|
472
|
+
The MCP HTTP server is local-only by default. Non-local deployment requires an authentication hook. HTTP request bodies are size-limited. Webhook delivery blocks loopback, private, link-local and metadata targets, resolves DNS before delivery, and rejects redirects.
|
|
473
|
+
|
|
474
|
+
## Response / Data Egress Guard (2.8)
|
|
475
|
+
|
|
476
|
+
Protects the boundary between tools and agents. Enable it on the MCP gateway:
|
|
477
|
+
|
|
478
|
+
```js
|
|
479
|
+
const gateway = createMCPGateway({
|
|
480
|
+
egress: {
|
|
481
|
+
// default: sensitive credentials BLOCK, PII REDACT
|
|
482
|
+
},
|
|
483
|
+
tools: [/* ... */]
|
|
484
|
+
});
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
The guard detects common API keys, private keys, bearer tokens, JWTs, emails, phone numbers, and card-like values. Findings are deterministic and produce `ALLOW`, `REDACT`, or `BLOCK` decisions. Custom rules can change the action for a finding type. Egress decisions are recorded on the run and emitted as `egress.blocked` / `egress.redacted` events.
|
|
488
|
+
|
|
489
|
+
For direct use:
|
|
490
|
+
|
|
491
|
+
```js
|
|
492
|
+
import { createEgressGuard } from 'agentgate-runtime-control';
|
|
493
|
+
const guard = createEgressGuard();
|
|
494
|
+
const result = guard.guard(toolResult);
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
## Response / Data Egress Guard (2.8)
|
|
498
|
+
|
|
499
|
+
Protect the boundary between tools and agents. Enable it on the MCP gateway:
|
|
500
|
+
|
|
501
|
+
```js
|
|
502
|
+
const gateway = createMCPGateway({
|
|
503
|
+
egress: {},
|
|
504
|
+
tools: [/* ... */]
|
|
505
|
+
});
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
The deterministic guard detects common API keys, private keys, bearer tokens, JWTs, email addresses, phone numbers, and card-like values. Findings produce `ALLOW`, `REDACT`, or `BLOCK` decisions. Credentials default to `BLOCK`; common PII defaults to `REDACT`. Rules can be overridden per finding type.
|
|
509
|
+
|
|
510
|
+
```js
|
|
511
|
+
import { createEgressGuard } from 'agentgate-runtime-control';
|
|
512
|
+
const guard = createEgressGuard();
|
|
513
|
+
const result = guard.guard(toolResult);
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
MCP runs record egress decisions and emit `egress.blocked` / `egress.redacted` runtime events.
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
## Preflight and Security Validation
|
|
520
|
+
|
|
521
|
+
Before exposing an agent to real traffic, run:
|
|
522
|
+
|
|
523
|
+
```bash
|
|
524
|
+
agentgate doctor
|
|
525
|
+
agentgate simulate
|
|
526
|
+
agentgate validate-security
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
`doctor` validates configuration and fail-closed deployment assumptions. `simulate` shows the deterministic decision matrix before execution. `validate-security` runs the built-in runtime attack, pre-execution blocking, approval boundary, egress detection, malformed-input resilience and tenant-isolation checks.
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
## Security hardening
|
|
533
|
+
|
|
534
|
+
The default egress guard blocks and redacts generic sensitive fields such as `secret`, `password`, `private_key`, `access_token`, and `authorization`. See `docs/security-hardening-release-report.md` and the external/managed-PostgreSQL test packs.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Reporting a vulnerability
|
|
4
|
+
|
|
5
|
+
Please do not disclose exploitable vulnerabilities in a public issue. Use the project's private security reporting channel once the repository is published, or contact the maintainers directly.
|
|
6
|
+
|
|
7
|
+
Include:
|
|
8
|
+
|
|
9
|
+
- affected version
|
|
10
|
+
- affected component or endpoint
|
|
11
|
+
- reproduction steps
|
|
12
|
+
- security impact
|
|
13
|
+
- suggested mitigation, if known
|
|
14
|
+
|
|
15
|
+
## Security model
|
|
16
|
+
|
|
17
|
+
AgentGate is designed so authorization decisions are deterministic and policy-driven. The model is not the authorization authority. Sensitive actions can be blocked or paused for approval before a tool handler executes.
|
|
18
|
+
|
|
19
|
+
AgentGate is not a security guarantee. Applications remain responsible for identity, secrets, network isolation, tool implementation, data handling, and testing their own threat model.
|