@neurosec/sentry 1.0.20 → 1.1.1

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 (192) hide show
  1. package/README.md +4 -0
  2. package/dist/api-auth.d.ts +31 -0
  3. package/dist/api-auth.d.ts.map +1 -0
  4. package/dist/api-auth.js +105 -0
  5. package/dist/api-auth.js.map +1 -0
  6. package/dist/api-auth.test.d.ts +2 -0
  7. package/dist/api-auth.test.d.ts.map +1 -0
  8. package/dist/api-auth.test.js +89 -0
  9. package/dist/api-auth.test.js.map +1 -0
  10. package/dist/api.d.ts +8 -7
  11. package/dist/api.d.ts.map +1 -1
  12. package/dist/api.js +141 -134
  13. package/dist/api.js.map +1 -1
  14. package/dist/cli.d.ts +1 -1
  15. package/dist/cli.d.ts.map +1 -1
  16. package/dist/cli.js +107 -14
  17. package/dist/cli.js.map +1 -1
  18. package/dist/cli.test.d.ts +2 -0
  19. package/dist/cli.test.d.ts.map +1 -0
  20. package/dist/cli.test.js +68 -0
  21. package/dist/cli.test.js.map +1 -0
  22. package/dist/config.d.ts +30 -0
  23. package/dist/config.d.ts.map +1 -1
  24. package/dist/config.js +68 -2
  25. package/dist/config.js.map +1 -1
  26. package/dist/config.test.d.ts +2 -0
  27. package/dist/config.test.d.ts.map +1 -0
  28. package/dist/config.test.js +121 -0
  29. package/dist/config.test.js.map +1 -0
  30. package/dist/discovery-win.d.ts +4 -0
  31. package/dist/discovery-win.d.ts.map +1 -0
  32. package/dist/discovery-win.js +153 -0
  33. package/dist/discovery-win.js.map +1 -0
  34. package/dist/discovery.d.ts.map +1 -1
  35. package/dist/discovery.js +23 -97
  36. package/dist/discovery.js.map +1 -1
  37. package/dist/discovery.test.js +18 -109
  38. package/dist/discovery.test.js.map +1 -1
  39. package/dist/enforcement/file-monitor.d.ts +9 -0
  40. package/dist/enforcement/file-monitor.d.ts.map +1 -1
  41. package/dist/enforcement/file-monitor.js +9 -2
  42. package/dist/enforcement/file-monitor.js.map +1 -1
  43. package/dist/enforcement/network-monitor.d.ts.map +1 -1
  44. package/dist/enforcement/network-monitor.js +350 -9
  45. package/dist/enforcement/network-monitor.js.map +1 -1
  46. package/dist/enforcement/network-monitor.test.d.ts +2 -0
  47. package/dist/enforcement/network-monitor.test.d.ts.map +1 -0
  48. package/dist/enforcement/network-monitor.test.js +52 -0
  49. package/dist/enforcement/network-monitor.test.js.map +1 -0
  50. package/dist/enforcement/policy-executor.d.ts +24 -1
  51. package/dist/enforcement/policy-executor.d.ts.map +1 -1
  52. package/dist/enforcement/policy-executor.js +213 -69
  53. package/dist/enforcement/policy-executor.js.map +1 -1
  54. package/dist/enforcement/policy-executor.test.d.ts +2 -0
  55. package/dist/enforcement/policy-executor.test.d.ts.map +1 -0
  56. package/dist/enforcement/policy-executor.test.js +46 -0
  57. package/dist/enforcement/policy-executor.test.js.map +1 -0
  58. package/dist/enforcement/target-validator.d.ts +37 -0
  59. package/dist/enforcement/target-validator.d.ts.map +1 -0
  60. package/dist/enforcement/target-validator.js +0 -0
  61. package/dist/enforcement/target-validator.js.map +1 -0
  62. package/dist/enforcement/target-validator.test.d.ts +2 -0
  63. package/dist/enforcement/target-validator.test.d.ts.map +1 -0
  64. package/dist/enforcement/target-validator.test.js +103 -0
  65. package/dist/enforcement/target-validator.test.js.map +1 -0
  66. package/dist/http-client.d.ts +35 -0
  67. package/dist/http-client.d.ts.map +1 -0
  68. package/dist/http-client.js +179 -0
  69. package/dist/http-client.js.map +1 -0
  70. package/dist/http-client.test.d.ts +2 -0
  71. package/dist/http-client.test.d.ts.map +1 -0
  72. package/dist/http-client.test.js +175 -0
  73. package/dist/http-client.test.js.map +1 -0
  74. package/dist/index.js +190 -114
  75. package/dist/index.js.map +1 -1
  76. package/dist/launcher.d.ts +33 -0
  77. package/dist/launcher.d.ts.map +1 -0
  78. package/dist/launcher.js +425 -0
  79. package/dist/launcher.js.map +1 -0
  80. package/dist/launcher.test.d.ts +2 -0
  81. package/dist/launcher.test.d.ts.map +1 -0
  82. package/dist/launcher.test.js +109 -0
  83. package/dist/launcher.test.js.map +1 -0
  84. package/dist/proxy/cert-manager.d.ts +24 -0
  85. package/dist/proxy/cert-manager.d.ts.map +1 -0
  86. package/dist/proxy/cert-manager.js +117 -0
  87. package/dist/proxy/cert-manager.js.map +1 -0
  88. package/dist/proxy/cert-manager.test.d.ts +2 -0
  89. package/dist/proxy/cert-manager.test.d.ts.map +1 -0
  90. package/dist/proxy/cert-manager.test.js +70 -0
  91. package/dist/proxy/cert-manager.test.js.map +1 -0
  92. package/dist/proxy/index.d.ts +61 -0
  93. package/dist/proxy/index.d.ts.map +1 -0
  94. package/dist/proxy/index.js +74 -0
  95. package/dist/proxy/index.js.map +1 -0
  96. package/dist/proxy/policy-enforcer.d.ts +30 -0
  97. package/dist/proxy/policy-enforcer.d.ts.map +1 -0
  98. package/dist/proxy/policy-enforcer.js +143 -0
  99. package/dist/proxy/policy-enforcer.js.map +1 -0
  100. package/dist/proxy/proxy-server.d.ts +42 -0
  101. package/dist/proxy/proxy-server.d.ts.map +1 -0
  102. package/dist/proxy/proxy-server.js +652 -0
  103. package/dist/proxy/proxy-server.js.map +1 -0
  104. package/dist/proxy/redaction-engine.d.ts +4 -0
  105. package/dist/proxy/redaction-engine.d.ts.map +1 -0
  106. package/dist/proxy/redaction-engine.js +50 -0
  107. package/dist/proxy/redaction-engine.js.map +1 -0
  108. package/dist/proxy/response-redaction.test.d.ts +2 -0
  109. package/dist/proxy/response-redaction.test.d.ts.map +1 -0
  110. package/dist/proxy/response-redaction.test.js +125 -0
  111. package/dist/proxy/response-redaction.test.js.map +1 -0
  112. package/dist/proxy/threat-engine.d.ts +22 -0
  113. package/dist/proxy/threat-engine.d.ts.map +1 -0
  114. package/dist/proxy/threat-engine.js +291 -0
  115. package/dist/proxy/threat-engine.js.map +1 -0
  116. package/dist/proxy/threat-engine.test.d.ts +2 -0
  117. package/dist/proxy/threat-engine.test.d.ts.map +1 -0
  118. package/dist/proxy/threat-engine.test.js +27 -0
  119. package/dist/proxy/threat-engine.test.js.map +1 -0
  120. package/dist/redirect/env-injector.d.ts +72 -0
  121. package/dist/redirect/env-injector.d.ts.map +1 -0
  122. package/dist/redirect/env-injector.js +177 -0
  123. package/dist/redirect/env-injector.js.map +1 -0
  124. package/dist/redirect/env-injector.test.d.ts +2 -0
  125. package/dist/redirect/env-injector.test.d.ts.map +1 -0
  126. package/dist/redirect/env-injector.test.js +91 -0
  127. package/dist/redirect/env-injector.test.js.map +1 -0
  128. package/dist/redirect/index.d.ts +3 -0
  129. package/dist/redirect/index.d.ts.map +1 -0
  130. package/dist/redirect/index.js +8 -0
  131. package/dist/redirect/index.js.map +1 -0
  132. package/dist/redirect/platform-redirect.d.ts +42 -0
  133. package/dist/redirect/platform-redirect.d.ts.map +1 -0
  134. package/dist/redirect/platform-redirect.js +229 -0
  135. package/dist/redirect/platform-redirect.js.map +1 -0
  136. package/dist/redirect/platform-redirect.test.d.ts +2 -0
  137. package/dist/redirect/platform-redirect.test.d.ts.map +1 -0
  138. package/dist/redirect/platform-redirect.test.js +76 -0
  139. package/dist/redirect/platform-redirect.test.js.map +1 -0
  140. package/dist/sandbox/index.d.ts +23 -2
  141. package/dist/sandbox/index.d.ts.map +1 -1
  142. package/dist/sandbox/index.js +24 -7
  143. package/dist/sandbox/index.js.map +1 -1
  144. package/dist/sandbox/linux-sandbox.d.ts +13 -2
  145. package/dist/sandbox/linux-sandbox.d.ts.map +1 -1
  146. package/dist/sandbox/linux-sandbox.js +61 -27
  147. package/dist/sandbox/linux-sandbox.js.map +1 -1
  148. package/dist/sandbox/macos-sandbox.d.ts +15 -4
  149. package/dist/sandbox/macos-sandbox.d.ts.map +1 -1
  150. package/dist/sandbox/macos-sandbox.js +36 -18
  151. package/dist/sandbox/macos-sandbox.js.map +1 -1
  152. package/dist/sandbox/sandbox-result.test.d.ts +2 -0
  153. package/dist/sandbox/sandbox-result.test.d.ts.map +1 -0
  154. package/dist/sandbox/sandbox-result.test.js +87 -0
  155. package/dist/sandbox/sandbox-result.test.js.map +1 -0
  156. package/dist/sandbox/windows-sandbox.d.ts +34 -0
  157. package/dist/sandbox/windows-sandbox.d.ts.map +1 -0
  158. package/dist/sandbox/windows-sandbox.js +161 -0
  159. package/dist/sandbox/windows-sandbox.js.map +1 -0
  160. package/dist/setup.d.ts.map +1 -1
  161. package/dist/setup.js +33 -43
  162. package/dist/setup.js.map +1 -1
  163. package/dist/skill-authz/skill-evaluator.d.ts +30 -0
  164. package/dist/skill-authz/skill-evaluator.d.ts.map +1 -1
  165. package/dist/skill-authz/skill-evaluator.js +161 -30
  166. package/dist/skill-authz/skill-evaluator.js.map +1 -1
  167. package/dist/skill-authz/skill-evaluator.test.d.ts +2 -0
  168. package/dist/skill-authz/skill-evaluator.test.d.ts.map +1 -0
  169. package/dist/skill-authz/skill-evaluator.test.js +127 -0
  170. package/dist/skill-authz/skill-evaluator.test.js.map +1 -0
  171. package/dist/telemetry.d.ts +2 -8
  172. package/dist/telemetry.d.ts.map +1 -1
  173. package/dist/telemetry.js +17 -147
  174. package/dist/telemetry.js.map +1 -1
  175. package/dist/types.d.ts +48 -105
  176. package/dist/types.d.ts.map +1 -1
  177. package/dist/types.js +34 -1
  178. package/dist/types.js.map +1 -1
  179. package/package.json +7 -3
  180. package/scripts/install-sentry-windows.ps1 +217 -0
  181. package/dist/action-logger.d.ts +0 -40
  182. package/dist/action-logger.d.ts.map +0 -1
  183. package/dist/action-logger.js +0 -252
  184. package/dist/action-logger.js.map +0 -1
  185. package/dist/agent-registry.d.ts +0 -24
  186. package/dist/agent-registry.d.ts.map +0 -1
  187. package/dist/agent-registry.js +0 -176
  188. package/dist/agent-registry.js.map +0 -1
  189. package/dist/anomaly-detector.d.ts +0 -26
  190. package/dist/anomaly-detector.d.ts.map +0 -1
  191. package/dist/anomaly-detector.js +0 -299
  192. package/dist/anomaly-detector.js.map +0 -1
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ensureProxyCertificate = ensureProxyCertificate;
7
+ /**
8
+ * On-disk self-signed certificate provisioning for the Sentry HTTPS proxy.
9
+ *
10
+ * Why this exists (S-C8): the previous code defaulted `interceptHttps: false`
11
+ * and required operators to provision certs by hand at /etc/neuroshield/proxy-cert.pem.
12
+ * Most operators didn't, so the proxy received zero HTTPS traffic and the
13
+ * threat engine + redactor never ran on real LLM requests.
14
+ *
15
+ * Behavior:
16
+ * - On first start, if certPath / keyPath don't exist, generate a self-signed
17
+ * 2048-bit RSA cert via `openssl req -x509`, valid 365 days, with SANs
18
+ * for `localhost`, `127.0.0.1`, `*.openai.com`, `*.anthropic.com`,
19
+ * `*.googleapis.com`, etc. Persist to stateDir/proxy-cert.{pem,key}.
20
+ * - Cert is written 0600. Daemon owner only.
21
+ * - Each call returns { certPath, keyPath, generated, fingerprintSha256 }
22
+ * so operators / the Sentry CLI can echo the fingerprint to trust on
23
+ * client machines.
24
+ * - Clients must trust this CA for HTTPS interception to work — the cert
25
+ * fingerprint is logged once at start so operators can pin it.
26
+ *
27
+ * Trust model: the cert is the LOCAL ca. We do NOT push it into system
28
+ * trust stores. Operators decide whether to add it manually or use the
29
+ * agent-launcher wrapping that sets NODE_EXTRA_CA_CERTS.
30
+ */
31
+ const fs_1 = __importDefault(require("fs"));
32
+ const path_1 = __importDefault(require("path"));
33
+ const child_process_1 = require("child_process");
34
+ const crypto_1 = require("crypto");
35
+ const logger_1 = require("../logger");
36
+ const DEFAULT_SANS = [
37
+ 'localhost',
38
+ '127.0.0.1',
39
+ '::1',
40
+ ];
41
+ /**
42
+ * Ensure a usable cert/key pair exists. Returns the paths plus a SHA-256
43
+ * fingerprint suitable for client-side pinning.
44
+ *
45
+ * Idempotent: if files already exist AND parse as a valid cert, leaves them
46
+ * alone. Otherwise generates a new self-signed cert via openssl.
47
+ */
48
+ function ensureProxyCertificate(opts) {
49
+ const existing = readIfValid(opts.certPath, opts.keyPath);
50
+ if (existing)
51
+ return { ...existing, generated: false };
52
+ if (!hasOpenssl()) {
53
+ throw new Error('openssl(1) is required to provision the HTTPS proxy cert; install it or supply --certPath/--keyPath');
54
+ }
55
+ // Build SAN list — include the operator's extras + defaults.
56
+ const sansFlat = [...new Set([...DEFAULT_SANS, ...(opts.extraSans ?? [])])];
57
+ const sanString = sansFlat
58
+ .map((s) => /^[0-9.]+$|^[0-9a-f:]+$/i.test(s) ? `IP:${s}` : `DNS:${s}`)
59
+ .join(',');
60
+ fs_1.default.mkdirSync(path_1.default.dirname(opts.certPath), { recursive: true });
61
+ fs_1.default.mkdirSync(path_1.default.dirname(opts.keyPath), { recursive: true });
62
+ (0, child_process_1.execFileSync)('openssl', [
63
+ 'req', '-x509',
64
+ '-newkey', 'rsa:2048',
65
+ '-nodes',
66
+ '-keyout', opts.keyPath,
67
+ '-out', opts.certPath,
68
+ '-days', String(opts.validityDays ?? 365),
69
+ '-subj', '/CN=NeuroShield Sentry Local CA',
70
+ '-addext', `subjectAltName=${sanString}`,
71
+ ], { stdio: 'ignore', timeout: 30000 });
72
+ try {
73
+ fs_1.default.chmodSync(opts.keyPath, 0o600);
74
+ }
75
+ catch { /* best effort */ }
76
+ try {
77
+ fs_1.default.chmodSync(opts.certPath, 0o644);
78
+ }
79
+ catch { /* best effort */ }
80
+ const written = readIfValid(opts.certPath, opts.keyPath);
81
+ if (!written) {
82
+ throw new Error('Cert provisioning succeeded but the resulting files failed to parse');
83
+ }
84
+ logger_1.logger.info('Sentry HTTPS proxy cert generated', {
85
+ certPath: opts.certPath,
86
+ keyPath: opts.keyPath,
87
+ fingerprintSha256: written.fingerprintSha256,
88
+ notAfter: written.notAfter,
89
+ sans: sansFlat,
90
+ hint: 'Trust this cert on agent hosts (e.g. NODE_EXTRA_CA_CERTS) to enable HTTPS interception',
91
+ });
92
+ return { ...written, generated: true };
93
+ }
94
+ function readIfValid(certPath, keyPath) {
95
+ try {
96
+ if (!fs_1.default.existsSync(certPath) || !fs_1.default.existsSync(keyPath))
97
+ return null;
98
+ const certPem = fs_1.default.readFileSync(certPath, 'utf8');
99
+ const x509 = new crypto_1.X509Certificate(certPem);
100
+ const fingerprintSha256 = (0, crypto_1.createHash)('sha256').update(x509.raw).digest('hex').toUpperCase();
101
+ const notAfter = x509.validTo;
102
+ return { certPath, keyPath, fingerprintSha256, notAfter };
103
+ }
104
+ catch {
105
+ return null;
106
+ }
107
+ }
108
+ function hasOpenssl() {
109
+ try {
110
+ (0, child_process_1.execFileSync)('openssl', ['version'], { stdio: 'ignore', timeout: 2000 });
111
+ return true;
112
+ }
113
+ catch {
114
+ return false;
115
+ }
116
+ }
117
+ //# sourceMappingURL=cert-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cert-manager.js","sourceRoot":"","sources":["../../src/proxy/cert-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cert-manager.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cert-manager.test.d.ts","sourceRoot":"","sources":["../../src/proxy/cert-manager.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const vitest_1 = require("vitest");
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const os_1 = __importDefault(require("os"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const child_process_1 = require("child_process");
11
+ const cert_manager_1 = require("./cert-manager");
12
+ function hasOpenssl() {
13
+ try {
14
+ (0, child_process_1.execFileSync)('openssl', ['version'], { stdio: 'ignore' });
15
+ return true;
16
+ }
17
+ catch {
18
+ return false;
19
+ }
20
+ }
21
+ function tmpdir() {
22
+ return fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'sentry-cert-'));
23
+ }
24
+ (0, vitest_1.describe)('ensureProxyCertificate (S-C8)', () => {
25
+ let dir;
26
+ (0, vitest_1.beforeEach)(() => { dir = tmpdir(); });
27
+ (0, vitest_1.it)('generates a new cert/key when neither exists', () => {
28
+ if (!hasOpenssl())
29
+ return; // CI without openssl
30
+ const certPath = path_1.default.join(dir, 'cert.pem');
31
+ const keyPath = path_1.default.join(dir, 'key.pem');
32
+ const result = (0, cert_manager_1.ensureProxyCertificate)({ certPath, keyPath });
33
+ (0, vitest_1.expect)(result.generated).toBe(true);
34
+ (0, vitest_1.expect)(fs_1.default.existsSync(certPath)).toBe(true);
35
+ (0, vitest_1.expect)(fs_1.default.existsSync(keyPath)).toBe(true);
36
+ (0, vitest_1.expect)(result.fingerprintSha256).toMatch(/^[A-F0-9]{64}$/);
37
+ (0, vitest_1.expect)(result.notAfter).toBeTruthy();
38
+ });
39
+ (0, vitest_1.it)('is idempotent: re-running returns the existing cert without regenerating', () => {
40
+ if (!hasOpenssl())
41
+ return;
42
+ const certPath = path_1.default.join(dir, 'cert.pem');
43
+ const keyPath = path_1.default.join(dir, 'key.pem');
44
+ const first = (0, cert_manager_1.ensureProxyCertificate)({ certPath, keyPath });
45
+ const second = (0, cert_manager_1.ensureProxyCertificate)({ certPath, keyPath });
46
+ (0, vitest_1.expect)(second.generated).toBe(false);
47
+ (0, vitest_1.expect)(second.fingerprintSha256).toBe(first.fingerprintSha256);
48
+ });
49
+ (0, vitest_1.it)('regenerates if the existing cert is malformed', () => {
50
+ if (!hasOpenssl())
51
+ return;
52
+ const certPath = path_1.default.join(dir, 'cert.pem');
53
+ const keyPath = path_1.default.join(dir, 'key.pem');
54
+ fs_1.default.writeFileSync(certPath, 'not a cert');
55
+ fs_1.default.writeFileSync(keyPath, 'not a key');
56
+ const result = (0, cert_manager_1.ensureProxyCertificate)({ certPath, keyPath });
57
+ (0, vitest_1.expect)(result.generated).toBe(true);
58
+ (0, vitest_1.expect)(result.fingerprintSha256).toMatch(/^[A-F0-9]{64}$/);
59
+ });
60
+ (0, vitest_1.it)('writes the private key 0600', () => {
61
+ if (!hasOpenssl())
62
+ return;
63
+ const certPath = path_1.default.join(dir, 'cert.pem');
64
+ const keyPath = path_1.default.join(dir, 'key.pem');
65
+ (0, cert_manager_1.ensureProxyCertificate)({ certPath, keyPath });
66
+ const mode = fs_1.default.statSync(keyPath).mode & 0o077;
67
+ (0, vitest_1.expect)(mode).toBe(0);
68
+ });
69
+ });
70
+ //# sourceMappingURL=cert-manager.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cert-manager.test.js","sourceRoot":"","sources":["../../src/proxy/cert-manager.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ export { LLMProxyServer } from './proxy-server';
2
+ export { PolicyEnforcer } from './policy-enforcer';
3
+ export { ThreatEngine } from './threat-engine';
4
+ export { RedactionEngine } from './redaction-engine';
5
+ export declare const DEFAULT_POLICIES: ({
6
+ id: string;
7
+ name: string;
8
+ enabled: boolean;
9
+ priority: number;
10
+ action: "block";
11
+ threatTypes: string[];
12
+ minSeverity: string;
13
+ minConfidence: number;
14
+ direction: "input";
15
+ description: string;
16
+ } | {
17
+ id: string;
18
+ name: string;
19
+ enabled: boolean;
20
+ priority: number;
21
+ action: "block";
22
+ threatTypes: string[];
23
+ minSeverity: string;
24
+ minConfidence: number;
25
+ direction: "output";
26
+ description: string;
27
+ } | {
28
+ id: string;
29
+ name: string;
30
+ enabled: boolean;
31
+ priority: number;
32
+ action: "redact";
33
+ threatTypes: string[];
34
+ minSeverity: string;
35
+ minConfidence: number;
36
+ direction: "output";
37
+ description: string;
38
+ } | {
39
+ id: string;
40
+ name: string;
41
+ enabled: boolean;
42
+ priority: number;
43
+ action: "warn";
44
+ threatTypes: string[];
45
+ minSeverity: string;
46
+ minConfidence: number;
47
+ direction: "input";
48
+ description: string;
49
+ } | {
50
+ id: string;
51
+ name: string;
52
+ enabled: boolean;
53
+ priority: number;
54
+ action: "block";
55
+ threatTypes: string[];
56
+ minSeverity: string;
57
+ minConfidence: number;
58
+ direction: "both";
59
+ description: string;
60
+ })[];
61
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/proxy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA6D5B,CAAC"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_POLICIES = exports.RedactionEngine = exports.ThreatEngine = exports.PolicyEnforcer = exports.LLMProxyServer = void 0;
4
+ var proxy_server_1 = require("./proxy-server");
5
+ Object.defineProperty(exports, "LLMProxyServer", { enumerable: true, get: function () { return proxy_server_1.LLMProxyServer; } });
6
+ var policy_enforcer_1 = require("./policy-enforcer");
7
+ Object.defineProperty(exports, "PolicyEnforcer", { enumerable: true, get: function () { return policy_enforcer_1.PolicyEnforcer; } });
8
+ var threat_engine_1 = require("./threat-engine");
9
+ Object.defineProperty(exports, "ThreatEngine", { enumerable: true, get: function () { return threat_engine_1.ThreatEngine; } });
10
+ var redaction_engine_1 = require("./redaction-engine");
11
+ Object.defineProperty(exports, "RedactionEngine", { enumerable: true, get: function () { return redaction_engine_1.RedactionEngine; } });
12
+ exports.DEFAULT_POLICIES = [
13
+ {
14
+ id: 'default-block-prompt-injection',
15
+ name: 'Block Prompt Injection',
16
+ enabled: true,
17
+ priority: 100,
18
+ action: 'block',
19
+ threatTypes: ['PROMPT_INJECTION', 'JAILBREAK'],
20
+ minSeverity: 'medium',
21
+ minConfidence: 0.7,
22
+ direction: 'input',
23
+ description: 'Blocks prompt injection and jailbreak attempts',
24
+ },
25
+ {
26
+ id: 'default-block-data-leakage',
27
+ name: 'Block Data Leakage',
28
+ enabled: true,
29
+ priority: 90,
30
+ action: 'block',
31
+ threatTypes: ['DATA_LEAKAGE', 'MODEL_THEFT'],
32
+ minSeverity: 'high',
33
+ minConfidence: 0.8,
34
+ direction: 'output',
35
+ description: 'Blocks data leakage and model theft in responses',
36
+ },
37
+ {
38
+ id: 'default-redact-pii',
39
+ name: 'Redact PII',
40
+ enabled: true,
41
+ priority: 80,
42
+ action: 'redact',
43
+ threatTypes: ['PII_EXPOSURE'],
44
+ minSeverity: 'low',
45
+ minConfidence: 0.3,
46
+ direction: 'output',
47
+ description: 'Redacts personally identifiable information from responses',
48
+ },
49
+ {
50
+ id: 'default-warn-suspicious',
51
+ name: 'Warn Suspicious Content',
52
+ enabled: true,
53
+ priority: 50,
54
+ action: 'warn',
55
+ threatTypes: ['ANOMALOUS_BEHAVIOR', 'UNAUTHORIZED_ACCESS'],
56
+ minSeverity: 'medium',
57
+ minConfidence: 0.5,
58
+ direction: 'input',
59
+ description: 'Warns on suspicious or unauthorized access patterns',
60
+ },
61
+ {
62
+ id: 'default-block-agent-compromise',
63
+ name: 'Block Agent Compromise',
64
+ enabled: true,
65
+ priority: 110,
66
+ action: 'block',
67
+ threatTypes: ['AGENT_COMPROMISE'],
68
+ minSeverity: 'medium',
69
+ minConfidence: 0.6,
70
+ direction: 'both',
71
+ description: 'Blocks agent compromise attempts',
72
+ },
73
+ ];
74
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/proxy/index.ts"],"names":[],"mappings":";;;AAAA,+CAAgD;AAAvC,8GAAA,cAAc,OAAA;AACvB,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AACrB,uDAAqD;AAA5C,mHAAA,eAAe,OAAA;AAEX,QAAA,gBAAgB,GAAG;IAC9B;QACE,EAAE,EAAE,gCAAgC;QACpC,IAAI,EAAE,wBAAwB;QAC9B,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,GAAG;QACb,MAAM,EAAE,OAAgB;QACxB,WAAW,EAAE,CAAC,kBAAkB,EAAE,WAAW,CAAC;QAC9C,WAAW,EAAE,QAAQ;QACrB,aAAa,EAAE,GAAG;QAClB,SAAS,EAAE,OAAgB;QAC3B,WAAW,EAAE,gDAAgD;KAC9D;IACD;QACE,EAAE,EAAE,4BAA4B;QAChC,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,EAAE;QACZ,MAAM,EAAE,OAAgB;QACxB,WAAW,EAAE,CAAC,cAAc,EAAE,aAAa,CAAC;QAC5C,WAAW,EAAE,MAAM;QACnB,aAAa,EAAE,GAAG;QAClB,SAAS,EAAE,QAAiB;QAC5B,WAAW,EAAE,kDAAkD;KAChE;IACD;QACE,EAAE,EAAE,oBAAoB;QACxB,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,EAAE;QACZ,MAAM,EAAE,QAAiB;QACzB,WAAW,EAAE,CAAC,cAAc,CAAC;QAC7B,WAAW,EAAE,KAAK;QAClB,aAAa,EAAE,GAAG;QAClB,SAAS,EAAE,QAAiB;QAC5B,WAAW,EAAE,4DAA4D;KAC1E;IACD;QACE,EAAE,EAAE,yBAAyB;QAC7B,IAAI,EAAE,yBAAyB;QAC/B,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,EAAE;QACZ,MAAM,EAAE,MAAe;QACvB,WAAW,EAAE,CAAC,oBAAoB,EAAE,qBAAqB,CAAC;QAC1D,WAAW,EAAE,QAAQ;QACrB,aAAa,EAAE,GAAG;QAClB,SAAS,EAAE,OAAgB;QAC3B,WAAW,EAAE,qDAAqD;KACnE;IACD;QACE,EAAE,EAAE,gCAAgC;QACpC,IAAI,EAAE,wBAAwB;QAC9B,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,GAAG;QACb,MAAM,EAAE,OAAgB;QACxB,WAAW,EAAE,CAAC,kBAAkB,CAAC;QACjC,WAAW,EAAE,QAAQ;QACrB,aAAa,EAAE,GAAG;QAClB,SAAS,EAAE,MAAe;QAC1B,WAAW,EAAE,kCAAkC;KAChD;CACF,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { ProxyDecision, ProxyAction } from '../types';
2
+ import { ThreatEngine } from './threat-engine';
3
+ import { RedactionEngine } from './redaction-engine';
4
+ export interface LocalPolicy {
5
+ id: string;
6
+ name: string;
7
+ enabled: boolean;
8
+ priority: number;
9
+ action: ProxyAction;
10
+ threatTypes: string[];
11
+ minSeverity: string;
12
+ minConfidence: number;
13
+ direction: 'input' | 'output' | 'both';
14
+ description?: string;
15
+ }
16
+ export declare class PolicyEnforcer {
17
+ private threatEngine;
18
+ private redactionEngine;
19
+ private policies;
20
+ private mode;
21
+ constructor(threatEngine?: ThreatEngine, redactionEngine?: RedactionEngine);
22
+ /** Exposed for the proxy-server's structure-aware response redaction. */
23
+ getRedactionEngine(): RedactionEngine;
24
+ setMode(mode: 'monitor' | 'enforce' | 'quarantine'): void;
25
+ setPolicies(policies: LocalPolicy[]): void;
26
+ addPolicy(policy: LocalPolicy): void;
27
+ enforce(content: string, direction: 'input' | 'output'): ProxyDecision;
28
+ private matchesPolicy;
29
+ }
30
+ //# sourceMappingURL=policy-enforcer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-enforcer.d.ts","sourceRoot":"","sources":["../../src/proxy/policy-enforcer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAqB,WAAW,EAAE,MAAM,UAAU,CAAC;AACzE,OAAO,EAAE,YAAY,EAAgB,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAWD,qBAAa,cAAc;IACzB,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAuC;IACvD,OAAO,CAAC,IAAI,CAAmD;gBAEnD,YAAY,CAAC,EAAE,YAAY,EAAE,eAAe,CAAC,EAAE,eAAe;IAK1E,yEAAyE;IACzE,kBAAkB,IAAI,eAAe;IAIrC,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,IAAI;IAKzD,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,IAAI;IAU1C,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAMpC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,QAAQ,GAAG,aAAa;IA+FtE,OAAO,CAAC,aAAa;CAatB"}
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PolicyEnforcer = void 0;
4
+ const threat_engine_1 = require("./threat-engine");
5
+ const redaction_engine_1 = require("./redaction-engine");
6
+ const logger_1 = require("../logger");
7
+ const ACTION_PRIORITY = {
8
+ block: 4,
9
+ redact: 3,
10
+ warn: 2,
11
+ allow: 1,
12
+ };
13
+ const FORCE_BLOCK_THREATS = new Set(['PROMPT_INJECTION', 'JAILBREAK', 'MODEL_THEFT', 'AGENT_COMPROMISE']);
14
+ class PolicyEnforcer {
15
+ constructor(threatEngine, redactionEngine) {
16
+ this.policies = new Map();
17
+ this.mode = 'enforce';
18
+ this.threatEngine = threatEngine ?? new threat_engine_1.ThreatEngine();
19
+ this.redactionEngine = redactionEngine ?? new redaction_engine_1.RedactionEngine();
20
+ }
21
+ /** Exposed for the proxy-server's structure-aware response redaction. */
22
+ getRedactionEngine() {
23
+ return this.redactionEngine;
24
+ }
25
+ setMode(mode) {
26
+ this.mode = mode;
27
+ logger_1.logger.info('Policy enforcer mode set', { mode });
28
+ }
29
+ setPolicies(policies) {
30
+ this.policies.clear();
31
+ for (const p of policies) {
32
+ if (p.enabled) {
33
+ this.policies.set(p.id, p);
34
+ }
35
+ }
36
+ logger_1.logger.info('Policies updated', { count: this.policies.size });
37
+ }
38
+ addPolicy(policy) {
39
+ if (policy.enabled) {
40
+ this.policies.set(policy.id, policy);
41
+ }
42
+ }
43
+ enforce(content, direction) {
44
+ const analysis = this.threatEngine.analyze(content, direction);
45
+ if (!analysis.detected) {
46
+ return {
47
+ action: 'allow',
48
+ reason: 'No threats detected',
49
+ triggeredRules: [],
50
+ threats: [],
51
+ riskScore: 0,
52
+ };
53
+ }
54
+ // In monitor mode, always allow but report
55
+ if (this.mode === 'monitor') {
56
+ return {
57
+ action: 'allow',
58
+ reason: `[MONITOR] Detected ${analysis.signals.length} threat(s)`,
59
+ triggeredRules: analysis.signals.map(s => s.type),
60
+ threats: analysis.signals,
61
+ riskScore: analysis.riskScore,
62
+ };
63
+ }
64
+ if (this.mode === 'quarantine') {
65
+ return {
66
+ action: 'block',
67
+ reason: 'Quarantine mode: all threats blocked',
68
+ triggeredRules: analysis.signals.map(s => s.type),
69
+ threats: analysis.signals,
70
+ riskScore: analysis.riskScore,
71
+ };
72
+ }
73
+ // Evaluate against policies
74
+ const sortedPolicies = [...this.policies.values()].sort((a, b) => b.priority - a.priority);
75
+ let finalAction = 'allow';
76
+ let finalReason = 'No matching policy';
77
+ const allTriggered = [];
78
+ for (const policy of sortedPolicies) {
79
+ const matched = this.matchesPolicy(policy, analysis.signals, direction);
80
+ if (matched) {
81
+ allTriggered.push(policy.name || policy.id);
82
+ if (ACTION_PRIORITY[policy.action] > ACTION_PRIORITY[finalAction]) {
83
+ finalAction = policy.action;
84
+ finalReason = `Policy '${policy.name || policy.id}' matched`;
85
+ }
86
+ }
87
+ }
88
+ // If no policy matched but threats exist, apply default based on severity
89
+ if (allTriggered.length === 0 && analysis.signals.length > 0) {
90
+ const hasHighSeverity = analysis.signals.some(s => s.severity === 'high' || s.severity === 'critical');
91
+ if (hasHighSeverity) {
92
+ finalAction = 'block';
93
+ finalReason = 'Auto-blocked: high severity threat detected, no matching policy';
94
+ }
95
+ else {
96
+ finalAction = 'warn';
97
+ finalReason = 'Auto-warn: low severity threat detected, no matching policy';
98
+ }
99
+ }
100
+ // Force-block specific threat types
101
+ const hasForceBlock = analysis.signals.some(s => FORCE_BLOCK_THREATS.has(s.type));
102
+ if (hasForceBlock && finalAction !== 'block') {
103
+ finalAction = 'block';
104
+ finalReason = 'Force-blocked due to dangerous threat type';
105
+ }
106
+ let processedContent = content;
107
+ if (finalAction === 'redact') {
108
+ const threatTypes = analysis.signals.map(s => s.type);
109
+ processedContent = this.redactionEngine.redact(content, threatTypes);
110
+ }
111
+ logger_1.logger.info('Policy enforcement', {
112
+ action: finalAction,
113
+ threats: analysis.signals.length,
114
+ riskScore: analysis.riskScore,
115
+ direction,
116
+ reason: finalReason,
117
+ });
118
+ return {
119
+ action: finalAction,
120
+ reason: finalReason,
121
+ triggeredRules: allTriggered,
122
+ threats: analysis.signals,
123
+ riskScore: analysis.riskScore,
124
+ };
125
+ }
126
+ matchesPolicy(policy, threats, direction) {
127
+ if (policy.direction !== 'both' && policy.direction !== direction)
128
+ return false;
129
+ const severityOrder = { info: 0, low: 1, medium: 2, high: 3, critical: 4 };
130
+ const minSevIdx = severityOrder[policy.minSeverity] ?? 0;
131
+ return threats.some(threat => {
132
+ if (policy.threatTypes.length > 0 && !policy.threatTypes.includes(threat.type))
133
+ return false;
134
+ if (severityOrder[threat.severity] < minSevIdx)
135
+ return false;
136
+ if (threat.confidence < policy.minConfidence)
137
+ return false;
138
+ return true;
139
+ });
140
+ }
141
+ }
142
+ exports.PolicyEnforcer = PolicyEnforcer;
143
+ //# sourceMappingURL=policy-enforcer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-enforcer.js","sourceRoot":"","sources":["../../src/proxy/policy-enforcer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { ProxyConfig } from '../config';
2
+ import { PolicyEnforcer } from './policy-enforcer';
3
+ export declare class LLMProxyServer {
4
+ private server;
5
+ private httpsServer;
6
+ private enforcer;
7
+ private config;
8
+ private activeRequests;
9
+ constructor(config: ProxyConfig, enforcer: PolicyEnforcer);
10
+ start(): Promise<void>;
11
+ stop(): Promise<void>;
12
+ private handleRequest;
13
+ private forwardRequest;
14
+ private forwardStreamingResponse;
15
+ private rewriteStreamingSseLine;
16
+ private allowDecision;
17
+ private isLLMRequest;
18
+ private resolveUpstream;
19
+ private collectBody;
20
+ private filterHeaders;
21
+ /**
22
+ * Apply RedactionEngine to a response body while preserving structure.
23
+ *
24
+ * For chat-completion / messages JSON responses we walk into known textual
25
+ * fields (`choices[].message.content`, `choices[].delta.content`, top-level
26
+ * `content[].text`, Anthropic-style `content[]` blocks) and redact those
27
+ * strings only. For SSE streams (text/event-stream) we redact each `data:`
28
+ * line's JSON payload in place. For anything else we redact the raw body.
29
+ *
30
+ * The previous TODO that returned the body unchanged caused REDACT decisions
31
+ * to silently pass through unredacted (S-C6).
32
+ */
33
+ private applyRedactionToResponse;
34
+ /**
35
+ * Walk a parsed JSON tree and replace text content in known LLM response
36
+ * shapes with redacted versions. We modify in place to preserve the rest
37
+ * of the object structure (function_call, tool_calls, finish_reason, etc.).
38
+ */
39
+ private _walkAndRedactJson;
40
+ private recordProxyEvent;
41
+ }
42
+ //# sourceMappingURL=proxy-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy-server.d.ts","sourceRoot":"","sources":["../../src/proxy/proxy-server.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAcnD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,cAAc,CAA0C;gBAEpD,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc;IAKnD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgEtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAYb,aAAa;YAyHb,cAAc;YAuJd,wBAAwB;IAsHtC,OAAO,CAAC,uBAAuB;IA4B/B,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,eAAe;IAyCvB,OAAO,CAAC,WAAW;IAyBnB,OAAO,CAAC,aAAa;IAgBrB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,wBAAwB;IAqChC;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAgE1B,OAAO,CAAC,gBAAgB;CAczB"}