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.
Files changed (75) hide show
  1. package/CHANGELOG.md +229 -0
  2. package/LICENSE +21 -0
  3. package/README.md +534 -0
  4. package/SECURITY.md +19 -0
  5. package/bin/agentgate.js +303 -0
  6. package/docs/case-study-technical-validation.md +25 -0
  7. package/docs/case-study-template.md +37 -0
  8. package/docs/data-protection.md +49 -0
  9. package/docs/design-partner-checklist.md +32 -0
  10. package/docs/design-partner-kit.md +51 -0
  11. package/docs/design-partner-rollout.md +35 -0
  12. package/docs/design-partner.md +67 -0
  13. package/docs/external-security-review-test-pack.md +132 -0
  14. package/docs/external-security-review.md +33 -0
  15. package/docs/incident-response.md +54 -0
  16. package/docs/integration-matrix.md +17 -0
  17. package/docs/managed-postgres-acceptance-test.md +138 -0
  18. package/docs/marketing-plan.md +33 -0
  19. package/docs/observability-alerting.md +44 -0
  20. package/docs/outreach.md +26 -0
  21. package/docs/partner-intake-template.md +26 -0
  22. package/docs/performance-baseline.md +23 -0
  23. package/docs/performance.md +27 -0
  24. package/docs/pricing.md +53 -0
  25. package/docs/production-deployment.md +70 -0
  26. package/docs/production-quickstart.md +58 -0
  27. package/docs/production-readiness.md +29 -0
  28. package/docs/quickstart.md +115 -0
  29. package/docs/release-checklist.md +33 -0
  30. package/docs/security-hardening-release-report.md +69 -0
  31. package/docs/threat-model.md +47 -0
  32. package/docs/website-copy.md +44 -0
  33. package/examples/basic.mjs +14 -0
  34. package/examples/control-plane.mjs +17 -0
  35. package/examples/design-partner-refund.mjs +33 -0
  36. package/examples/design-partner-shadow.mjs +27 -0
  37. package/examples/mcp-gateway.mjs +26 -0
  38. package/examples/policy-bundle.mjs +18 -0
  39. package/examples/refund-agent.mjs +20 -0
  40. package/examples/runtime.mjs +12 -0
  41. package/package.json +49 -0
  42. package/schema/postgres.sql +17 -0
  43. package/src/admin-rbac.js +3 -0
  44. package/src/agentgate.js +85 -0
  45. package/src/approval.js +30 -0
  46. package/src/attack-lab.js +94 -0
  47. package/src/auth.js +27 -0
  48. package/src/behavior.js +146 -0
  49. package/src/control-plane.js +215 -0
  50. package/src/egress-guard.js +132 -0
  51. package/src/event-bus.js +10 -0
  52. package/src/identity.js +109 -0
  53. package/src/index.js +44 -0
  54. package/src/local-experience.js +46 -0
  55. package/src/mcp-gateway.js +383 -0
  56. package/src/mcp-scanner.js +45 -0
  57. package/src/middleware.js +17 -0
  58. package/src/multi-tenant.js +29 -0
  59. package/src/observability.js +395 -0
  60. package/src/oidc.js +38 -0
  61. package/src/persistent-store.js +56 -0
  62. package/src/policy-builder.js +74 -0
  63. package/src/policy-bundles.js +17 -0
  64. package/src/policy-engine.js +67 -0
  65. package/src/policy-packs.js +115 -0
  66. package/src/policy-registry.js +58 -0
  67. package/src/postgres-adapter.js +76 -0
  68. package/src/runtime.js +138 -0
  69. package/src/saas.js +67 -0
  70. package/src/security-report.js +42 -0
  71. package/src/security-validation.js +92 -0
  72. package/src/shadow-mode.js +47 -0
  73. package/src/telemetry.js +28 -0
  74. package/src/webhook-delivery.js +70 -0
  75. package/standalone.html +86 -0
@@ -0,0 +1,58 @@
1
+ # Production Quickstart: PostgreSQL
2
+
3
+ This is a reference deployment for a pilot. Put a TLS reverse proxy in front of AgentGate in any non-local deployment.
4
+
5
+ ## 1. Set the database secret
6
+
7
+ ```bash
8
+ export POSTGRES_PASSWORD='use-a-long-random-secret'
9
+ ```
10
+
11
+ ## 2. Start PostgreSQL and AgentGate
12
+
13
+ ```bash
14
+ docker compose -f docker-compose.production.yml up -d --build
15
+ ```
16
+
17
+ ## 3. Verify readiness
18
+
19
+ ```bash
20
+ curl -fsS http://127.0.0.1:8787/api/health
21
+ curl -fsS http://127.0.0.1:8787/api/ready
22
+ ```
23
+
24
+ ## 4. Verify the database schema
25
+
26
+ The compose file mounts `schema/postgres.sql` as an initialization script. For an existing database, apply the schema through your normal migration/change-management process instead of relying on container initialization.
27
+
28
+ The schema must have:
29
+
30
+ - `agentgate_records`
31
+ - `(tenant_id, kind)` index
32
+ - RLS enabled
33
+ - tenant-scoped `USING` and `WITH CHECK` policy
34
+
35
+ ## 5. Production hardening
36
+
37
+ - Replace the sample password with a secret-manager value.
38
+ - Put the Control Plane behind HTTPS/OIDC or another production authentication boundary.
39
+ - Do not publish PostgreSQL directly to the Internet.
40
+ - Configure automated backups and test restore into an isolated database.
41
+ - Configure monitoring for `/api/health`, `/api/ready`, error rate, latency and database connectivity.
42
+ - Keep the exact image/package version and database schema version together for rollback decisions.
43
+
44
+ ## 6. Backup/restore acceptance test
45
+
46
+ Record:
47
+
48
+ ```text
49
+ backup timestamp:
50
+ backup identifier:
51
+ restore target:
52
+ restore duration:
53
+ RPO:
54
+ RTO:
55
+ replay verification:
56
+ approval verification:
57
+ tenant-isolation verification:
58
+ ```
@@ -0,0 +1,29 @@
1
+ # Production Readiness Status — 2.13.8
2
+
3
+ ## Completed in the release
4
+
5
+ - Runtime/SDK enforcement and approval lifecycle.
6
+ - Live `agentgate dev` Attack Lab with 5/5 demo tools.
7
+ - Explicit SKIPPED handling for missing tools in real gateways.
8
+ - Control Plane policy lifecycle and audit export.
9
+ - Browser syntax/release smoke coverage.
10
+ - Tenant isolation, egress controls, malformed-input handling and approval race tests.
11
+ - 139/139 automated tests passing.
12
+ - Reproducible performance benchmark and recorded baseline.
13
+ - PostgreSQL/Supabase deployment reference and RLS schema checks.
14
+ - Docker Compose production pilot reference.
15
+ - Retention, encryption, backup/restore and deletion guidance.
16
+ - Incident-response runbook.
17
+ - Threat model and integration matrix.
18
+ - Release consistency and npm artifact checks.
19
+
20
+ ## Environment-dependent gates
21
+
22
+ These cannot be truthfully marked complete inside the source archive alone:
23
+
24
+ 1. **Backup/restore execution:** run against the customer's real PostgreSQL/Supabase environment and record RPO/RTO.
25
+ 2. **Production monitoring/alerting:** connect the documented metrics and health probes to the customer's monitoring system.
26
+ 3. **Customer-specific integration validation:** run the actual agent/framework/tool stack.
27
+ 4. **External security review:** an independent reviewer must perform and sign off on the agreed scope.
28
+
29
+ The release intentionally does not claim any of these have been completed.
@@ -0,0 +1,115 @@
1
+ # AgentGate Quickstart
2
+
3
+
4
+ ## 0. Start with a policy pack
5
+
6
+ For the fastest first protection, use the Support Refund Safety Pack:
7
+
8
+ ```bash
9
+ npx agentgate pack list
10
+ npx agentgate pack init support-refund-safety
11
+ npx agentgate simulate
12
+ npx agentgate attack
13
+ ```
14
+
15
+ The generated config starts in `enforce` mode. For a focused Shadow/Observe demonstration, explicitly change `mode` to `observe` and do not use that configuration for sensitive production tools:
16
+
17
+ ```bash
18
+ npx agentgate demo refund
19
+ ```
20
+
21
+ See [`docs/design-partner.md`](design-partner.md) for the observe → enforce rollout and acceptance criteria.
22
+
23
+ AgentGate is a runtime control plane for AI agent tool execution. Put it between your agent and side-effecting tools so every action gets a deterministic `ALLOW`, `ASK`, or `BLOCK` decision.
24
+
25
+ ## 1. Install
26
+
27
+ ```bash
28
+ npm install agentgate-runtime-control
29
+ ```
30
+
31
+ ## 2. Protect a tool
32
+
33
+ ```js
34
+ import { protect } from 'agentgate-runtime-control';
35
+
36
+ const refund = protect(
37
+ async ({ amount, customerId }) => ({ refunded: amount, customerId }),
38
+ {
39
+ approvalActions: ['refund'],
40
+ autoApproveAmount: 500,
41
+ approvalAmount: 5000
42
+ }
43
+ );
44
+
45
+ await refund({ amount: 250, customerId: 'cus_123' });
46
+ // status: executed
47
+
48
+ await refund({ amount: 1200, customerId: 'cus_123' });
49
+ // status: approval_required
50
+
51
+ // amount 9000 is BLOCKED because it exceeds approvalAmount
52
+ ```
53
+
54
+ ## 3. Run the attack lab
55
+
56
+ ```bash
57
+ npx agentgate attack
58
+ ```
59
+
60
+ The lab exercises representative destructive, export, escalation, and high-value actions through the same gateway path used at runtime.
61
+
62
+ ## 4. Start the local control plane
63
+
64
+ ```bash
65
+ npx agentgate dev
66
+ ```
67
+
68
+ Then open `http://localhost:8787`. Local development creates a short-lived browser session automatically; production authentication remains required.
69
+
70
+ The dashboard starts with seeded ALLOW / ASK / BLOCK demo runs so you can verify the control plane before connecting your own agent.
71
+
72
+ Useful endpoints include:
73
+
74
+ - `/api/health` — process health
75
+ - `/api/ready` — readiness state
76
+ - `/api/metrics` — runtime telemetry
77
+ - `/api/runs` — replayable runs
78
+ - `/api/approvals` — pending approvals
79
+ - `/api/behavior` — behavior signals
80
+ - `/api/blast-radius` — blast-radius analysis
81
+
82
+ ## 5. Start from the CLI
83
+
84
+ ```bash
85
+ npx agentgate init
86
+ ```
87
+
88
+ This creates `agentgate.config.mjs` with a conservative production policy baseline.
89
+
90
+ ## 6. Recommended rollout
91
+
92
+ 1. Start in `observe` mode.
93
+ 2. Run your normal agent traffic.
94
+ 3. Run `agentgate attack` and your own abuse cases.
95
+ 4. Review replay IDs, behavior signals, and generated reports.
96
+ 5. Activate reviewed policies.
97
+ 6. Switch to `enforce` mode for production side effects.
98
+ 7. Keep approvals and audit events connected to your operational workflow.
99
+
100
+ AgentGate is a control layer, not a guarantee that an agent is safe. Test the actions and tools that matter to your application.
101
+
102
+
103
+ ## Approval lifecycle for `createAgentGate`
104
+
105
+ When a protected SDK tool returns `approval_required`, the returned `approvalId` is resolved through the same gate:
106
+
107
+ ```js
108
+ const result = await refund({ amount: 900 });
109
+ if (result.status === 'approval_required') {
110
+ const approved = await gate.approve(result.approvalId);
111
+ // or: await gate.deny(result.approvalId, 'Not authorized');
112
+ }
113
+ ```
114
+
115
+ You can inspect pending requests with `gate.approvals()` and retrieve one with `gate.getApproval(approvalId)`. The approval API executes the original protected tool only after explicit approval.
@@ -0,0 +1,33 @@
1
+ # Production Release Checklist
2
+
3
+ ## Automated gate
4
+
5
+ - [ ] `npm test` is green.
6
+ - [ ] `node scripts/release-check.mjs` is green.
7
+ - [ ] `npm pack --dry-run` contains no tests, internal tarballs, or stale versions.
8
+ - [ ] `node --check` passes for extracted standalone JavaScript.
9
+ - [ ] release browser smoke passes.
10
+ - [ ] `agentgate dev` Live Attack Lab returns 5/5 protected in its demo environment.
11
+ - [ ] clean consumer install from the generated npm tarball passes.
12
+ - [ ] approval race test confirms exactly one execution.
13
+ - [ ] tenant isolation test passes.
14
+ - [ ] egress test passes.
15
+
16
+ ## Operational gate
17
+
18
+ - [ ] Production PostgreSQL/Supabase is configured with RLS.
19
+ - [ ] TLS is enabled.
20
+ - [ ] Backup and restore have been exercised.
21
+ - [ ] Retention period is documented by the deployment owner.
22
+ - [ ] RPO/RTO are documented by the deployment owner.
23
+ - [ ] Incident-response contacts/runbook are configured.
24
+ - [ ] Monitoring and alerting are configured.
25
+ - [ ] Application-specific abuse cases are recorded.
26
+
27
+ ## Assurance gate
28
+
29
+ - [ ] Threat model reviewed.
30
+ - [ ] Dependency/supply-chain review completed.
31
+ - [ ] External security review completed, if required by the customer/plan.
32
+
33
+ An unchecked external-review item must never be described as completed or certified.
@@ -0,0 +1,69 @@
1
+ # AgentGate v2.13.8 — Security Hardening Release Report
2
+
3
+ ## Changes closed from the v2.13.7 verification report
4
+
5
+ ### 1. Generic secret detection
6
+
7
+ Added default field-aware egress protection for:
8
+
9
+ - `secret`
10
+ - `password`
11
+ - `passphrase`
12
+ - `private_key`
13
+ - `access_token`
14
+ - `refresh_token`
15
+ - `authorization`
16
+ - `auth_token`
17
+ - `client_secret`
18
+ - `api_secret`
19
+
20
+ Sensitive values are redacted as `[REDACTED:SECRET]` and the egress decision is `BLOCK` by default.
21
+
22
+ Regression coverage includes nested objects, arrays, inspection, and existing MCP egress behavior.
23
+
24
+ ### 2. Enforcement configuration
25
+
26
+ The shipped `agentgate.config.mjs` now uses `mode: 'enforce'` so the packaged runtime example does not accidentally present Observe as an enforcement configuration.
27
+
28
+ Observe remains supported for explicit shadow/testing workflows.
29
+
30
+ ### 3. PostgreSQL reference hardening
31
+
32
+ The reference schema now uses both:
33
+
34
+ ```sql
35
+ ALTER TABLE agentgate_records ENABLE ROW LEVEL SECURITY;
36
+ ALTER TABLE agentgate_records FORCE ROW LEVEL SECURITY;
37
+ ```
38
+
39
+ The managed production acceptance procedure remains separate because it requires a real managed PostgreSQL environment.
40
+
41
+ ### 4. External security review
42
+
43
+ No external audit is claimed. The release contains a reviewer-ready test pack covering authentication, authorization, tenant isolation, runtime enforcement, approval races, egress, malformed input, MCP boundaries, replay/audit integrity, persistence, and abuse controls.
44
+
45
+ ### 5. Managed PostgreSQL production acceptance
46
+
47
+ The release contains a provider-neutral acceptance test covering RLS, tenant isolation, backup/restore, application-role privileges, TLS, RPO/RTO, and restore verification.
48
+
49
+ ## Release verification executed in this environment
50
+
51
+ - `npm test` — 144/144 PASS.
52
+ - `node bin/agentgate.js --version` — 2.13.8.
53
+ - `node bin/agentgate.js doctor` — OK, enforce mode, no warnings.
54
+ - `node bin/agentgate.js validate-security` — OK.
55
+ - `node bin/agentgate.js attack-ci` — 5/5 PROTECTED.
56
+ - `node --test test/release-browser-smoke.mjs` — PASS.
57
+ - `npm run benchmark` — PASS, environment-specific baseline.
58
+ - `npm run release:check` — PASS.
59
+ - `npm audit --omit=dev` — 0 vulnerabilities reported.
60
+
61
+ ## Remaining evidence gates
62
+
63
+ These cannot honestly be marked complete by an internal local build:
64
+
65
+ 1. Independent external security review — requires an independent reviewer and dated report.
66
+ 2. Managed PostgreSQL production acceptance — requires the target managed PostgreSQL environment and its backup/restore evidence.
67
+ 3. Production SLA/capacity — requires HTTP + managed DB + network testing in the target deployment environment.
68
+
69
+ The release therefore closes the code-level finding and packages the remaining independent/production evidence tests without falsely claiming those external validations.
@@ -0,0 +1,47 @@
1
+ # AgentGate Threat Model
2
+
3
+ ## Assets
4
+
5
+ - Tool execution authority.
6
+ - Approval decisions.
7
+ - Run/replay evidence.
8
+ - Tenant-scoped audit data.
9
+ - Policy definitions and versions.
10
+ - Credentials used by the protected application.
11
+
12
+ ## Trust boundaries
13
+
14
+ ```text
15
+ Untrusted model/agent
16
+ |
17
+ v
18
+ AgentGate runtime boundary
19
+ |
20
+ +--> policy engine
21
+ +--> approval boundary
22
+ +--> egress guard
23
+ +--> audit/persistence
24
+ |
25
+ v
26
+ Side-effecting tool / MCP / API
27
+ ```
28
+
29
+ ## Threats and controls
30
+
31
+ | Threat | Primary control | Evidence |
32
+ |---|---|---|
33
+ | Prompt injection causes dangerous tool call | Deterministic tool/action policy | Attack Lab |
34
+ | High-value action bypasses approval | ASK before handler execution | Approval tests |
35
+ | Double approval causes duplicate side effect | Single-resolution approval state | Approval race test |
36
+ | Destructive tool executes | BLOCK before handler | Security validation / Attack Lab |
37
+ | Cross-tenant replay/read | Tenant-scoped API and persistence | Tenant tests + RLS schema |
38
+ | Secret/PII leaves tool boundary | Egress inspection | Egress tests |
39
+ | Policy drift | Versioned policy registry/test/activate | Policy lifecycle tests |
40
+ | Audit loss during rollback | Export + durable store + backup procedure | Operations runbook |
41
+ | Credential theft outside AgentGate | Application/IAM/secret-manager controls | Out of scope |
42
+ | Compromised host/kernel | Infrastructure security | Out of scope |
43
+ | Unsafe model output without tool call | Model/provider safety controls | Out of scope |
44
+
45
+ ## Security boundary
46
+
47
+ AgentGate is an execution-control layer. It is not an IAM replacement, secret manager, network firewall, model safety guarantee, or host security boundary.
@@ -0,0 +1,44 @@
1
+ # AgentGate Website Copy — Launch Draft
2
+
3
+ ## Hero
4
+ **Control what your AI agents can actually do.**
5
+
6
+ AgentGate is the runtime control plane for AI agent actions. Stop dangerous tool calls before they execute, require approval for sensitive actions, and keep replayable evidence of every decision.
7
+
8
+ **CTA:** Start with the SDK
9
+ **Secondary CTA:** Run the Attack Lab
10
+
11
+ ## Proof strip
12
+ `ALLOW` · `ASK` · `BLOCK` · Approval boundaries · Egress protection · Tenant isolation · Replay
13
+
14
+ ## How it works
15
+ **Install → Observe → Attack → Enforce → Replay**
16
+
17
+ AgentGate sits between your agent and its tools. The model can request an action; AgentGate makes the deterministic runtime decision.
18
+
19
+ ## Why AgentGate
20
+ ### Prevent side effects
21
+ A BLOCK decision happens before the protected handler executes.
22
+
23
+ ### Make approvals real
24
+ Sensitive actions can pause for human approval. No pre-approval handler execution.
25
+
26
+ ### Prove what happened
27
+ Every important decision can carry a winning rule, rule trace, execution outcome, and Replay evidence.
28
+
29
+ ### Start without production risk
30
+ Use sandbox, replay traffic, and Shadow Mode before enforcing a sensitive tool.
31
+
32
+ ## Use cases
33
+ - Support and financial operations: refunds, cancellations, customer changes.
34
+ - DevOps and IT: deployments, production changes, destructive operations.
35
+ - Data and CRM: exports, bulk updates, cross-tenant access.
36
+
37
+ ## Security boundary
38
+ AgentGate is a runtime control layer. It does not replace application authorization, IAM, secret management, network isolation, provider controls, or threat modeling.
39
+
40
+ ## CTA
41
+ **Give one agent one sensitive tool. See what AgentGate would allow, ask, and block.**
42
+
43
+ Install:
44
+ `npm install agentgate-runtime-control`
@@ -0,0 +1,14 @@
1
+ import { protect } from 'agentgate-runtime-control';
2
+
3
+ const refund = protect(
4
+ async ({ amount, customerId }) => ({ refunded: amount, customerId }),
5
+ { autoApproveAmount: 500, approvalAmount: 5000, requireApprovalForDestructive: false }
6
+ );
7
+
8
+ console.log(await refund({ amount: 250, customerId: 'cus_123' })); // executed
9
+ console.log(await refund({ amount: 1200, customerId: 'cus_123' })); // approval_required
10
+ try {
11
+ await refund({ amount: 9000, customerId: 'cus_123' });
12
+ } catch (error) {
13
+ console.log({ status: 'blocked', decision: error.agentgate.decision, reason: error.agentgate.reason });
14
+ }
@@ -0,0 +1,17 @@
1
+ import fs from 'node:fs/promises';
2
+ import { createControlPlane } from '../src/control-plane.js';
3
+ import { createMCPGateway } from '../src/mcp-gateway.js';
4
+
5
+ const html = await fs.readFile(new URL('../standalone.html', import.meta.url), 'utf8');
6
+ const gateway = createMCPGateway({
7
+ mode: 'enforce',
8
+ policies: { productionBlock: true },
9
+ tools: [
10
+ { name: 'read', handler: async (args) => ({ ok: true, data: args }) },
11
+ { name: 'refund', handler: async (args) => ({ refunded: args.amount }) },
12
+ { name: 'delete', handler: async (args) => ({ deleted: args.id }) }
13
+ ]
14
+ });
15
+ const { server } = createControlPlane({ gateway, html });
16
+ const port = Number(process.env.PORT || 8787);
17
+ server.listen(port, () => console.log(`AgentGate Control Plane: http://localhost:${port}`));
@@ -0,0 +1,33 @@
1
+ import { createAgentGate, getPolicyPack } from 'agentgate-runtime-control';
2
+
3
+ const pack = getPolicyPack('support-refund-safety');
4
+ const gate = createAgentGate({
5
+ agent: 'SupportAgent',
6
+ mode: 'observe',
7
+ policies: pack.policies
8
+ });
9
+
10
+ let executions = 0;
11
+ const refund = gate.protect(
12
+ async ({ amount, customerId }) => {
13
+ executions += 1;
14
+ return { refunded: amount, customerId };
15
+ },
16
+ { tool: 'refund', action: 'refund' }
17
+ );
18
+
19
+ for (const amount of [250, 1200, 5000.01]) {
20
+ const result = await refund(
21
+ { amount, customerId: 'sandbox_customer' },
22
+ { amount, environment: 'production' }
23
+ );
24
+ console.log({
25
+ amount,
26
+ proposedDecision: result.agentgate.decision,
27
+ winningRule: result.agentgate.winningRule,
28
+ simulated: result.agentgate.simulated,
29
+ handlerExecuted: result.status === 'executed'
30
+ });
31
+ }
32
+
33
+ console.log({ mode: gate.mode, executions, note: 'Observe mode records proposed decisions and intentionally does not enforce them.' });
@@ -0,0 +1,27 @@
1
+ import { createAgentGate, getPolicyPack, recordShadowEvent, analyzeShadowEvents } from 'agentgate-runtime-control';
2
+
3
+ const pack = getPolicyPack('support-refund-safety');
4
+ const gate = createAgentGate({ agent: 'SupportAgent', mode: 'observe', policies: pack.policies });
5
+ const events = [];
6
+
7
+ async function refundTool({ amount, customerId }) {
8
+ return { refunded: amount, customerId };
9
+ }
10
+
11
+ const refund = gate.protect(refundTool, { tool: 'refund', action: 'refund' });
12
+
13
+ for (const amount of [250, 1200, 5000.01]) {
14
+ const result = await refund({ amount, customerId: 'sandbox_customer' }, { amount });
15
+ events.push(recordShadowEvent({
16
+ runId: result.agentgate.id,
17
+ decision: result.agentgate.decision,
18
+ executed: result.status === 'executed',
19
+ request: result.agentgate.request
20
+ }));
21
+ }
22
+
23
+ console.log(JSON.stringify({
24
+ mode: gate.mode,
25
+ shadow: analyzeShadowEvents(events),
26
+ events
27
+ }, null, 2));
@@ -0,0 +1,26 @@
1
+ import { createMCPGatewayServer } from '../src/mcp-gateway.js';
2
+
3
+ const { server } = createMCPGatewayServer({
4
+ mode: 'enforce',
5
+ policies: {
6
+ approvalActions: ['refund'],
7
+ blockActions: ['export_all']
8
+ },
9
+ tools: [
10
+ {
11
+ name: 'read_customer',
12
+ description: 'Read a customer record',
13
+ inputSchema: { type: 'object', properties: { customerId: { type: 'string' } } },
14
+ handler: async ({ customerId }) => ({ customerId, name: 'Demo Customer' })
15
+ },
16
+ {
17
+ name: 'refund',
18
+ description: 'Issue a refund',
19
+ inputSchema: { type: 'object', properties: { amount: { type: 'number' } } },
20
+ handler: async ({ amount }) => ({ refunded: amount })
21
+ }
22
+ ]
23
+ });
24
+
25
+ const port = Number(process.env.PORT || 8787);
26
+ server.listen(port, () => console.log(`AgentGate MCP Gateway listening on http://localhost:${port}/mcp`));
@@ -0,0 +1,18 @@
1
+ import { createPolicyBundleRegistry } from 'agentgate-runtime-control';
2
+
3
+ const registry = createPolicyBundleRegistry({ filePath: '.agentgate/policy-bundles.json' });
4
+
5
+ const bundle = registry.create('support-production', {
6
+ productionBlock: true,
7
+ approvalActions: ['refund', 'delete'],
8
+ autoApproveAmount: 500,
9
+ approvalAmount: 5000
10
+ });
11
+
12
+ registry.test('support-production', bundle.version, [
13
+ { input: { action: 'read', environment: 'production' }, expected: 'ALLOW' },
14
+ { input: { action: 'refund', amount: 1200, environment: 'staging' }, expected: 'ASK' },
15
+ { input: { action: 'delete', environment: 'production' }, expected: 'BLOCK' }
16
+ ]);
17
+
18
+ console.log(registry.activate('support-production', bundle.version));
@@ -0,0 +1,20 @@
1
+ import { createAgentGate } from 'agentgate-runtime-control';
2
+
3
+ const gate = createAgentGate({
4
+ agent: 'SupportAgent',
5
+ mode: 'enforce',
6
+ policies: { productionBlock: true, autoApproveAmount: 500, approvalAmount: 5000 }
7
+ });
8
+
9
+ const refund = gate.protect(
10
+ async ({ amount, customerId }) => ({ refunded: amount, customerId }),
11
+ { tool: 'refund', action: 'refund' }
12
+ );
13
+
14
+ for (const amount of [250, 1200]) {
15
+ try {
16
+ console.log(await refund({ amount, customerId: 'cus_123' }));
17
+ } catch (error) {
18
+ console.log({ status: 'blocked', code: error.code, decision: error.agentgate?.decision, reason: error.agentgate?.reason });
19
+ }
20
+ }
@@ -0,0 +1,12 @@
1
+ import { createRuntime, runAttackLab } from 'agentgate-runtime-control';
2
+
3
+ const gate = createRuntime({ mode: 'enforce', policies: { productionBlock: true, approvalAmount: 5000, autoApproveAmount: 500 } });
4
+ const charge = async ({ amount }) => ({ charged: amount });
5
+
6
+ try {
7
+ console.log(await gate.execute(charge, { action: 'refund', amount: 120 }));
8
+ } catch (error) {
9
+ console.log({ status: 'blocked', code: error.code, decision: error.agentgate?.decision, reason: error.agentgate?.reason });
10
+ }
11
+ console.log(gate.runs());
12
+ console.table(runAttackLab({ productionBlock: true }));
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "agentgate-runtime-control",
3
+ "version": "2.13.8",
4
+ "type": "module",
5
+ "description": "Runtime control plane and SaaS governance layer for AI agent tool execution",
6
+ "exports": {
7
+ ".": "./src/index.js",
8
+ "./policy-engine": "./src/policy-engine.js",
9
+ "./mcp-gateway": "./src/mcp-gateway.js",
10
+ "./policy-builder": "./src/policy-builder.js",
11
+ "./control-plane": "./src/control-plane.js",
12
+ "./agentgate": "./src/agentgate.js",
13
+ "./security-report": "./src/security-report.js",
14
+ "./behavior": "./src/behavior.js",
15
+ "./identity": "./src/identity.js",
16
+ "./policy-registry": "./src/policy-registry.js",
17
+ "./multi-tenant": "./src/multi-tenant.js",
18
+ "./telemetry": "./src/telemetry.js",
19
+ "./oidc": "./src/oidc.js",
20
+ "./saas": "./src/saas.js",
21
+ "./mcp-scanner": "./src/mcp-scanner.js",
22
+ "./egress-guard": "./src/egress-guard.js",
23
+ "./observability": "./src/observability.js"
24
+ },
25
+ "bin": {
26
+ "agentgate": "./bin/agentgate.js"
27
+ },
28
+ "scripts": {
29
+ "test": "node --test",
30
+ "prepublishOnly": "npm test",
31
+ "benchmark": "node scripts/performance-benchmark.mjs",
32
+ "release:check": "node scripts/release-check.mjs"
33
+ },
34
+ "engines": {
35
+ "node": ">=18"
36
+ },
37
+ "files": [
38
+ "src",
39
+ "bin",
40
+ "examples",
41
+ "schema",
42
+ "docs",
43
+ "standalone.html",
44
+ "README.md",
45
+ "LICENSE",
46
+ "SECURITY.md",
47
+ "CHANGELOG.md"
48
+ ]
49
+ }
@@ -0,0 +1,17 @@
1
+ -- AgentGate production Postgres schema
2
+ -- Runtime database sessions should set: select set_config('agentgate.tenant_id', '<tenant>', true);
3
+ create table if not exists agentgate_records (
4
+ id text primary key,
5
+ tenant_id text not null,
6
+ kind text not null,
7
+ data jsonb not null,
8
+ version integer not null default 1,
9
+ created_at timestamptz not null default now()
10
+ );
11
+ create index if not exists agentgate_records_tenant_kind_idx on agentgate_records (tenant_id, kind);
12
+ alter table agentgate_records enable row level security;
13
+ alter table agentgate_records force row level security;
14
+ drop policy if exists agentgate_tenant_isolation on agentgate_records;
15
+ create policy agentgate_tenant_isolation on agentgate_records
16
+ using (tenant_id = current_setting('agentgate.tenant_id', true))
17
+ with check (tenant_id = current_setting('agentgate.tenant_id', true));
@@ -0,0 +1,3 @@
1
+ export const ADMIN_ROLES=Object.freeze({OWNER:['*'],ADMIN:['tenant:read','tenant:write','keys:read','keys:write','policies:read','policies:write','webhooks:read','webhooks:write','runs:read','approvals:resolve'],OPERATOR:['runs:read','approvals:resolve','policies:read'],VIEWER:['runs:read','policies:read']});
2
+ export function adminAuthorize(identity, permission){ const roles=Array.isArray(identity?.roles)?identity.roles:[]; return roles.some(role=>ADMIN_ROLES[role]?.includes('*')||ADMIN_ROLES[role]?.includes(permission)); }
3
+ export function requireAdmin(identity,permission){ if(!adminAuthorize(identity,permission)){const e=new Error('Admin permission denied');e.code='AGENTGATE_ADMIN_FORBIDDEN';throw e;} return true; }