@sentinel-atl/trust-gateway 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/README.md +134 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +153 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +95 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +110 -0
- package/dist/config.js.map +1 -0
- package/dist/gateway.d.ts +63 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +245 -0
- package/dist/gateway.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/proxy.d.ts +68 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/proxy.js +399 -0
- package/dist/proxy.js.map +1 -0
- package/dist/trust-store.d.ts +51 -0
- package/dist/trust-store.d.ts.map +1 -0
- package/dist/trust-store.js +95 -0
- package/dist/trust-store.js.map +1 -0
- package/package.json +59 -0
package/dist/gateway.js
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust Gateway — runtime MCP request enforcement using YAML policies and STCs.
|
|
3
|
+
*
|
|
4
|
+
* For every incoming tool call, the gateway:
|
|
5
|
+
* 1. Identifies which server policy applies
|
|
6
|
+
* 2. Checks the server's STC trust score against the policy
|
|
7
|
+
* 3. Enforces tool allow/block lists
|
|
8
|
+
* 4. Applies rate limiting
|
|
9
|
+
* 5. Logs the decision to the audit trail
|
|
10
|
+
*/
|
|
11
|
+
import { AuditLog } from '@sentinel-atl/audit';
|
|
12
|
+
import { TrustStore } from './trust-store.js';
|
|
13
|
+
// ─── Rate Limiter ────────────────────────────────────────────────────
|
|
14
|
+
class RateLimiter {
|
|
15
|
+
maxRequests;
|
|
16
|
+
windowMs;
|
|
17
|
+
windows = new Map();
|
|
18
|
+
constructor(maxRequests, windowMs) {
|
|
19
|
+
this.maxRequests = maxRequests;
|
|
20
|
+
this.windowMs = windowMs;
|
|
21
|
+
}
|
|
22
|
+
check(key) {
|
|
23
|
+
const now = Date.now();
|
|
24
|
+
const entry = this.windows.get(key);
|
|
25
|
+
if (!entry || now >= entry.resetAt) {
|
|
26
|
+
this.windows.set(key, { count: 1, resetAt: now + this.windowMs });
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
if (entry.count >= this.maxRequests)
|
|
30
|
+
return false;
|
|
31
|
+
entry.count++;
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function parseRateLimit(spec) {
|
|
36
|
+
const match = spec.match(/^(\d+)\/(min|hour|day)$/);
|
|
37
|
+
if (!match)
|
|
38
|
+
return { max: 100, windowMs: 60_000 };
|
|
39
|
+
const max = parseInt(match[1]);
|
|
40
|
+
const windowMs = match[2] === 'min' ? 60_000
|
|
41
|
+
: match[2] === 'hour' ? 3_600_000
|
|
42
|
+
: 86_400_000;
|
|
43
|
+
return { max, windowMs };
|
|
44
|
+
}
|
|
45
|
+
// ─── Grade Comparison ────────────────────────────────────────────────
|
|
46
|
+
const GRADE_ORDER = { A: 4, B: 3, C: 2, D: 1, F: 0 };
|
|
47
|
+
function gradeAtLeast(actual, required) {
|
|
48
|
+
return (GRADE_ORDER[actual] ?? 0) >= (GRADE_ORDER[required] ?? 0);
|
|
49
|
+
}
|
|
50
|
+
// ─── Gateway ─────────────────────────────────────────────────────────
|
|
51
|
+
export class TrustGateway {
|
|
52
|
+
config;
|
|
53
|
+
trustStore;
|
|
54
|
+
auditLog;
|
|
55
|
+
rateLimiters = new Map();
|
|
56
|
+
stats = {
|
|
57
|
+
totalRequests: 0,
|
|
58
|
+
allowed: 0,
|
|
59
|
+
denied: 0,
|
|
60
|
+
warned: 0,
|
|
61
|
+
};
|
|
62
|
+
constructor(config, trustStore, auditLog) {
|
|
63
|
+
this.config = config;
|
|
64
|
+
this.trustStore = trustStore ?? new TrustStore();
|
|
65
|
+
this.auditLog = auditLog ?? new AuditLog({
|
|
66
|
+
logPath: config.gateway.logPath ?? './sentinel-gateway-audit.jsonl',
|
|
67
|
+
});
|
|
68
|
+
// Initialize rate limiters for each server
|
|
69
|
+
for (const server of config.servers) {
|
|
70
|
+
if (server.rateLimit) {
|
|
71
|
+
const { max, windowMs } = parseRateLimit(server.rateLimit);
|
|
72
|
+
this.rateLimiters.set(server.name, new RateLimiter(max, windowMs));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get the trust store for loading certificates.
|
|
78
|
+
*/
|
|
79
|
+
getTrustStore() {
|
|
80
|
+
return this.trustStore;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Process a tool call request through the trust pipeline.
|
|
84
|
+
*/
|
|
85
|
+
async processRequest(request) {
|
|
86
|
+
const start = performance.now();
|
|
87
|
+
this.stats.totalRequests++;
|
|
88
|
+
// Find the server policy
|
|
89
|
+
const policy = this.config.servers.find(s => s.name === request.serverName);
|
|
90
|
+
if (!policy) {
|
|
91
|
+
this.stats.denied++;
|
|
92
|
+
return this.makeResponse(request, 'deny-unknown-server', `Server "${request.serverName}" is not configured`, start);
|
|
93
|
+
}
|
|
94
|
+
// Rate limit check
|
|
95
|
+
const limiter = this.rateLimiters.get(request.serverName);
|
|
96
|
+
if (limiter && !limiter.check(`${request.callerId}:${request.serverName}`)) {
|
|
97
|
+
this.stats.denied++;
|
|
98
|
+
return this.makeResponse(request, 'deny-rate-limit', 'Rate limit exceeded', start);
|
|
99
|
+
}
|
|
100
|
+
// Tool allow/block list check
|
|
101
|
+
if (policy.blockedTools?.includes(request.toolName)) {
|
|
102
|
+
this.stats.denied++;
|
|
103
|
+
return this.makeResponse(request, 'deny-blocked-tool', `Tool "${request.toolName}" is blocked for server "${request.serverName}"`, start);
|
|
104
|
+
}
|
|
105
|
+
if (policy.allowedTools && !policy.allowedTools.includes(request.toolName)) {
|
|
106
|
+
this.stats.denied++;
|
|
107
|
+
return this.makeResponse(request, 'deny-not-allowed', `Tool "${request.toolName}" is not in the allowed list for server "${request.serverName}"`, start);
|
|
108
|
+
}
|
|
109
|
+
// Trust verification
|
|
110
|
+
const trustResult = this.checkTrust(request.serverName, policy);
|
|
111
|
+
if (trustResult.decision !== 'allow') {
|
|
112
|
+
if (this.config.gateway.mode === 'permissive') {
|
|
113
|
+
// Permissive mode: warn but allow
|
|
114
|
+
this.stats.warned++;
|
|
115
|
+
await this.audit(request, 'warn', trustResult.reason);
|
|
116
|
+
return {
|
|
117
|
+
allowed: true,
|
|
118
|
+
decision: 'warn',
|
|
119
|
+
reason: `[WARN] ${trustResult.reason}`,
|
|
120
|
+
serverName: request.serverName,
|
|
121
|
+
toolName: request.toolName,
|
|
122
|
+
trustScore: trustResult.trustScore,
|
|
123
|
+
grade: trustResult.grade,
|
|
124
|
+
latencyMs: performance.now() - start,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
this.stats.denied++;
|
|
128
|
+
await this.audit(request, trustResult.decision, trustResult.reason);
|
|
129
|
+
return {
|
|
130
|
+
allowed: false,
|
|
131
|
+
decision: trustResult.decision,
|
|
132
|
+
reason: trustResult.reason,
|
|
133
|
+
serverName: request.serverName,
|
|
134
|
+
toolName: request.toolName,
|
|
135
|
+
trustScore: trustResult.trustScore,
|
|
136
|
+
grade: trustResult.grade,
|
|
137
|
+
latencyMs: performance.now() - start,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
// All checks passed
|
|
141
|
+
this.stats.allowed++;
|
|
142
|
+
await this.audit(request, 'allow');
|
|
143
|
+
return {
|
|
144
|
+
allowed: true,
|
|
145
|
+
decision: 'allow',
|
|
146
|
+
serverName: request.serverName,
|
|
147
|
+
toolName: request.toolName,
|
|
148
|
+
trustScore: trustResult.trustScore,
|
|
149
|
+
grade: trustResult.grade,
|
|
150
|
+
latencyMs: performance.now() - start,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Get gateway stats.
|
|
155
|
+
*/
|
|
156
|
+
getStats() {
|
|
157
|
+
return { ...this.stats };
|
|
158
|
+
}
|
|
159
|
+
// ─── Trust Verification ─────────────────────────────────────────
|
|
160
|
+
checkTrust(serverName, policy) {
|
|
161
|
+
const trust = policy.trust ?? {};
|
|
162
|
+
const globalMinScore = this.config.gateway.minTrustScore;
|
|
163
|
+
const globalMinGrade = this.config.gateway.minGrade;
|
|
164
|
+
// Check if certificate is required
|
|
165
|
+
const cert = this.trustStore.getCertificate(serverName);
|
|
166
|
+
if (trust.requireCertificate && !cert) {
|
|
167
|
+
return { decision: 'deny-no-cert', reason: `No trust certificate found for "${serverName}"` };
|
|
168
|
+
}
|
|
169
|
+
// If no cert and not required, skip cert-dependent checks
|
|
170
|
+
if (!cert) {
|
|
171
|
+
// Apply global minimums if set — without a cert we can't verify
|
|
172
|
+
if (globalMinScore !== undefined || globalMinGrade !== undefined) {
|
|
173
|
+
return { decision: 'deny-no-cert', reason: `Trust score/grade required but no certificate available for "${serverName}"` };
|
|
174
|
+
}
|
|
175
|
+
return { decision: 'allow' };
|
|
176
|
+
}
|
|
177
|
+
if (!cert.verified) {
|
|
178
|
+
return { decision: 'deny-invalid-cert', reason: 'Certificate signature is invalid', trustScore: cert.certificate.trustScore.overall, grade: cert.certificate.trustScore.grade };
|
|
179
|
+
}
|
|
180
|
+
// Expiry check
|
|
181
|
+
if (new Date(cert.certificate.expiresAt) < new Date()) {
|
|
182
|
+
return { decision: 'deny-expired', reason: 'Certificate has expired', trustScore: cert.certificate.trustScore.overall, grade: cert.certificate.trustScore.grade };
|
|
183
|
+
}
|
|
184
|
+
const score = cert.certificate.trustScore.overall;
|
|
185
|
+
const grade = cert.certificate.trustScore.grade;
|
|
186
|
+
// Score checks (server-specific overrides global)
|
|
187
|
+
const minScore = trust.minScore ?? globalMinScore;
|
|
188
|
+
if (minScore !== undefined && score < minScore) {
|
|
189
|
+
return { decision: 'deny-score', reason: `Trust score ${score} is below minimum ${minScore}`, trustScore: score, grade };
|
|
190
|
+
}
|
|
191
|
+
// Grade checks
|
|
192
|
+
const minGrade = trust.minGrade ?? globalMinGrade;
|
|
193
|
+
if (minGrade && !gradeAtLeast(grade, minGrade)) {
|
|
194
|
+
return { decision: 'deny-grade', reason: `Grade ${grade} is below minimum ${minGrade}`, trustScore: score, grade };
|
|
195
|
+
}
|
|
196
|
+
// Finding limits
|
|
197
|
+
const summary = cert.certificate.findingSummary;
|
|
198
|
+
if (trust.maxFindingsCritical !== undefined && summary.critical > trust.maxFindingsCritical) {
|
|
199
|
+
return { decision: 'deny-findings', reason: `${summary.critical} critical findings exceeds max ${trust.maxFindingsCritical}`, trustScore: score, grade };
|
|
200
|
+
}
|
|
201
|
+
if (trust.maxFindingsHigh !== undefined && summary.high > trust.maxFindingsHigh) {
|
|
202
|
+
return { decision: 'deny-findings', reason: `${summary.high} high findings exceeds max ${trust.maxFindingsHigh}`, trustScore: score, grade };
|
|
203
|
+
}
|
|
204
|
+
// Permission checks
|
|
205
|
+
if (trust.allowedPermissions) {
|
|
206
|
+
const forbidden = cert.certificate.permissions.filter(p => !trust.allowedPermissions.includes(p));
|
|
207
|
+
if (forbidden.length > 0) {
|
|
208
|
+
return { decision: 'deny-permissions', reason: `Forbidden permissions detected: ${forbidden.join(', ')}`, trustScore: score, grade };
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (trust.blockedPermissions) {
|
|
212
|
+
const blocked = cert.certificate.permissions.filter(p => trust.blockedPermissions.includes(p));
|
|
213
|
+
if (blocked.length > 0) {
|
|
214
|
+
return { decision: 'deny-permissions', reason: `Blocked permissions detected: ${blocked.join(', ')}`, trustScore: score, grade };
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return { decision: 'allow', trustScore: score, grade };
|
|
218
|
+
}
|
|
219
|
+
// ─── Helpers ────────────────────────────────────────────────────
|
|
220
|
+
async audit(request, decision, reason) {
|
|
221
|
+
await this.auditLog.log({
|
|
222
|
+
eventType: decision === 'allow' ? 'session_created' : 'handshake_failed',
|
|
223
|
+
actorDid: request.callerId,
|
|
224
|
+
result: decision === 'allow' || decision === 'warn' ? 'success' : 'failure',
|
|
225
|
+
metadata: {
|
|
226
|
+
server: request.serverName,
|
|
227
|
+
tool: request.toolName,
|
|
228
|
+
decision,
|
|
229
|
+
reason,
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
makeResponse(request, decision, reason, startTime) {
|
|
234
|
+
this.audit(request, decision, reason);
|
|
235
|
+
return {
|
|
236
|
+
allowed: false,
|
|
237
|
+
decision,
|
|
238
|
+
reason,
|
|
239
|
+
serverName: request.serverName,
|
|
240
|
+
toolName: request.toolName,
|
|
241
|
+
latencyMs: performance.now() - startTime,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=gateway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway.js","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAyC9C,wEAAwE;AAExE,MAAM,WAAW;IAIL;IACA;IAJF,OAAO,GAAG,IAAI,GAAG,EAA8C,CAAC;IAExE,YACU,WAAmB,EACnB,QAAgB;QADhB,gBAAW,GAAX,WAAW,CAAQ;QACnB,aAAQ,GAAR,QAAQ,CAAQ;IACvB,CAAC;IAEJ,KAAK,CAAC,GAAW;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEpC,IAAI,CAAC,KAAK,IAAI,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YAClE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAC;QAClD,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACpD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAElD,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM;QAC1C,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS;YACjC,CAAC,CAAC,UAAU,CAAC;IAEf,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;AAC3B,CAAC;AAED,wEAAwE;AAExE,MAAM,WAAW,GAA2B,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AAE7E,SAAS,YAAY,CAAC,MAAc,EAAE,QAAgB;IACpD,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,wEAAwE;AAExE,MAAM,OAAO,YAAY;IACf,MAAM,CAAgB;IACtB,UAAU,CAAa;IACvB,QAAQ,CAAW;IACnB,YAAY,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC9C,KAAK,GAAG;QACd,aAAa,EAAE,CAAC;QAChB,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,CAAC;QACT,MAAM,EAAE,CAAC;KACV,CAAC;IAEF,YAAY,MAAqB,EAAE,UAAuB,EAAE,QAAmB;QAC7E,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,UAAU,IAAI,IAAI,UAAU,EAAE,CAAC;QACjD,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,IAAI,QAAQ,CAAC;YACvC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,gCAAgC;SACpE,CAAC,CAAC;QAEH,2CAA2C;QAC3C,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBACrB,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBAC3D,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,WAAW,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,OAAuB;QAC1C,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;QAE3B,yBAAyB;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;QAC5E,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,qBAAqB,EACrD,WAAW,OAAO,CAAC,UAAU,qBAAqB,EAAE,KAAK,CAAC,CAAC;QAC/D,CAAC;QAED,mBAAmB;QACnB,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC1D,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC;YAC3E,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,KAAK,CAAC,CAAC;QACrF,CAAC;QAED,8BAA8B;QAC9B,IAAI,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,mBAAmB,EACnD,SAAS,OAAO,CAAC,QAAQ,4BAA4B,OAAO,CAAC,UAAU,GAAG,EAAE,KAAK,CAAC,CAAC;QACvF,CAAC;QAED,IAAI,MAAM,CAAC,YAAY,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3E,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,kBAAkB,EAClD,SAAS,OAAO,CAAC,QAAQ,4CAA4C,OAAO,CAAC,UAAU,GAAG,EAAE,KAAK,CAAC,CAAC;QACvG,CAAC;QAED,qBAAqB;QACrB,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAEhE,IAAI,WAAW,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACrC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC9C,kCAAkC;gBAClC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACpB,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;gBACtD,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,QAAQ,EAAE,MAAM;oBAChB,MAAM,EAAE,UAAU,WAAW,CAAC,MAAM,EAAE;oBACtC,UAAU,EAAE,OAAO,CAAC,UAAU;oBAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,UAAU,EAAE,WAAW,CAAC,UAAU;oBAClC,KAAK,EAAE,WAAW,CAAC,KAAK;oBACxB,SAAS,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK;iBACrC,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;YACpE,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE,WAAW,CAAC,QAAQ;gBAC9B,MAAM,EAAE,WAAW,CAAC,MAAM;gBAC1B,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,UAAU,EAAE,WAAW,CAAC,UAAU;gBAClC,KAAK,EAAE,WAAW,CAAC,KAAK;gBACxB,SAAS,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK;aACrC,CAAC;QACJ,CAAC;QAED,oBAAoB;QACpB,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAEnC,OAAO;YACL,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,OAAO;YACjB,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,UAAU,EAAE,WAAW,CAAC,UAAU;YAClC,KAAK,EAAE,WAAW,CAAC,KAAK;YACxB,SAAS,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK;SACrC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED,mEAAmE;IAE3D,UAAU,CAChB,UAAkB,EAClB,MAAoB;QAEpB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;QACjC,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC;QACzD,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;QAEpD,mCAAmC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QAExD,IAAI,KAAK,CAAC,kBAAkB,IAAI,CAAC,IAAI,EAAE,CAAC;YACtC,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,mCAAmC,UAAU,GAAG,EAAE,CAAC;QAChG,CAAC;QAED,0DAA0D;QAC1D,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,gEAAgE;YAChE,IAAI,cAAc,KAAK,SAAS,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;gBACjE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,gEAAgE,UAAU,GAAG,EAAE,CAAC;YAC7H,CAAC;YACD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;QAC/B,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,EAAE,kCAAkC,EAAE,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QAClL,CAAC;QAED,eAAe;QACf,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;YACtD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,yBAAyB,EAAE,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACpK,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC;QAEhD,kDAAkD;QAClD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,cAAc,CAAC;QAClD,IAAI,QAAQ,KAAK,SAAS,IAAI,KAAK,GAAG,QAAQ,EAAE,CAAC;YAC/C,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,KAAK,qBAAqB,QAAQ,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC3H,CAAC;QAED,eAAe;QACf,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,cAAc,CAAC;QAClD,IAAI,QAAQ,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC/C,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,KAAK,qBAAqB,QAAQ,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACrH,CAAC;QAED,iBAAiB;QACjB,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC;QAChD,IAAI,KAAK,CAAC,mBAAmB,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAC,mBAAmB,EAAE,CAAC;YAC5F,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,kCAAkC,KAAK,CAAC,mBAAmB,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC3J,CAAC;QACD,IAAI,KAAK,CAAC,eAAe,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC,eAAe,EAAE,CAAC;YAChF,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,8BAA8B,KAAK,CAAC,eAAe,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC/I,CAAC;QAED,oBAAoB;QACpB,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC;YAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YACnG,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,EAAE,mCAAmC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YACvI,CAAC;QACH,CAAC;QACD,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YAChG,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,EAAE,iCAAiC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YACnI,CAAC;QACH,CAAC;QAED,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACzD,CAAC;IAED,mEAAmE;IAE3D,KAAK,CAAC,KAAK,CACjB,OAAuB,EACvB,QAAuB,EACvB,MAAe;QAEf,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YACtB,SAAS,EAAE,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,kBAAkB;YACxE,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,MAAM,EAAE,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YAC3E,QAAQ,EAAE;gBACR,MAAM,EAAE,OAAO,CAAC,UAAU;gBAC1B,IAAI,EAAE,OAAO,CAAC,QAAQ;gBACtB,QAAQ;gBACR,MAAM;aACP;SACF,CAAC,CAAC;IACL,CAAC;IAEO,YAAY,CAClB,OAAuB,EACvB,QAAuB,EACvB,MAAc,EACd,SAAiB;QAEjB,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QACtC,OAAO;YACL,OAAO,EAAE,KAAK;YACd,QAAQ;YACR,MAAM;YACN,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,SAAS,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS;SACzC,CAAC;IACJ,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sentinel-atl/trust-gateway — YAML-Configured MCP Trust Gateway
|
|
3
|
+
*
|
|
4
|
+
* A runtime trust enforcement proxy for MCP servers.
|
|
5
|
+
* Reads a sentinel.yaml config file and enforces trust policies:
|
|
6
|
+
*
|
|
7
|
+
* Client → [Trust Gateway: verify STC, check score, enforce permissions] → MCP Server
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* sentinel-gateway --config sentinel.yaml
|
|
11
|
+
*/
|
|
12
|
+
export { loadConfig, validateConfig, type GatewayConfig, type ServerPolicy, type TrustRequirements, } from './config.js';
|
|
13
|
+
export { TrustGateway, type GatewayRequest, type GatewayResponse, type TrustDecision, } from './gateway.js';
|
|
14
|
+
export { TrustStore, type StoredCertificate, type TrustStoreOptions, } from './trust-store.js';
|
|
15
|
+
export { TrustGatewayProxy, type ProxyOptions, } from './proxy.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,UAAU,EACV,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,iBAAiB,GACvB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,EACZ,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,aAAa,GACnB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,UAAU,EACV,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,iBAAiB,EACjB,KAAK,YAAY,GAClB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sentinel-atl/trust-gateway — YAML-Configured MCP Trust Gateway
|
|
3
|
+
*
|
|
4
|
+
* A runtime trust enforcement proxy for MCP servers.
|
|
5
|
+
* Reads a sentinel.yaml config file and enforces trust policies:
|
|
6
|
+
*
|
|
7
|
+
* Client → [Trust Gateway: verify STC, check score, enforce permissions] → MCP Server
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* sentinel-gateway --config sentinel.yaml
|
|
11
|
+
*/
|
|
12
|
+
export { loadConfig, validateConfig, } from './config.js';
|
|
13
|
+
export { TrustGateway, } from './gateway.js';
|
|
14
|
+
export { TrustStore, } from './trust-store.js';
|
|
15
|
+
export { TrustGatewayProxy, } from './proxy.js';
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,UAAU,EACV,cAAc,GAIf,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,GAIb,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,UAAU,GAGX,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,iBAAiB,GAElB,MAAM,YAAY,CAAC"}
|
package/dist/proxy.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust Gateway HTTP Proxy — sits between MCP client and server,
|
|
3
|
+
* enforcing trust policies on every tool call.
|
|
4
|
+
*
|
|
5
|
+
* Supports upstream protocols:
|
|
6
|
+
* - http:// / https:// → SSE-based MCP server
|
|
7
|
+
* - stdio:// → stdio-based MCP server (spawns child process)
|
|
8
|
+
*
|
|
9
|
+
* Endpoints exposed:
|
|
10
|
+
* GET /sse → SSE stream (proxied from upstream)
|
|
11
|
+
* POST /message → JSON-RPC message relay (tool calls pass through trust engine)
|
|
12
|
+
* GET /health → Proxy health
|
|
13
|
+
* GET /stats → Gateway stats
|
|
14
|
+
*/
|
|
15
|
+
import { TrustGateway } from './gateway.js';
|
|
16
|
+
import type { GatewayConfig } from './config.js';
|
|
17
|
+
import { TrustStore } from './trust-store.js';
|
|
18
|
+
import { type AuthConfig, type CorsConfig, type TlsConfig } from '@sentinel-atl/hardening';
|
|
19
|
+
export interface ProxyOptions {
|
|
20
|
+
/** Gateway config */
|
|
21
|
+
config: GatewayConfig;
|
|
22
|
+
/** Pre-configured trust store (optional) */
|
|
23
|
+
trustStore?: TrustStore;
|
|
24
|
+
/** Default caller ID when none provided */
|
|
25
|
+
defaultCallerId?: string;
|
|
26
|
+
/** API key authentication config */
|
|
27
|
+
auth?: AuthConfig;
|
|
28
|
+
/** CORS configuration */
|
|
29
|
+
cors?: CorsConfig;
|
|
30
|
+
/** TLS configuration */
|
|
31
|
+
tls?: TlsConfig;
|
|
32
|
+
}
|
|
33
|
+
export declare class TrustGatewayProxy {
|
|
34
|
+
private server;
|
|
35
|
+
private gateway;
|
|
36
|
+
private config;
|
|
37
|
+
private sseClients;
|
|
38
|
+
private stdioUpstreams;
|
|
39
|
+
private defaultCallerId;
|
|
40
|
+
private authConfig;
|
|
41
|
+
private corsConfig;
|
|
42
|
+
private tlsConfig?;
|
|
43
|
+
private globalRateLimiter?;
|
|
44
|
+
constructor(options: ProxyOptions);
|
|
45
|
+
getGateway(): TrustGateway;
|
|
46
|
+
/**
|
|
47
|
+
* Start the HTTP proxy server.
|
|
48
|
+
*/
|
|
49
|
+
start(): Promise<{
|
|
50
|
+
port: number;
|
|
51
|
+
}>;
|
|
52
|
+
/**
|
|
53
|
+
* Stop the proxy and clean up.
|
|
54
|
+
*/
|
|
55
|
+
stop(): Promise<void>;
|
|
56
|
+
private handleRequest;
|
|
57
|
+
private handleHealth;
|
|
58
|
+
private handleStats;
|
|
59
|
+
private handleSSE;
|
|
60
|
+
private sendSSEEvent;
|
|
61
|
+
private handleMessage;
|
|
62
|
+
private findUpstream;
|
|
63
|
+
private forwardToUpstream;
|
|
64
|
+
private forwardHttp;
|
|
65
|
+
private connectStdio;
|
|
66
|
+
private forwardStdio;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=proxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,EAAE,YAAY,EAAwB,MAAM,cAAc,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAOL,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EACjD,MAAM,yBAAyB,CAAC;AAIjC,MAAM,WAAW,YAAY;IAC3B,qBAAqB;IACrB,MAAM,EAAE,aAAa,CAAC;IACtB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,2CAA2C;IAC3C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oCAAoC;IACpC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,yBAAyB;IACzB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,wBAAwB;IACxB,GAAG,CAAC,EAAE,SAAS,CAAC;CACjB;AAgBD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,cAAc,CAAoC;IAC1D,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,iBAAiB,CAAC,CAAsB;gBAEpC,OAAO,EAAE,YAAY;IAejC,UAAU,IAAI,YAAY;IAI1B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAuBxC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B3B,OAAO,CAAC,aAAa;IAiCrB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,SAAS;IA0BjB,OAAO,CAAC,YAAY;YAMN,aAAa;IAgI3B,OAAO,CAAC,YAAY;YAMN,iBAAiB;YAcjB,WAAW;IAqBzB,OAAO,CAAC,YAAY;IAoDpB,OAAO,CAAC,YAAY;CAqBrB"}
|