@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/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# @sentinel-atl/trust-gateway
|
|
2
|
+
|
|
3
|
+
YAML-configured MCP trust gateway — runtime enforcement of Sentinel Trust Certificates.
|
|
4
|
+
|
|
5
|
+
Acts as a reverse proxy between MCP clients and servers, enforcing trust policies based on scan results and STCs. Supports stdio and HTTP/SSE upstreams, strict/permissive modes, per-server policies, and tool-level access control.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @sentinel-atl/trust-gateway
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### 1. Create a config file
|
|
16
|
+
|
|
17
|
+
```yaml
|
|
18
|
+
# sentinel.yaml
|
|
19
|
+
gateway:
|
|
20
|
+
name: my-gateway
|
|
21
|
+
port: 3100
|
|
22
|
+
mode: strict # reject untrusted servers (or 'permissive' to warn only)
|
|
23
|
+
minTrustScore: 60
|
|
24
|
+
minGrade: C
|
|
25
|
+
|
|
26
|
+
servers:
|
|
27
|
+
- name: filesystem
|
|
28
|
+
upstream: stdio://node ./fs-server.js
|
|
29
|
+
trust:
|
|
30
|
+
minScore: 75
|
|
31
|
+
minGrade: B
|
|
32
|
+
requireCertificate: true
|
|
33
|
+
maxFindingsCritical: 0
|
|
34
|
+
maxFindingsHigh: 2
|
|
35
|
+
allowedPermissions: [filesystem]
|
|
36
|
+
blockedTools: [delete_file]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 2. Start the gateway
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx sentinel-gateway --config sentinel.yaml
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 3. Validate config without starting
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx sentinel-gateway validate sentinel.yaml
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Configuration Reference
|
|
52
|
+
|
|
53
|
+
### Gateway Settings
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
gateway:
|
|
57
|
+
name: my-gateway
|
|
58
|
+
port: 3100
|
|
59
|
+
mode: strict | permissive
|
|
60
|
+
minTrustScore: 60 # Global minimum (0-100)
|
|
61
|
+
minGrade: C # Global minimum (A-F)
|
|
62
|
+
logPath: ./audit.jsonl # Audit log location
|
|
63
|
+
apiKeys: [key1, key2] # API key auth
|
|
64
|
+
corsOrigins: ['*'] # CORS origins
|
|
65
|
+
tlsCert: /path/to/cert.pem
|
|
66
|
+
tlsKey: /path/to/key.pem
|
|
67
|
+
rateLimit: "1000/min"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Per-Server Policies
|
|
71
|
+
|
|
72
|
+
```yaml
|
|
73
|
+
servers:
|
|
74
|
+
- name: my-server
|
|
75
|
+
upstream: http://localhost:4000/sse # or stdio://command args
|
|
76
|
+
trust:
|
|
77
|
+
minScore: 75
|
|
78
|
+
minGrade: B
|
|
79
|
+
requireCertificate: true
|
|
80
|
+
maxFindingsCritical: 0
|
|
81
|
+
maxFindingsHigh: 2
|
|
82
|
+
allowedPermissions: [filesystem, network]
|
|
83
|
+
blockedPermissions: [native]
|
|
84
|
+
rateLimit: "100/min"
|
|
85
|
+
blockedTools: [dangerous_tool]
|
|
86
|
+
allowedTools: [safe_tool_a, safe_tool_b]
|
|
87
|
+
certificatePath: ./server.stc.json
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Programmatic Usage
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import { TrustGateway, loadConfig } from '@sentinel-atl/trust-gateway';
|
|
94
|
+
|
|
95
|
+
const config = await loadConfig('./sentinel.yaml');
|
|
96
|
+
const gateway = new TrustGateway(config);
|
|
97
|
+
|
|
98
|
+
const decision = await gateway.evaluate({
|
|
99
|
+
serverName: 'filesystem',
|
|
100
|
+
tool: 'read_file',
|
|
101
|
+
});
|
|
102
|
+
// { allowed: true, score: 85, grade: 'B', ... }
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### With Persistent Storage
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { TrustStore } from '@sentinel-atl/trust-gateway';
|
|
109
|
+
import { RedisStore } from '@sentinel-atl/store';
|
|
110
|
+
|
|
111
|
+
const backend = new RedisStore({ url: 'redis://localhost:6379' });
|
|
112
|
+
const trustStore = new TrustStore({ backend });
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Environment Variables
|
|
116
|
+
|
|
117
|
+
| Variable | Description |
|
|
118
|
+
|----------|-------------|
|
|
119
|
+
| `SENTINEL_API_KEYS` | API key auth |
|
|
120
|
+
| `SENTINEL_CORS_ORIGINS` | CORS allowed origins |
|
|
121
|
+
| `SENTINEL_TLS_CERT_PATH` | TLS certificate path |
|
|
122
|
+
| `SENTINEL_TLS_KEY_PATH` | TLS private key path |
|
|
123
|
+
|
|
124
|
+
## Security
|
|
125
|
+
|
|
126
|
+
- **Content-Type enforcement** on `/message` endpoint
|
|
127
|
+
- **Security headers** — CSP, X-Content-Type-Options, X-Frame-Options
|
|
128
|
+
- **HSTS** when TLS is active
|
|
129
|
+
- **Rate limiting** — global and per-server
|
|
130
|
+
- **Audit logging** to JSONL with rotation
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
MIT
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
process.on('unhandledRejection', (err) => {
|
|
3
|
+
console.error('Unhandled rejection:', err);
|
|
4
|
+
process.exit(1);
|
|
5
|
+
});
|
|
6
|
+
process.on('uncaughtException', (err) => {
|
|
7
|
+
console.error('Uncaught exception:', err);
|
|
8
|
+
process.exit(1);
|
|
9
|
+
});
|
|
10
|
+
/**
|
|
11
|
+
* sentinel-gateway — CLI for running the Sentinel Trust Gateway
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* sentinel-gateway --config sentinel.yaml
|
|
15
|
+
* sentinel-gateway validate sentinel.yaml
|
|
16
|
+
*/
|
|
17
|
+
import { readFile } from 'node:fs/promises';
|
|
18
|
+
import { loadConfig, validateConfig } from './config.js';
|
|
19
|
+
import { TrustGateway } from './gateway.js';
|
|
20
|
+
import { TrustGatewayProxy } from './proxy.js';
|
|
21
|
+
import { parse as parseYaml } from 'yaml';
|
|
22
|
+
import { authConfigFromEnv, corsConfigFromEnv, tlsConfigFromEnv, } from '@sentinel-atl/hardening';
|
|
23
|
+
const args = process.argv.slice(2);
|
|
24
|
+
if (args[0] === 'validate') {
|
|
25
|
+
// Validate a config file
|
|
26
|
+
const configPath = args[1];
|
|
27
|
+
if (!configPath) {
|
|
28
|
+
console.error('Usage: sentinel-gateway validate <config.yaml>');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const raw = await readFile(configPath, 'utf-8');
|
|
33
|
+
const config = parseYaml(raw);
|
|
34
|
+
const errors = validateConfig(config);
|
|
35
|
+
if (errors.length === 0) {
|
|
36
|
+
console.log('✓ Configuration is valid');
|
|
37
|
+
console.log(` Gateway: ${config.gateway.name}`);
|
|
38
|
+
console.log(` Mode: ${config.gateway.mode}`);
|
|
39
|
+
console.log(` Servers: ${config.servers.length}`);
|
|
40
|
+
for (const server of config.servers) {
|
|
41
|
+
console.log(` - ${server.name} → ${server.upstream}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.error('✗ Configuration errors:');
|
|
46
|
+
for (const err of errors) {
|
|
47
|
+
console.error(` ${err.path}: ${err.message}`);
|
|
48
|
+
}
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
console.error(`Error: ${err.message}`);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else if (args.includes('--config')) {
|
|
58
|
+
const configIdx = args.indexOf('--config');
|
|
59
|
+
const configPath = args[configIdx + 1];
|
|
60
|
+
if (!configPath) {
|
|
61
|
+
console.error('Usage: sentinel-gateway --config <sentinel.yaml>');
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const config = await loadConfig(configPath);
|
|
66
|
+
console.log(`🛡️ Sentinel Trust Gateway`);
|
|
67
|
+
console.log(` Name: ${config.gateway.name}`);
|
|
68
|
+
console.log(` Mode: ${config.gateway.mode}`);
|
|
69
|
+
console.log(` Port: ${config.gateway.port}`);
|
|
70
|
+
console.log(` Servers: ${config.servers.length}`);
|
|
71
|
+
for (const server of config.servers) {
|
|
72
|
+
console.log(` - ${server.name} → ${server.upstream}`);
|
|
73
|
+
}
|
|
74
|
+
const gateway = new TrustGateway(config);
|
|
75
|
+
// Load certificates
|
|
76
|
+
for (const server of config.servers) {
|
|
77
|
+
if (server.certificatePath) {
|
|
78
|
+
try {
|
|
79
|
+
const stored = await gateway.getTrustStore().loadCertificate(server.name, server.certificatePath);
|
|
80
|
+
const status = stored.verified ? '✓ verified' : '✗ invalid';
|
|
81
|
+
console.log(` [${status}] ${server.name}: score ${stored.certificate.trustScore.overall}/100`);
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
console.error(` ✗ Failed to load certificate for ${server.name}: ${err.message}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Start HTTP proxy with hardening config (YAML > env > defaults)
|
|
89
|
+
const authConfig = config.gateway.apiKeys?.length
|
|
90
|
+
? { enabled: true, keys: config.gateway.apiKeys.map(k => ({ key: k, scopes: ['read', 'write', 'admin'] })) }
|
|
91
|
+
: authConfigFromEnv();
|
|
92
|
+
const corsConfig = config.gateway.corsOrigins?.length
|
|
93
|
+
? { allowedOrigins: config.gateway.corsOrigins }
|
|
94
|
+
: corsConfigFromEnv();
|
|
95
|
+
const tlsConfig = (config.gateway.tlsCert && config.gateway.tlsKey)
|
|
96
|
+
? { enabled: true, certPath: config.gateway.tlsCert, keyPath: config.gateway.tlsKey }
|
|
97
|
+
: tlsConfigFromEnv();
|
|
98
|
+
const proxy = new TrustGatewayProxy({
|
|
99
|
+
config,
|
|
100
|
+
trustStore: gateway.getTrustStore(),
|
|
101
|
+
auth: authConfig,
|
|
102
|
+
cors: corsConfig,
|
|
103
|
+
tls: tlsConfig,
|
|
104
|
+
});
|
|
105
|
+
const { port } = await proxy.start();
|
|
106
|
+
const proto = tlsConfig ? 'https' : 'http';
|
|
107
|
+
console.log(`\n 🚀 HTTP proxy listening on ${proto}://localhost:${port}`);
|
|
108
|
+
console.log(' Endpoints:');
|
|
109
|
+
console.log(` GET /sse?server=<name> SSE stream`);
|
|
110
|
+
console.log(` POST /message?server=<name> JSON-RPC relay`);
|
|
111
|
+
console.log(` GET /health Health check`);
|
|
112
|
+
console.log(` GET /stats Gateway stats`);
|
|
113
|
+
console.log();
|
|
114
|
+
// Graceful shutdown
|
|
115
|
+
const shutdown = async () => {
|
|
116
|
+
console.log('\n Shutting down...');
|
|
117
|
+
await proxy.stop();
|
|
118
|
+
process.exit(0);
|
|
119
|
+
};
|
|
120
|
+
process.on('SIGINT', shutdown);
|
|
121
|
+
process.on('SIGTERM', shutdown);
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
console.error(`Error: ${err.message}`);
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
console.log('🛡️ Sentinel Trust Gateway');
|
|
130
|
+
console.log();
|
|
131
|
+
console.log('Usage:');
|
|
132
|
+
console.log(' sentinel-gateway --config <sentinel.yaml> Start the HTTP proxy');
|
|
133
|
+
console.log(' sentinel-gateway validate <config.yaml> Validate config');
|
|
134
|
+
console.log();
|
|
135
|
+
console.log('Example sentinel.yaml:');
|
|
136
|
+
console.log(`
|
|
137
|
+
gateway:
|
|
138
|
+
name: my-gateway
|
|
139
|
+
port: 3100
|
|
140
|
+
mode: strict
|
|
141
|
+
minTrustScore: 60
|
|
142
|
+
|
|
143
|
+
servers:
|
|
144
|
+
- name: filesystem
|
|
145
|
+
upstream: stdio://node server.js
|
|
146
|
+
trust:
|
|
147
|
+
minScore: 75
|
|
148
|
+
requireCertificate: true
|
|
149
|
+
allowedPermissions: [filesystem]
|
|
150
|
+
blockedTools: [delete_file]
|
|
151
|
+
`);
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YAML configuration loader and validator for the trust gateway.
|
|
3
|
+
*
|
|
4
|
+
* Example sentinel.yaml:
|
|
5
|
+
*
|
|
6
|
+
* gateway:
|
|
7
|
+
* name: my-trust-gateway
|
|
8
|
+
* port: 3100
|
|
9
|
+
* mode: strict # strict = reject unverified, permissive = warn only
|
|
10
|
+
* minTrustScore: 60 # global minimum trust score (0-100)
|
|
11
|
+
* minGrade: C # global minimum grade (A-F)
|
|
12
|
+
* logPath: ./audit.jsonl
|
|
13
|
+
*
|
|
14
|
+
* servers:
|
|
15
|
+
* - name: filesystem
|
|
16
|
+
* upstream: stdio://node server.js
|
|
17
|
+
* trust:
|
|
18
|
+
* minScore: 75
|
|
19
|
+
* minGrade: B
|
|
20
|
+
* requireCertificate: true
|
|
21
|
+
* maxFindingsCritical: 0
|
|
22
|
+
* maxFindingsHigh: 2
|
|
23
|
+
* allowedPermissions: [filesystem]
|
|
24
|
+
* rateLimit: 100/min
|
|
25
|
+
* blockedTools: [delete_file, write_file]
|
|
26
|
+
*
|
|
27
|
+
* - name: web-search
|
|
28
|
+
* upstream: http://localhost:4000/sse
|
|
29
|
+
* trust:
|
|
30
|
+
* minScore: 50
|
|
31
|
+
* allowedPermissions: [network]
|
|
32
|
+
*/
|
|
33
|
+
export interface TrustRequirements {
|
|
34
|
+
/** Minimum trust score (0-100) */
|
|
35
|
+
minScore?: number;
|
|
36
|
+
/** Minimum grade (A-F) */
|
|
37
|
+
minGrade?: string;
|
|
38
|
+
/** Whether a valid STC is required */
|
|
39
|
+
requireCertificate?: boolean;
|
|
40
|
+
/** Maximum allowed critical findings */
|
|
41
|
+
maxFindingsCritical?: number;
|
|
42
|
+
/** Maximum allowed high findings */
|
|
43
|
+
maxFindingsHigh?: number;
|
|
44
|
+
/** Allowed permission kinds (whitelist) */
|
|
45
|
+
allowedPermissions?: string[];
|
|
46
|
+
/** Blocked permission kinds (blacklist) */
|
|
47
|
+
blockedPermissions?: string[];
|
|
48
|
+
}
|
|
49
|
+
export interface ServerPolicy {
|
|
50
|
+
/** Server name */
|
|
51
|
+
name: string;
|
|
52
|
+
/** Upstream MCP server connection (stdio:// or http://) */
|
|
53
|
+
upstream: string;
|
|
54
|
+
/** Trust requirements for this server */
|
|
55
|
+
trust?: TrustRequirements;
|
|
56
|
+
/** Rate limit (e.g., "100/min", "1000/hour") */
|
|
57
|
+
rateLimit?: string;
|
|
58
|
+
/** Blocked tool names */
|
|
59
|
+
blockedTools?: string[];
|
|
60
|
+
/** Allowed tool names (whitelist — if set, only these tools are allowed) */
|
|
61
|
+
allowedTools?: string[];
|
|
62
|
+
/** Path to the server's STC file */
|
|
63
|
+
certificatePath?: string;
|
|
64
|
+
}
|
|
65
|
+
export interface GatewayConfig {
|
|
66
|
+
gateway: {
|
|
67
|
+
name: string;
|
|
68
|
+
port: number;
|
|
69
|
+
mode: 'strict' | 'permissive';
|
|
70
|
+
minTrustScore?: number;
|
|
71
|
+
minGrade?: string;
|
|
72
|
+
logPath?: string;
|
|
73
|
+
/** API keys for authentication (comma-separated in YAML, or use env SENTINEL_API_KEYS) */
|
|
74
|
+
apiKeys?: string[];
|
|
75
|
+
/** Allowed CORS origins (comma-separated in YAML, or use env SENTINEL_CORS_ORIGINS) */
|
|
76
|
+
corsOrigins?: string[];
|
|
77
|
+
/** Path to TLS certificate file */
|
|
78
|
+
tlsCert?: string;
|
|
79
|
+
/** Path to TLS key file */
|
|
80
|
+
tlsKey?: string;
|
|
81
|
+
/** Global rate limit (e.g. "1000/min") */
|
|
82
|
+
rateLimit?: string;
|
|
83
|
+
};
|
|
84
|
+
servers: ServerPolicy[];
|
|
85
|
+
}
|
|
86
|
+
export interface ConfigError {
|
|
87
|
+
path: string;
|
|
88
|
+
message: string;
|
|
89
|
+
}
|
|
90
|
+
export declare function validateConfig(config: GatewayConfig): ConfigError[];
|
|
91
|
+
/**
|
|
92
|
+
* Load and validate a sentinel.yaml configuration file.
|
|
93
|
+
*/
|
|
94
|
+
export declare function loadConfig(configPath: string): Promise<GatewayConfig>;
|
|
95
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAOH,MAAM,WAAW,iBAAiB;IAChC,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,wCAAwC;IACxC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oCAAoC;IACpC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2CAA2C;IAC3C,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,2CAA2C;IAC3C,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,oCAAoC;IACpC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,QAAQ,GAAG,YAAY,CAAC;QAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,0FAA0F;QAC1F,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,uFAAuF;QACvF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;QACvB,mCAAmC;QACnC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,2BAA2B;QAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,0CAA0C;QAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAOD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,EAAE,CAsEnE;AAID;;GAEG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAW3E"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YAML configuration loader and validator for the trust gateway.
|
|
3
|
+
*
|
|
4
|
+
* Example sentinel.yaml:
|
|
5
|
+
*
|
|
6
|
+
* gateway:
|
|
7
|
+
* name: my-trust-gateway
|
|
8
|
+
* port: 3100
|
|
9
|
+
* mode: strict # strict = reject unverified, permissive = warn only
|
|
10
|
+
* minTrustScore: 60 # global minimum trust score (0-100)
|
|
11
|
+
* minGrade: C # global minimum grade (A-F)
|
|
12
|
+
* logPath: ./audit.jsonl
|
|
13
|
+
*
|
|
14
|
+
* servers:
|
|
15
|
+
* - name: filesystem
|
|
16
|
+
* upstream: stdio://node server.js
|
|
17
|
+
* trust:
|
|
18
|
+
* minScore: 75
|
|
19
|
+
* minGrade: B
|
|
20
|
+
* requireCertificate: true
|
|
21
|
+
* maxFindingsCritical: 0
|
|
22
|
+
* maxFindingsHigh: 2
|
|
23
|
+
* allowedPermissions: [filesystem]
|
|
24
|
+
* rateLimit: 100/min
|
|
25
|
+
* blockedTools: [delete_file, write_file]
|
|
26
|
+
*
|
|
27
|
+
* - name: web-search
|
|
28
|
+
* upstream: http://localhost:4000/sse
|
|
29
|
+
* trust:
|
|
30
|
+
* minScore: 50
|
|
31
|
+
* allowedPermissions: [network]
|
|
32
|
+
*/
|
|
33
|
+
import { readFile } from 'node:fs/promises';
|
|
34
|
+
import { parse as parseYaml } from 'yaml';
|
|
35
|
+
// ─── Validators ──────────────────────────────────────────────────────
|
|
36
|
+
const VALID_GRADES = ['A', 'B', 'C', 'D', 'F'];
|
|
37
|
+
const VALID_PERMISSIONS = ['filesystem', 'network', 'process', 'crypto', 'environment', 'native'];
|
|
38
|
+
export function validateConfig(config) {
|
|
39
|
+
const errors = [];
|
|
40
|
+
if (!config.gateway) {
|
|
41
|
+
errors.push({ path: 'gateway', message: 'Missing gateway configuration' });
|
|
42
|
+
return errors;
|
|
43
|
+
}
|
|
44
|
+
if (!config.gateway.name) {
|
|
45
|
+
errors.push({ path: 'gateway.name', message: 'Gateway name is required' });
|
|
46
|
+
}
|
|
47
|
+
if (!config.gateway.port || config.gateway.port < 1 || config.gateway.port > 65535) {
|
|
48
|
+
errors.push({ path: 'gateway.port', message: 'Port must be between 1 and 65535' });
|
|
49
|
+
}
|
|
50
|
+
if (!['strict', 'permissive'].includes(config.gateway.mode)) {
|
|
51
|
+
errors.push({ path: 'gateway.mode', message: 'Mode must be "strict" or "permissive"' });
|
|
52
|
+
}
|
|
53
|
+
if (config.gateway.minTrustScore !== undefined &&
|
|
54
|
+
(config.gateway.minTrustScore < 0 || config.gateway.minTrustScore > 100)) {
|
|
55
|
+
errors.push({ path: 'gateway.minTrustScore', message: 'Score must be 0-100' });
|
|
56
|
+
}
|
|
57
|
+
if (config.gateway.minGrade !== undefined && !VALID_GRADES.includes(config.gateway.minGrade)) {
|
|
58
|
+
errors.push({ path: 'gateway.minGrade', message: `Grade must be one of: ${VALID_GRADES.join(', ')}` });
|
|
59
|
+
}
|
|
60
|
+
if (!Array.isArray(config.servers)) {
|
|
61
|
+
errors.push({ path: 'servers', message: 'Servers must be an array' });
|
|
62
|
+
return errors;
|
|
63
|
+
}
|
|
64
|
+
for (let i = 0; i < config.servers.length; i++) {
|
|
65
|
+
const server = config.servers[i];
|
|
66
|
+
const prefix = `servers[${i}]`;
|
|
67
|
+
if (!server.name) {
|
|
68
|
+
errors.push({ path: `${prefix}.name`, message: 'Server name is required' });
|
|
69
|
+
}
|
|
70
|
+
if (!server.upstream) {
|
|
71
|
+
errors.push({ path: `${prefix}.upstream`, message: 'Upstream is required' });
|
|
72
|
+
}
|
|
73
|
+
else if (!server.upstream.startsWith('stdio://') &&
|
|
74
|
+
!server.upstream.startsWith('http://') &&
|
|
75
|
+
!server.upstream.startsWith('https://')) {
|
|
76
|
+
errors.push({ path: `${prefix}.upstream`, message: 'Upstream must start with stdio://, http://, or https://' });
|
|
77
|
+
}
|
|
78
|
+
if (server.trust?.minGrade && !VALID_GRADES.includes(server.trust.minGrade)) {
|
|
79
|
+
errors.push({ path: `${prefix}.trust.minGrade`, message: `Grade must be one of: ${VALID_GRADES.join(', ')}` });
|
|
80
|
+
}
|
|
81
|
+
if (server.trust?.allowedPermissions) {
|
|
82
|
+
for (const perm of server.trust.allowedPermissions) {
|
|
83
|
+
if (!VALID_PERMISSIONS.includes(perm)) {
|
|
84
|
+
errors.push({ path: `${prefix}.trust.allowedPermissions`, message: `Unknown permission: ${perm}` });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (server.rateLimit) {
|
|
89
|
+
if (!/^\d+\/(min|hour|day)$/.test(server.rateLimit)) {
|
|
90
|
+
errors.push({ path: `${prefix}.rateLimit`, message: 'Rate limit must be in format "N/min", "N/hour", or "N/day"' });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return errors;
|
|
95
|
+
}
|
|
96
|
+
// ─── Loader ──────────────────────────────────────────────────────────
|
|
97
|
+
/**
|
|
98
|
+
* Load and validate a sentinel.yaml configuration file.
|
|
99
|
+
*/
|
|
100
|
+
export async function loadConfig(configPath) {
|
|
101
|
+
const raw = await readFile(configPath, 'utf-8');
|
|
102
|
+
const config = parseYaml(raw);
|
|
103
|
+
const errors = validateConfig(config);
|
|
104
|
+
if (errors.length > 0) {
|
|
105
|
+
const messages = errors.map(e => ` ${e.path}: ${e.message}`).join('\n');
|
|
106
|
+
throw new Error(`Invalid configuration:\n${messages}`);
|
|
107
|
+
}
|
|
108
|
+
return config;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
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 type { GatewayConfig } from './config.js';
|
|
13
|
+
import { TrustStore } from './trust-store.js';
|
|
14
|
+
export interface GatewayRequest {
|
|
15
|
+
/** Name of the server being called */
|
|
16
|
+
serverName: string;
|
|
17
|
+
/** Tool being invoked */
|
|
18
|
+
toolName: string;
|
|
19
|
+
/** Caller identifier */
|
|
20
|
+
callerId: string;
|
|
21
|
+
/** Tool call arguments (for logging) */
|
|
22
|
+
arguments?: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
export type TrustDecision = 'allow' | 'deny-no-cert' | 'deny-invalid-cert' | 'deny-expired' | 'deny-score' | 'deny-grade' | 'deny-findings' | 'deny-permissions' | 'deny-blocked-tool' | 'deny-not-allowed' | 'deny-rate-limit' | 'deny-unknown-server' | 'warn';
|
|
25
|
+
export interface GatewayResponse {
|
|
26
|
+
allowed: boolean;
|
|
27
|
+
decision: TrustDecision;
|
|
28
|
+
reason?: string;
|
|
29
|
+
serverName: string;
|
|
30
|
+
toolName: string;
|
|
31
|
+
trustScore?: number;
|
|
32
|
+
grade?: string;
|
|
33
|
+
latencyMs: number;
|
|
34
|
+
}
|
|
35
|
+
export declare class TrustGateway {
|
|
36
|
+
private config;
|
|
37
|
+
private trustStore;
|
|
38
|
+
private auditLog;
|
|
39
|
+
private rateLimiters;
|
|
40
|
+
private stats;
|
|
41
|
+
constructor(config: GatewayConfig, trustStore?: TrustStore, auditLog?: AuditLog);
|
|
42
|
+
/**
|
|
43
|
+
* Get the trust store for loading certificates.
|
|
44
|
+
*/
|
|
45
|
+
getTrustStore(): TrustStore;
|
|
46
|
+
/**
|
|
47
|
+
* Process a tool call request through the trust pipeline.
|
|
48
|
+
*/
|
|
49
|
+
processRequest(request: GatewayRequest): Promise<GatewayResponse>;
|
|
50
|
+
/**
|
|
51
|
+
* Get gateway stats.
|
|
52
|
+
*/
|
|
53
|
+
getStats(): {
|
|
54
|
+
totalRequests: number;
|
|
55
|
+
allowed: number;
|
|
56
|
+
denied: number;
|
|
57
|
+
warned: number;
|
|
58
|
+
};
|
|
59
|
+
private checkTrust;
|
|
60
|
+
private audit;
|
|
61
|
+
private makeResponse;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=gateway.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAmC,MAAM,aAAa,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAI9C,MAAM,WAAW,cAAc;IAC7B,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,MAAM,aAAa,GACrB,OAAO,GACP,cAAc,GACd,mBAAmB,GACnB,cAAc,GACd,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,kBAAkB,GAClB,mBAAmB,GACnB,kBAAkB,GAClB,iBAAiB,GACjB,qBAAqB,GACrB,MAAM,CAAC;AAEX,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAiDD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,KAAK,CAKX;gBAEU,MAAM,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,QAAQ;IAgB/E;;OAEG;IACH,aAAa,IAAI,UAAU;IAI3B;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAiFvE;;OAEG;IACH,QAAQ;;;;;;IAMR,OAAO,CAAC,UAAU;YA4EJ,KAAK;IAkBnB,OAAO,CAAC,YAAY;CAgBrB"}
|