@mcp-guardian/server 0.4.0 → 0.5.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.
Files changed (91) hide show
  1. package/README.md +105 -8
  2. package/dist/auth/auth-types.d.ts +40 -0
  3. package/dist/auth/auth-types.d.ts.map +1 -0
  4. package/dist/auth/auth-types.js +5 -0
  5. package/dist/auth/auth-types.js.map +1 -0
  6. package/dist/auth/dashboard-auth.d.ts +97 -0
  7. package/dist/auth/dashboard-auth.d.ts.map +1 -0
  8. package/dist/auth/dashboard-auth.js +319 -0
  9. package/dist/auth/dashboard-auth.js.map +1 -0
  10. package/dist/auth/dpop.d.ts +38 -0
  11. package/dist/auth/dpop.d.ts.map +1 -0
  12. package/dist/auth/dpop.js +72 -0
  13. package/dist/auth/dpop.js.map +1 -0
  14. package/dist/auth/oauth.d.ts +25 -0
  15. package/dist/auth/oauth.d.ts.map +1 -0
  16. package/dist/auth/oauth.js +96 -0
  17. package/dist/auth/oauth.js.map +1 -0
  18. package/dist/auth/redis-session-cache.d.ts +21 -0
  19. package/dist/auth/redis-session-cache.d.ts.map +1 -0
  20. package/dist/auth/redis-session-cache.js +74 -0
  21. package/dist/auth/redis-session-cache.js.map +1 -0
  22. package/dist/auth/session-cache.d.ts +47 -0
  23. package/dist/auth/session-cache.d.ts.map +1 -0
  24. package/dist/auth/session-cache.js +91 -0
  25. package/dist/auth/session-cache.js.map +1 -0
  26. package/dist/cli.js +23 -5
  27. package/dist/cli.js.map +1 -1
  28. package/dist/database/database-interface.d.ts +17 -0
  29. package/dist/database/database-interface.d.ts.map +1 -0
  30. package/dist/database/database-interface.js +2 -0
  31. package/dist/database/database-interface.js.map +1 -0
  32. package/dist/database/postgres-db.d.ts +18 -0
  33. package/dist/database/postgres-db.d.ts.map +1 -0
  34. package/dist/database/postgres-db.js +118 -0
  35. package/dist/database/postgres-db.js.map +1 -0
  36. package/dist/index.js +1 -1
  37. package/dist/policy/policy-watcher.d.ts +24 -0
  38. package/dist/policy/policy-watcher.d.ts.map +1 -0
  39. package/dist/policy/policy-watcher.js +68 -0
  40. package/dist/policy/policy-watcher.js.map +1 -0
  41. package/dist/policy/shell-tokenizer.d.ts +92 -0
  42. package/dist/policy/shell-tokenizer.d.ts.map +1 -0
  43. package/dist/policy/shell-tokenizer.js +300 -0
  44. package/dist/policy/shell-tokenizer.js.map +1 -0
  45. package/dist/proxy/http-proxy-server.d.ts +26 -0
  46. package/dist/proxy/http-proxy-server.d.ts.map +1 -0
  47. package/dist/proxy/http-proxy-server.js +172 -0
  48. package/dist/proxy/http-proxy-server.js.map +1 -0
  49. package/dist/proxy/proxy-manager.d.ts +3 -1
  50. package/dist/proxy/proxy-manager.d.ts.map +1 -1
  51. package/dist/proxy/proxy-manager.js +10 -3
  52. package/dist/proxy/proxy-manager.js.map +1 -1
  53. package/dist/proxy/proxy-server.d.ts +15 -8
  54. package/dist/proxy/proxy-server.d.ts.map +1 -1
  55. package/dist/proxy/proxy-server.js +80 -26
  56. package/dist/proxy/proxy-server.js.map +1 -1
  57. package/dist/utils/circuit-breaker.d.ts +29 -0
  58. package/dist/utils/circuit-breaker.d.ts.map +1 -0
  59. package/dist/utils/circuit-breaker.js +81 -0
  60. package/dist/utils/circuit-breaker.js.map +1 -0
  61. package/dist/utils/dashboard-server.d.ts +19 -0
  62. package/dist/utils/dashboard-server.d.ts.map +1 -0
  63. package/dist/utils/dashboard-server.js +258 -0
  64. package/dist/utils/dashboard-server.js.map +1 -0
  65. package/dist/utils/metrics.d.ts +17 -0
  66. package/dist/utils/metrics.d.ts.map +1 -0
  67. package/dist/utils/metrics.js +79 -0
  68. package/dist/utils/metrics.js.map +1 -0
  69. package/dist/utils/mtls-config.d.ts +27 -0
  70. package/dist/utils/mtls-config.d.ts.map +1 -0
  71. package/dist/utils/mtls-config.js +82 -0
  72. package/dist/utils/mtls-config.js.map +1 -0
  73. package/dist/utils/payload-normalizer.d.ts +62 -0
  74. package/dist/utils/payload-normalizer.d.ts.map +1 -0
  75. package/dist/utils/payload-normalizer.js +240 -0
  76. package/dist/utils/payload-normalizer.js.map +1 -0
  77. package/dist/utils/policy-auditor.d.ts +24 -0
  78. package/dist/utils/policy-auditor.d.ts.map +1 -0
  79. package/dist/utils/policy-auditor.js +58 -0
  80. package/dist/utils/policy-auditor.js.map +1 -0
  81. package/dist/utils/redis-rate-limiter.d.ts +22 -0
  82. package/dist/utils/redis-rate-limiter.d.ts.map +1 -0
  83. package/dist/utils/redis-rate-limiter.js +61 -0
  84. package/dist/utils/redis-rate-limiter.js.map +1 -0
  85. package/dist/utils/structured-logger.d.ts +1 -1
  86. package/dist/utils/structured-logger.d.ts.map +1 -1
  87. package/dist/utils/tracing.d.ts +7 -0
  88. package/dist/utils/tracing.d.ts.map +1 -0
  89. package/dist/utils/tracing.js +34 -0
  90. package/dist/utils/tracing.js.map +1 -0
  91. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"proxy-server.d.ts","sourceRoot":"","sources":["../../src/proxy/proxy-server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAI1D;;;;;;;GAOG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,gBAAgB,CAAsC;IAC9D,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,YAAY,CAAsB;gBAGxC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3B,EAAE,EAAE,eAAe,EACnB,UAAU,CAAC,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,YAAY;IAoB7B,IAAI,KAAK,IAAI,MAAM,CAAC,cAAc,GAAG,IAAI,CAExC;IAED,OAAO,CAAC,WAAW;IAoCnB,OAAO,CAAC,WAAW;IAMnB;;;;OAIG;IACH,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAuEpC,IAAI,IAAI,IAAI;CAOb"}
1
+ {"version":3,"file":"proxy-server.d.ts","sourceRoot":"","sources":["../../src/proxy/proxy-server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAG1D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD;;;;;;;GAOG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,gBAAgB,CAAsC;IAC9D,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,aAAa,CAAwB;gBAG3C,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3B,EAAE,EAAE,eAAe,EACnB,UAAU,CAAC,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,YAAY,EAC3B,aAAa,CAAC,EAAE,cAAc;IAsBhC,IAAI,KAAK,IAAI,MAAM,CAAC,cAAc,GAAG,IAAI,CAExC;IAED,OAAO,CAAC,WAAW;IAiCnB,OAAO,CAAC,WAAW;IAMnB;;OAEG;IACH,OAAO,CAAC,SAAS;IASjB;;;;;OAKG;IACG,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmHnD,IAAI,IAAI,IAAI;CAOb"}
@@ -3,13 +3,14 @@ import { createInterface } from 'readline';
3
3
  import { TokenCounter } from '../utils/token-counter.js';
4
4
  import { Logger } from '../utils/logger.js';
5
5
  import { StructuredLogger } from '../utils/structured-logger.js';
6
+ import { OAuthValidator } from '../auth/oauth.js';
6
7
  /**
7
- * MCP Proxy Interceptor — sits between the AI client and an MCP server,
8
- * capturing every JSON-RPC call's token usage for real cost auditing.
8
+ * MCP Proxy Interceptor — sits between the AI client and an MCP server.
9
9
  *
10
10
  * v0.4: Integrated PolicyEngine for active blocking of malicious tool calls.
11
- * If policyEngine is provided, every tools/call is evaluated before forwarding.
12
- * Blocked calls return a JSON-RPC error to the client instead of reaching the server.
11
+ * v0.5: OAuth 2.1 JWT validation validates bearer tokens before policy evaluation.
12
+ * If authValidator is provided, every tools/call requires a valid JWT.
13
+ * Unauthenticated calls are blocked with a JSON-RPC auth error.
13
14
  */
14
15
  export class McpProxyServer {
15
16
  child;
@@ -22,9 +23,11 @@ export class McpProxyServer {
22
23
  requestArguments;
23
24
  serverName;
24
25
  policyEngine;
25
- constructor(command, args, env, db, serverName, policyEngine) {
26
+ authValidator;
27
+ constructor(command, args, env, db, serverName, policyEngine, authValidator) {
26
28
  this.serverName = serverName || command.split('/').pop() || command;
27
29
  this.policyEngine = policyEngine || null;
30
+ this.authValidator = authValidator || null;
28
31
  this.child = spawn(command, args, {
29
32
  env: { ...process.env, ...env },
30
33
  stdio: ['pipe', 'pipe', 'pipe'],
@@ -37,6 +40,7 @@ export class McpProxyServer {
37
40
  event: 'proxy_started',
38
41
  serverName: this.serverName,
39
42
  blockingMode: this.policyEngine ? this.policyEngine.getMode() : 'audit',
43
+ authEnabled: this.authValidator ? this.authValidator.getConfig().required : false,
40
44
  });
41
45
  }
42
46
  get stdin() {
@@ -48,7 +52,6 @@ export class McpProxyServer {
48
52
  try {
49
53
  const msg = JSON.parse(line);
50
54
  if (msg.id && msg.id === this.currentRequestId) {
51
- // Response to our tracked tools/call request
52
55
  const responseTokens = this.tokenCounter.count(line);
53
56
  const record = {
54
57
  serverName: this.serverName,
@@ -63,11 +66,9 @@ export class McpProxyServer {
63
66
  this.currentRequestId = null;
64
67
  this.requestToolName = null;
65
68
  }
66
- // Forward response to client
67
69
  process.stdout.write(line + '\n');
68
70
  }
69
71
  catch {
70
- // Non-JSON line — forward as-is
71
72
  process.stdout.write(line + '\n');
72
73
  }
73
74
  });
@@ -80,12 +81,24 @@ export class McpProxyServer {
80
81
  process.stderr.write(data);
81
82
  });
82
83
  }
84
+ /**
85
+ * Send a JSON-RPC 2.0 error response to the client.
86
+ */
87
+ sendError(id, code, message, data) {
88
+ const errorResponse = JSON.stringify({
89
+ jsonrpc: '2.0',
90
+ id,
91
+ error: { code, message, data },
92
+ });
93
+ process.stdout.write(errorResponse + '\n');
94
+ }
83
95
  /**
84
96
  * Called when the AI client writes a request to be proxied.
85
- * Evaluates tools/call against policy engine before forwarding.
86
- * Blocked calls receive a JSON-RPC error response.
97
+ * 1. Validate OAuth 2.1 JWT (if configured)
98
+ * 2. Evaluate against policy engine
99
+ * 3. Forward or block
87
100
  */
88
- handleClientInput(raw) {
101
+ async handleClientInput(raw) {
89
102
  try {
90
103
  const msg = JSON.parse(raw);
91
104
  if (msg.method === 'tools/call' && msg.id) {
@@ -94,9 +107,60 @@ export class McpProxyServer {
94
107
  this.requestToolName = msg.params?.name || 'unknown';
95
108
  this.requestTokens = this.tokenCounter.count(raw);
96
109
  this.requestArguments = msg.params?.arguments;
110
+ const toolName = this.requestToolName || 'unknown';
111
+ // ── v0.5: OAuth 2.1 JWT validation ──────────────────
112
+ if (this.authValidator) {
113
+ const authHeader = msg.params?._meta?.auth?.Authorization
114
+ || msg.Authorization
115
+ || msg.params?.Authorization
116
+ || undefined;
117
+ const token = OAuthValidator.extractToken(authHeader);
118
+ if (!token) {
119
+ if (this.authValidator.getConfig().required) {
120
+ StructuredLogger.info({
121
+ event: 'auth_required',
122
+ serverName: this.serverName,
123
+ toolName,
124
+ requestId: msg.id,
125
+ });
126
+ this.sendError(msg.id, -32002, 'Authentication required. Provide a valid Bearer token in the Authorization header.');
127
+ this.currentRequestId = null;
128
+ this.requestToolName = null;
129
+ this.requestArguments = undefined;
130
+ return;
131
+ }
132
+ }
133
+ else {
134
+ const result = await this.authValidator.validate(token);
135
+ if (!result.valid) {
136
+ StructuredLogger.logError({
137
+ event: 'oidc_auth_error',
138
+ serverName: this.serverName,
139
+ error: `JWT validation failed: ${result.error}`,
140
+ requestId: msg.id,
141
+ });
142
+ if (this.authValidator.getConfig().required) {
143
+ this.sendError(msg.id, -32003, `Authentication failed: ${result.error}`);
144
+ this.currentRequestId = null;
145
+ this.requestToolName = null;
146
+ this.requestArguments = undefined;
147
+ return;
148
+ }
149
+ }
150
+ else {
151
+ StructuredLogger.info({
152
+ event: 'auth_success',
153
+ serverName: this.serverName,
154
+ toolName,
155
+ requestId: msg.id,
156
+ agent: result.identity?.sub,
157
+ clientId: result.identity?.clientId,
158
+ });
159
+ }
160
+ }
161
+ }
97
162
  // ── v0.4: Active policy enforcement ──────────────────
98
163
  if (this.policyEngine) {
99
- const toolName = this.requestToolName || 'unknown';
100
164
  const context = {
101
165
  serverName: this.serverName,
102
166
  toolName,
@@ -106,7 +170,6 @@ export class McpProxyServer {
106
170
  timestamp: new Date().toISOString(),
107
171
  };
108
172
  const decision = this.policyEngine.evaluate(context);
109
- // Log every decision for SIEM audit trail
110
173
  StructuredLogger.logPolicyDecision({
111
174
  event: 'policy_decision',
112
175
  requestId: msg.id,
@@ -124,22 +187,14 @@ export class McpProxyServer {
124
187
  reason: decision.reason,
125
188
  rule: decision.rule,
126
189
  });
127
- // Return JSON-RPC 2.0 error to client do NOT forward to server
128
- const errorResponse = JSON.stringify({
129
- jsonrpc: '2.0',
130
- id: msg.id,
131
- error: {
132
- code: -32001,
133
- message: `Blocked by MCP Guardian policy: ${decision.reason}`,
134
- data: { rule: decision.rule, policy: this.policyEngine.getMode() },
135
- },
190
+ this.sendError(msg.id, -32001, `Blocked by MCP Guardian policy: ${decision.reason}`, {
191
+ rule: decision.rule,
192
+ policy: this.policyEngine.getMode(),
136
193
  });
137
- process.stdout.write(errorResponse + '\n');
138
- // Reset state
139
194
  this.currentRequestId = null;
140
195
  this.requestToolName = null;
141
196
  this.requestArguments = undefined;
142
- return; // ← CRITICAL: do not forward to child
197
+ return;
143
198
  }
144
199
  }
145
200
  }
@@ -147,7 +202,6 @@ export class McpProxyServer {
147
202
  catch {
148
203
  // Non-JSON input — forward as-is
149
204
  }
150
- // Forward to the underlying MCP server
151
205
  this.child.stdin?.write(raw + '\n');
152
206
  }
153
207
  kill() {
@@ -1 +1 @@
1
- {"version":3,"file":"proxy-server.js","sourceRoot":"","sources":["../../src/proxy/proxy-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proxy-server.js","sourceRoot":"","sources":["../../src/proxy/proxy-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export type CircuitState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';
2
+ export declare class CircuitBreaker {
3
+ private state;
4
+ private failureCount;
5
+ private successCount;
6
+ private lastFailureTime;
7
+ private readonly resetTimeout;
8
+ private readonly failureThreshold;
9
+ private readonly successThreshold;
10
+ private readonly name;
11
+ constructor(name: string, options?: {
12
+ failureThreshold?: number;
13
+ successThreshold?: number;
14
+ resetTimeoutMs?: number;
15
+ });
16
+ /** Check if the circuit allows a request through */
17
+ allowRequest(): boolean;
18
+ /** Record a successful request */
19
+ recordSuccess(): void;
20
+ /** Record a failed request */
21
+ recordFailure(): void;
22
+ getState(): CircuitState;
23
+ getStats(): {
24
+ state: CircuitState;
25
+ failureCount: number;
26
+ successCount: number;
27
+ };
28
+ }
29
+ //# sourceMappingURL=circuit-breaker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../../src/utils/circuit-breaker.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAE3D,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAA0B;IACvC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAG5B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;QAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAO;IAQjG,oDAAoD;IACpD,YAAY,IAAI,OAAO;IAcvB,kCAAkC;IAClC,aAAa,IAAI,IAAI;IAcrB,8BAA8B;IAC9B,aAAa,IAAI,IAAI;IAerB,QAAQ,IAAI,YAAY;IAIxB,QAAQ,IAAI;QAAE,KAAK,EAAE,YAAY,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE;CAOhF"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Circuit Breaker for MCP Proxy Server.
3
+ * Implements the classic 3-state circuit breaker pattern:
4
+ * CLOSED → OPEN → HALF_OPEN → CLOSED (or OPEN again).
5
+ *
6
+ * Used to protect upstream MCP servers from cascading failures.
7
+ */
8
+ import { Logger } from './logger.js';
9
+ export class CircuitBreaker {
10
+ state = 'CLOSED';
11
+ failureCount = 0;
12
+ successCount = 0;
13
+ lastFailureTime = 0;
14
+ resetTimeout;
15
+ failureThreshold;
16
+ successThreshold;
17
+ name;
18
+ constructor(name, options = {}) {
19
+ this.name = name;
20
+ this.failureThreshold = options.failureThreshold || 5;
21
+ this.successThreshold = options.successThreshold || 2;
22
+ this.resetTimeout = options.resetTimeoutMs || 30000;
23
+ }
24
+ /** Check if the circuit allows a request through */
25
+ allowRequest() {
26
+ if (this.state === 'CLOSED')
27
+ return true;
28
+ if (this.state === 'OPEN') {
29
+ if (Date.now() - this.lastFailureTime >= this.resetTimeout) {
30
+ this.state = 'HALF_OPEN';
31
+ Logger.debug(`[circuit-breaker:${this.name}] Transitioned to HALF_OPEN`);
32
+ return true;
33
+ }
34
+ return false;
35
+ }
36
+ // HALF_OPEN: allow probes
37
+ return true;
38
+ }
39
+ /** Record a successful request */
40
+ recordSuccess() {
41
+ if (this.state === 'HALF_OPEN') {
42
+ this.successCount++;
43
+ if (this.successCount >= this.successThreshold) {
44
+ this.state = 'CLOSED';
45
+ this.failureCount = 0;
46
+ this.successCount = 0;
47
+ Logger.info(`[circuit-breaker:${this.name}] Circuit CLOSED — service healthy`);
48
+ }
49
+ }
50
+ else if (this.state === 'CLOSED') {
51
+ this.failureCount = 0;
52
+ }
53
+ }
54
+ /** Record a failed request */
55
+ recordFailure() {
56
+ this.lastFailureTime = Date.now();
57
+ if (this.state === 'HALF_OPEN') {
58
+ this.state = 'OPEN';
59
+ this.successCount = 0;
60
+ Logger.warn(`[circuit-breaker:${this.name}] Circuit OPEN — half-open probe failed`);
61
+ }
62
+ else if (this.state === 'CLOSED') {
63
+ this.failureCount++;
64
+ if (this.failureCount >= this.failureThreshold) {
65
+ this.state = 'OPEN';
66
+ Logger.warn(`[circuit-breaker:${this.name}] Circuit OPEN — ${this.failureCount} consecutive failures`);
67
+ }
68
+ }
69
+ }
70
+ getState() {
71
+ return this.state;
72
+ }
73
+ getStats() {
74
+ return {
75
+ state: this.state,
76
+ failureCount: this.failureCount,
77
+ successCount: this.successCount,
78
+ };
79
+ }
80
+ }
81
+ //# sourceMappingURL=circuit-breaker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../../src/utils/circuit-breaker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,MAAM,OAAO,cAAc;IACjB,KAAK,GAAiB,QAAQ,CAAC;IAC/B,YAAY,GAAW,CAAC,CAAC;IACzB,YAAY,GAAW,CAAC,CAAC;IACzB,eAAe,GAAW,CAAC,CAAC;IACnB,YAAY,CAAS;IACrB,gBAAgB,CAAS;IACzB,gBAAgB,CAAS;IACzB,IAAI,CAAS;IAE9B,YACE,IAAY,EACZ,UAA6F,EAAE;QAE/F,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,cAAc,IAAI,KAAK,CAAC;IACtD,CAAC;IAED,oDAAoD;IACpD,YAAY;QACV,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACzC,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAC1B,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBAC3D,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC;gBACzB,MAAM,CAAC,KAAK,CAAC,oBAAoB,IAAI,CAAC,IAAI,6BAA6B,CAAC,CAAC;gBACzE,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,0BAA0B;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kCAAkC;IAClC,aAAa;QACX,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAC/C,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;gBACtB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;gBACtB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;gBACtB,MAAM,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,IAAI,oCAAoC,CAAC,CAAC;YACjF,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACnC,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,8BAA8B;IAC9B,aAAa;QACX,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC;YACpB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,IAAI,yCAAyC,CAAC,CAAC;QACtF,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACnC,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAC/C,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC;gBACpB,MAAM,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,IAAI,oBAAoB,IAAI,CAAC,YAAY,uBAAuB,CAAC,CAAC;YACzG,CAAC;QACH,CAAC;IACH,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,QAAQ;QACN,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,YAAY,EAAE,IAAI,CAAC,YAAY;SAChC,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ import { createServer } from 'http';
2
+ import { PolicyWatcher } from '../policy/policy-watcher.js';
3
+ import { DashboardAuth } from '../auth/dashboard-auth.js';
4
+ /**
5
+ * Lightweight dashboard server that serves:
6
+ * - / — the dashboard HTML (requires auth if enabled)
7
+ * - /login — login page (when JWT auth is enabled)
8
+ * - /api/login — POST login endpoint
9
+ * - /api/policy — current policy (JSON, requires auth)
10
+ * - /api/policy/reload — trigger policy reload (requires auth)
11
+ * - /metrics — Prometheus metrics (can be auth-gated or public via DASHBOARD_METRICS_PUBLIC=true)
12
+ *
13
+ * v1.2: Integrated DashboardAuth for JWT/API key authentication, CSRF protection.
14
+ */
15
+ export declare function startDashboardServer(port?: number, policyWatcher?: PolicyWatcher, dashboardAuth?: DashboardAuth): Promise<{
16
+ auth: DashboardAuth;
17
+ server: ReturnType<typeof createServer>;
18
+ }>;
19
+ //# sourceMappingURL=dashboard-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-server.d.ts","sourceRoot":"","sources":["../../src/utils/dashboard-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAmC,MAAM,MAAM,CAAC;AAKrE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAM1D;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,GAAE,MAAa,EACnB,aAAa,CAAC,EAAE,aAAa,EAC7B,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAA;CAAE,CAAC,CA2P3E"}
@@ -0,0 +1,258 @@
1
+ import { createServer } from 'http';
2
+ import { readFileSync } from 'fs';
3
+ import { resolve, dirname } from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import { Logger } from './logger.js';
6
+ import { DashboardAuth } from '../auth/dashboard-auth.js';
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = dirname(__filename);
9
+ /**
10
+ * Lightweight dashboard server that serves:
11
+ * - / — the dashboard HTML (requires auth if enabled)
12
+ * - /login — login page (when JWT auth is enabled)
13
+ * - /api/login — POST login endpoint
14
+ * - /api/policy — current policy (JSON, requires auth)
15
+ * - /api/policy/reload — trigger policy reload (requires auth)
16
+ * - /metrics — Prometheus metrics (can be auth-gated or public via DASHBOARD_METRICS_PUBLIC=true)
17
+ *
18
+ * v1.2: Integrated DashboardAuth for JWT/API key authentication, CSRF protection.
19
+ */
20
+ export async function startDashboardServer(port = 4000, policyWatcher, dashboardAuth) {
21
+ if (process.env['DASHBOARD_ENABLED'] !== 'true') {
22
+ Logger.debug('[dashboard] Dashboard server not enabled (set DASHBOARD_ENABLED=true)');
23
+ return { auth: dashboardAuth || new DashboardAuth({ enabled: false }), server: createServer((_req, res) => {
24
+ res.writeHead(200);
25
+ res.end();
26
+ }) };
27
+ }
28
+ const auth = dashboardAuth || new DashboardAuth();
29
+ const authEnabled = auth.isEnabled();
30
+ if (authEnabled) {
31
+ Logger.info('[dashboard] Dashboard authentication enabled');
32
+ }
33
+ else {
34
+ Logger.info('[dashboard] Dashboard running without authentication (set DASHBOARD_AUTH_ENABLED=true)');
35
+ }
36
+ const dashboardHtml = readFileSync(resolve(__dirname, '..', '..', 'deploy', 'dashboard.html'), 'utf-8');
37
+ /** Read JSON body from request */
38
+ async function readBody(req) {
39
+ return new Promise((resolve, reject) => {
40
+ let data = '';
41
+ req.on('data', (chunk) => { data += chunk.toString(); });
42
+ req.on('end', () => {
43
+ try {
44
+ resolve(data ? JSON.parse(data) : {});
45
+ }
46
+ catch {
47
+ resolve({});
48
+ }
49
+ });
50
+ req.on('error', reject);
51
+ });
52
+ }
53
+ /** Parse form-encoded body from request */
54
+ async function readFormBody(req) {
55
+ return new Promise((resolve) => {
56
+ let data = '';
57
+ req.on('data', (chunk) => { data += chunk.toString(); });
58
+ req.on('end', () => {
59
+ const result = {};
60
+ if (data) {
61
+ try {
62
+ const params = new URLSearchParams(data);
63
+ for (const [key, value] of params) {
64
+ result[key] = value;
65
+ }
66
+ }
67
+ catch {
68
+ // Ignore parse errors
69
+ }
70
+ }
71
+ resolve(result);
72
+ });
73
+ });
74
+ }
75
+ /** Get client IP for rate limiting */
76
+ function getClientIp(req) {
77
+ const forwarded = req.headers['x-forwarded-for'];
78
+ if (forwarded) {
79
+ const first = Array.isArray(forwarded) ? forwarded[0] : forwarded.split(',')[0];
80
+ return (first || '').trim();
81
+ }
82
+ return req.socket?.remoteAddress || 'unknown';
83
+ }
84
+ /** Write JSON response */
85
+ function writeJson(res, status, data) {
86
+ res.writeHead(status, { 'Content-Type': 'application/json' });
87
+ res.end(JSON.stringify(data));
88
+ }
89
+ const server = createServer(async (req, res) => {
90
+ const url = req.url || '/';
91
+ const method = req.method || 'GET';
92
+ // ── CORS preflight ─────────────────────────────────────
93
+ if (method === 'OPTIONS') {
94
+ res.writeHead(204, {
95
+ 'Access-Control-Allow-Origin': '*',
96
+ 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
97
+ 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-API-Key',
98
+ });
99
+ res.end();
100
+ return;
101
+ }
102
+ // ── CORS headers on all responses ─────────────────────
103
+ const setCors = () => {
104
+ res.setHeader('Access-Control-Allow-Origin', '*');
105
+ };
106
+ try {
107
+ // ── Login page (only when JWT auth is enabled, no API key set) ──
108
+ if (url === '/login' && method === 'GET') {
109
+ setCors();
110
+ if (auth.isEnabled() && auth.hasJwtSessionAuth()) {
111
+ res.writeHead(200, { 'Content-Type': 'text/html' });
112
+ res.end(auth.getLoginPageHtml());
113
+ }
114
+ else {
115
+ res.writeHead(302, { 'Location': '/' });
116
+ res.end();
117
+ }
118
+ return;
119
+ }
120
+ // ── Login API endpoint ──────────────────────────────
121
+ if (url === '/api/login' && method === 'POST') {
122
+ setCors();
123
+ const ip = getClientIp(req);
124
+ const contentType = req.headers['content-type'] || '';
125
+ let body;
126
+ if (contentType.includes('application/x-www-form-urlencoded')) {
127
+ body = await readFormBody(req);
128
+ }
129
+ else {
130
+ body = await readBody(req);
131
+ }
132
+ const result = auth.login({
133
+ url,
134
+ headers: req.headers,
135
+ body: {
136
+ username: body.username,
137
+ password: body.password,
138
+ api_key: body.api_key,
139
+ },
140
+ ip,
141
+ });
142
+ if (result.success && req.headers['content-type']?.includes('form')) {
143
+ // Form submission — redirect to dashboard with token
144
+ res.writeHead(302, {
145
+ 'Location': `/?api_key=${encodeURIComponent(result.token)}`,
146
+ 'Set-Cookie': `mcp_guardian_session=${result.token}; Path=/; HttpOnly; SameSite=Strict; Max-Age=3600`,
147
+ });
148
+ res.end();
149
+ return;
150
+ }
151
+ if (result.success) {
152
+ writeJson(res, 200, { success: true, token: result.token });
153
+ }
154
+ else {
155
+ writeJson(res, 401, { success: false, error: result.error });
156
+ }
157
+ return;
158
+ }
159
+ // ── Auth check for all other routes ─────────────────
160
+ const authResult = auth.authenticate({ url, headers: req.headers, method });
161
+ if (!authResult.authenticated) {
162
+ setCors();
163
+ if (req.headers['accept']?.includes('text/html')) {
164
+ // Browser request — redirect to login
165
+ res.writeHead(302, { 'Location': '/login' });
166
+ res.end();
167
+ }
168
+ else {
169
+ writeJson(res, 401, { error: 'Authentication required', reason: authResult.reason });
170
+ }
171
+ return;
172
+ }
173
+ // ── Dashboard HTML ──────────────────────────────────
174
+ if (url === '/' || url === '/dashboard.html') {
175
+ setCors();
176
+ res.writeHead(200, { 'Content-Type': 'text/html' });
177
+ res.end(dashboardHtml);
178
+ return;
179
+ }
180
+ // ── Policy API ──────────────────────────────────────
181
+ if (url === '/api/policy' && method === 'GET') {
182
+ setCors();
183
+ if (!policyWatcher || !policyWatcher.get()) {
184
+ writeJson(res, 404, { error: 'No active policy. Start proxy with --policy flag.' });
185
+ return;
186
+ }
187
+ writeJson(res, 200, { mode: policyWatcher.get().getMode(), rules: 'Policy engine active (YAML view available on filesystem)' });
188
+ return;
189
+ }
190
+ if (url === '/api/policy/reload' && method === 'POST') {
191
+ setCors();
192
+ if (!policyWatcher) {
193
+ writeJson(res, 404, { error: 'Policy watcher not configured' });
194
+ return;
195
+ }
196
+ writeJson(res, 200, { status: 'ok', message: 'Policy watcher is active. File changes are auto-detected.' });
197
+ return;
198
+ }
199
+ // ── Prometheus /metrics proxy ──────────────────────
200
+ if (url === '/metrics') {
201
+ setCors();
202
+ const metricsPublic = process.env['DASHBOARD_METRICS_PUBLIC'] === 'true';
203
+ // Re-check auth for metrics unless public
204
+ if (metricsPublic || authResult.authenticated) {
205
+ try {
206
+ const metricsPort = process.env['METRICS_PORT'] || '9090';
207
+ const metricsRes = await fetch(`http://localhost:${metricsPort}/metrics`);
208
+ if (!metricsRes.ok)
209
+ throw new Error(`Metrics server returned ${metricsRes.status}`);
210
+ const text = await metricsRes.text();
211
+ res.writeHead(200, {
212
+ 'Content-Type': 'text/plain; version=0.0.4; charset=utf-8',
213
+ 'Access-Control-Allow-Origin': '*',
214
+ });
215
+ res.end(text);
216
+ }
217
+ catch {
218
+ writeJson(res, 200, { error: 'Metrics not available. Ensure METRICS_ENABLED=true and proxy is running.' });
219
+ }
220
+ }
221
+ else {
222
+ writeJson(res, 401, { error: 'Authentication required for metrics' });
223
+ }
224
+ return;
225
+ }
226
+ // ── Auth status check ───────────────────────────────
227
+ if (url === '/api/auth/status' && method === 'GET') {
228
+ setCors();
229
+ writeJson(res, 200, { authenticated: true, identity: authResult.identity, authEnabled });
230
+ return;
231
+ }
232
+ // ── Logout ──────────────────────────────────────────
233
+ if (url === '/api/logout' && method === 'POST') {
234
+ setCors();
235
+ const authHeader = req.headers['authorization'];
236
+ if (authHeader) {
237
+ const match = authHeader.match(/^Bearer\s+(.+)$/i);
238
+ if (match)
239
+ auth.logout(match[1]);
240
+ }
241
+ writeJson(res, 200, { status: 'ok', message: 'Logged out' });
242
+ return;
243
+ }
244
+ // ── 404 ──────────────────────────────────────────────
245
+ setCors();
246
+ writeJson(res, 404, { error: 'Not found' });
247
+ }
248
+ catch (err) {
249
+ setCors();
250
+ writeJson(res, 500, { error: err?.message || 'Internal error' });
251
+ }
252
+ });
253
+ server.listen(port, () => {
254
+ Logger.info(`[dashboard] Dashboard available at http://localhost:${port}${authEnabled ? ' (auth enabled)' : ''}`);
255
+ });
256
+ return { auth, server };
257
+ }
258
+ //# sourceMappingURL=dashboard-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-server.js","sourceRoot":"","sources":["../../src/utils/dashboard-server.ts"],"names":[],"mappings":"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"}