@devilsdev/rag-pipeline-utils 2.1.12 → 2.2.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 (110) hide show
  1. package/.ragrc.schema.json +218 -0
  2. package/README.md +292 -32
  3. package/bin/cli.js +8 -14
  4. package/dist/index.d.ts +237 -0
  5. package/dist/index.mjs +22 -7
  6. package/package.json +17 -13
  7. package/src/ai/adaptive-retrieval.js +191 -0
  8. package/src/ai/federated-learning.js +214 -0
  9. package/src/ai/federation/federated-learning-coordinator.js +345 -0
  10. package/src/ai/federation.js +76 -0
  11. package/src/ai/index-fixed.js +509 -0
  12. package/src/ai/index.js +33 -0
  13. package/src/ai/model-trainer.js +217 -0
  14. package/src/ai/model-training.js +205 -0
  15. package/src/ai/module-template.js +37 -0
  16. package/src/ai/multimodal/multi-modal-processor.js +345 -0
  17. package/src/ai/multimodal-processing.js +268 -0
  18. package/src/ai/multimodal.js +71 -0
  19. package/src/ai/orchestrator.js +70 -0
  20. package/src/ai/retrieval/adaptive-retrieval-engine.js +398 -0
  21. package/src/ai/retrieval-engine.js +69 -0
  22. package/src/ai/training/model-training-orchestrator.js +228 -0
  23. package/src/ci/workflow-analyzer.js +71 -0
  24. package/src/cli/commands/ai-ml.js +967 -0
  25. package/src/cli/commands/docs.js +228 -0
  26. package/src/cli/commands/dx.js +538 -0
  27. package/src/cli/commands/plugin-hub.js +875 -0
  28. package/src/cli/doctor-command.js +639 -0
  29. package/src/cli/enhanced-cli-commands.js +945 -0
  30. package/src/cli/interactive-wizard.js +997 -0
  31. package/src/cli/plugin-marketplace-commands.js +869 -0
  32. package/src/cli.js +17 -0
  33. package/src/config/enhanced-ragrc-schema.js +632 -0
  34. package/src/config/load-config.js +54 -0
  35. package/src/config/load-plugin-config.js +69 -0
  36. package/src/config/normalize-config.js +105 -0
  37. package/src/config/schema-validator.js +315 -0
  38. package/src/config/validate-plugin-schema.js +35 -0
  39. package/src/config/validate-schema.js +113 -0
  40. package/src/contracts/plugin-contracts.js +33 -0
  41. package/src/core/create-pipeline.js +99 -0
  42. package/src/core/dependency-injection.js +242 -0
  43. package/src/core/observability/event-logger.js +241 -0
  44. package/src/core/observability/instrumented-pipeline.js +609 -0
  45. package/src/core/observability/metrics.js +497 -0
  46. package/src/core/observability/tracing.js +781 -0
  47. package/src/core/performance/benchmark.js +516 -0
  48. package/src/core/performance/parallel-processor.js +240 -0
  49. package/src/core/performance/streaming-safeguards.js +611 -0
  50. package/src/core/pipeline-factory.js +60 -0
  51. package/src/core/plugin-contracts.js +89 -0
  52. package/src/core/plugin-marketplace/plugin-metadata.js +485 -0
  53. package/src/core/plugin-marketplace/plugin-publisher.js +574 -0
  54. package/src/core/plugin-marketplace/plugin-registry-format.js +419 -0
  55. package/src/core/plugin-marketplace/version-resolver.js +61 -0
  56. package/src/core/plugin-registry.js +265 -0
  57. package/src/dag/dag-engine.js +954 -0
  58. package/src/dag/dag-node.js +76 -0
  59. package/src/dag/enhanced-dag-engine.js +822 -0
  60. package/src/dx/index.js +40 -0
  61. package/src/dx/integration-templates.js +665 -0
  62. package/src/dx/performance-profiler.js +968 -0
  63. package/src/dx/realtime-debugger.js +755 -0
  64. package/src/dx/visual-pipeline-builder.js +578 -0
  65. package/src/ecosystem/plugin-analytics-dashboard.js +778 -0
  66. package/src/ecosystem/plugin-certification.js +580 -0
  67. package/src/ecosystem/plugin-hub.js +821 -0
  68. package/src/enterprise/audit-logging.js +967 -0
  69. package/src/enterprise/data-governance.js +408 -0
  70. package/src/enterprise/multi-tenancy.js +496 -0
  71. package/src/enterprise/sso-integration.js +903 -0
  72. package/src/evaluate/evaluator.js +52 -0
  73. package/src/evaluate/scoring.js +91 -0
  74. package/src/index.js +67 -0
  75. package/src/ingest.js +59 -0
  76. package/src/loader/csv-loader.js +38 -0
  77. package/src/loader/directory-loader.js +48 -0
  78. package/src/loader/html-loader.js +62 -0
  79. package/src/loader/markdown-loader.js +67 -0
  80. package/src/mocks/openai-embedder.js +119 -0
  81. package/src/mocks/openai-llm.js +77 -0
  82. package/src/mocks/pdf-loader.js +21 -0
  83. package/src/mocks/pinecone-retriever.js +106 -0
  84. package/src/observability/audit-logger.js +758 -0
  85. package/src/observability/dashboard-config.json +675 -0
  86. package/src/observability/event-logger.js +310 -0
  87. package/src/observability/metrics.js +691 -0
  88. package/src/observability/security-monitor.js +830 -0
  89. package/src/observability/slo-monitor.js +319 -0
  90. package/src/observability/telemetry.js +686 -0
  91. package/src/pipeline/pipeline.js +18 -0
  92. package/src/plugins/sample-embedder.js +53 -0
  93. package/src/plugins/sample-llm.js +30 -0
  94. package/src/plugins/sample-loader.js +24 -0
  95. package/src/plugins/sample-retriever.js +84 -0
  96. package/src/query.js +117 -0
  97. package/src/reranker/llm-reranker.js +85 -0
  98. package/src/scripts/script-utilities.js +36 -0
  99. package/src/security/plugin-sandbox.js +586 -0
  100. package/src/security/plugin-signature-verifier.js +414 -0
  101. package/src/security/validator.js +36 -0
  102. package/src/utils/ci/diagnostic-reporter.js +57 -0
  103. package/src/utils/logger.js +211 -0
  104. package/src/utils/performance-monitor.js +561 -0
  105. package/src/utils/plugin-scaffolder.js +447 -0
  106. package/src/utils/retry-policy.js +443 -0
  107. package/src/utils/retry.js +107 -0
  108. package/src/utils/safe-expression-evaluator.js +579 -0
  109. package/src/utils/structured-logger.js +361 -0
  110. package/src/utils/validate-plugin-contract.js +42 -0
@@ -0,0 +1,830 @@
1
+ /**
2
+ * @fileoverview Security monitoring and alerting system for the RAG pipeline.
3
+ * Provides real-time threat detection, anomaly analysis, and automated incident response.
4
+ *
5
+ * @author DevilsDev Team
6
+ * @since 2.1.0
7
+ * @version 2.1.0
8
+ */
9
+
10
+ const { EventEmitter } = require('events');
11
+ const fs = require('fs').promises;
12
+ const path = require('path');
13
+ const crypto = require('crypto');
14
+ const logger = require('../utils/structured-logger');
15
+ const { getTelemetryService } = require('./telemetry');
16
+
17
+ /**
18
+ * Security monitoring service for threat detection and incident response.
19
+ *
20
+ * Features:
21
+ * - Real-time security event monitoring
22
+ * - Anomaly detection and pattern analysis
23
+ * - Automated threat response
24
+ * - Security metrics and dashboards
25
+ * - Integration with SIEM systems
26
+ * - Compliance audit trails
27
+ *
28
+ * @class SecurityMonitor
29
+ * @extends EventEmitter
30
+ */
31
+ class SecurityMonitor extends EventEmitter {
32
+ constructor(options = {}) {
33
+ super();
34
+
35
+ this.config = {
36
+ // Monitoring Configuration
37
+ enabled: options.enabled !== false,
38
+ checkInterval: options.checkInterval || 30000, // 30 seconds
39
+ alertThreshold: options.alertThreshold || 5, // 5 events trigger alert
40
+ retentionDays: options.retentionDays || 30,
41
+
42
+ // Threat Detection
43
+ threatDetection: {
44
+ enabled: options.threatDetection?.enabled !== false,
45
+ rateLimitThreshold: options.threatDetection?.rateLimitThreshold || 100,
46
+ timeWindow: options.threatDetection?.timeWindow || 60000, // 1 minute
47
+ bruteForceThreshold: options.threatDetection?.bruteForceThreshold || 10,
48
+ suspiciousPatterns: options.threatDetection?.suspiciousPatterns || [],
49
+ ...options.threatDetection,
50
+ },
51
+
52
+ // Anomaly Detection
53
+ anomalyDetection: {
54
+ enabled: options.anomalyDetection?.enabled !== false,
55
+ baselineWindow: options.anomalyDetection?.baselineWindow || 3600000, // 1 hour
56
+ deviationThreshold: options.anomalyDetection?.deviationThreshold || 2.5, // 2.5 standard deviations
57
+ minSamples: options.anomalyDetection?.minSamples || 30,
58
+ ...options.anomalyDetection,
59
+ },
60
+
61
+ // Alerting Configuration
62
+ alerting: {
63
+ enabled: options.alerting?.enabled !== false,
64
+ channels: options.alerting?.channels || ['log'], // log, webhook, email
65
+ webhookUrl: options.alerting?.webhookUrl,
66
+ emailConfig: options.alerting?.emailConfig,
67
+ severity: {
68
+ low: options.alerting?.severity?.low || 'info',
69
+ medium: options.alerting?.severity?.medium || 'warn',
70
+ high: options.alerting?.severity?.high || 'error',
71
+ critical: options.alerting?.severity?.critical || 'error',
72
+ },
73
+ ...options.alerting,
74
+ },
75
+
76
+ // Response Configuration
77
+ autoResponse: {
78
+ enabled: options.autoResponse?.enabled !== false,
79
+ blockSuspiciousIPs: options.autoResponse?.blockSuspiciousIPs !== false,
80
+ rateLimitViolators: options.autoResponse?.rateLimitViolators !== false,
81
+ quarantineThreats: options.autoResponse?.quarantineThreats !== false,
82
+ ...options.autoResponse,
83
+ },
84
+
85
+ // Storage Configuration
86
+ storage: {
87
+ type: options.storage?.type || 'file', // file, database, s3
88
+ location: options.storage?.location || './security-logs',
89
+ maxFileSize: options.storage?.maxFileSize || 100 * 1024 * 1024, // 100MB
90
+ compression: options.storage?.compression !== false,
91
+ ...options.storage,
92
+ },
93
+
94
+ ...options,
95
+ };
96
+
97
+ // Internal state
98
+ this.isRunning = false;
99
+ this.securityEvents = new Map();
100
+ this.threatMetrics = new Map();
101
+ this.anomalyBaselines = new Map();
102
+ this.blockedEntities = new Set();
103
+ this.activeIncidents = new Map();
104
+ this.monitoringInterval = null;
105
+
106
+ // Event counters and rate tracking
107
+ this.eventCounters = new Map();
108
+ this.rateTracking = new Map();
109
+
110
+ // Telemetry service
111
+ this.telemetry = getTelemetryService();
112
+ }
113
+
114
+ /**
115
+ * Start the security monitoring service.
116
+ *
117
+ * @returns {Promise<void>} Start promise
118
+ */
119
+ async start() {
120
+ if (this.isRunning) {
121
+ logger.warn('Security monitor already running');
122
+ return;
123
+ }
124
+
125
+ if (!this.config.enabled) {
126
+ logger.info('Security monitoring is disabled');
127
+ return;
128
+ }
129
+
130
+ try {
131
+ logger.info('Starting security monitoring service', {
132
+ checkInterval: this.config.checkInterval,
133
+ threatDetection: this.config.threatDetection.enabled,
134
+ anomalyDetection: this.config.anomalyDetection.enabled,
135
+ autoResponse: this.config.autoResponse.enabled,
136
+ });
137
+
138
+ // Initialize storage
139
+ await this.initializeStorage();
140
+
141
+ // Load historical data for baselines
142
+ await this.loadBaselines();
143
+
144
+ // Start monitoring loop
145
+ this.startMonitoringLoop();
146
+
147
+ // Setup event listeners
148
+ this.setupEventListeners();
149
+
150
+ this.isRunning = true;
151
+
152
+ // Record telemetry
153
+ this.telemetry.recordMetric('security_monitor_started', 1, {
154
+ service: 'security-monitor',
155
+ });
156
+
157
+ logger.info('Security monitoring service started successfully');
158
+ } catch (error) {
159
+ logger.error('Failed to start security monitoring service', {
160
+ error: error.message,
161
+ stack: error.stack,
162
+ });
163
+ throw error;
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Stop the security monitoring service.
169
+ *
170
+ * @returns {Promise<void>} Stop promise
171
+ */
172
+ async stop() {
173
+ if (!this.isRunning) {
174
+ return;
175
+ }
176
+
177
+ logger.info('Stopping security monitoring service');
178
+
179
+ try {
180
+ // Stop monitoring loop
181
+ if (this.monitoringInterval) {
182
+ clearInterval(this.monitoringInterval);
183
+ this.monitoringInterval = null;
184
+ }
185
+
186
+ // Save current state
187
+ await this.saveState();
188
+
189
+ // Clear event listeners
190
+ this.removeAllListeners();
191
+
192
+ this.isRunning = false;
193
+
194
+ logger.info('Security monitoring service stopped successfully');
195
+ } catch (error) {
196
+ logger.error('Error stopping security monitoring service', {
197
+ error: error.message,
198
+ });
199
+ throw error;
200
+ }
201
+ }
202
+
203
+ /**
204
+ * Record a security event for monitoring and analysis.
205
+ *
206
+ * @param {Object} event - Security event data
207
+ * @param {string} event.type - Event type (auth_failure, rate_limit, etc.)
208
+ * @param {string} event.severity - Event severity (low, medium, high, critical)
209
+ * @param {string} event.source - Event source identifier
210
+ * @param {Object} event.details - Additional event details
211
+ */
212
+ async recordSecurityEvent(event) {
213
+ if (!this.isRunning || !this.config.enabled) {
214
+ return;
215
+ }
216
+
217
+ try {
218
+ const timestamp = Date.now();
219
+ const eventId = crypto.randomUUID();
220
+
221
+ const securityEvent = {
222
+ id: eventId,
223
+ timestamp,
224
+ type: event.type,
225
+ severity: event.severity || 'medium',
226
+ source: event.source,
227
+ details: event.details || {},
228
+ ...event,
229
+ };
230
+
231
+ // Store event
232
+ this.securityEvents.set(eventId, securityEvent);
233
+
234
+ // Update counters
235
+ this.updateEventCounters(securityEvent);
236
+
237
+ // Track rate metrics
238
+ this.trackRateMetrics(securityEvent);
239
+
240
+ // Perform threat detection
241
+ await this.detectThreats(securityEvent);
242
+
243
+ // Perform anomaly detection
244
+ await this.detectAnomalies(securityEvent);
245
+
246
+ // Log event with correlation
247
+ await logger.withCorrelation(eventId, async () => {
248
+ logger.security('Security event recorded', {
249
+ eventId,
250
+ type: securityEvent.type,
251
+ severity: securityEvent.severity,
252
+ source: securityEvent.source,
253
+ });
254
+ });
255
+
256
+ // Record telemetry
257
+ this.telemetry.recordMetric('security_events_total', 1, {
258
+ type: securityEvent.type,
259
+ severity: securityEvent.severity,
260
+ });
261
+
262
+ // Emit event for external handlers
263
+ this.emit('securityEvent', securityEvent);
264
+ } catch (error) {
265
+ logger.error('Failed to record security event', {
266
+ event,
267
+ error: error.message,
268
+ });
269
+ }
270
+ }
271
+
272
+ /**
273
+ * Detect threats based on security event patterns.
274
+ *
275
+ * @private
276
+ * @param {Object} event - Security event
277
+ */
278
+ async detectThreats(event) {
279
+ if (!this.config.threatDetection.enabled) {
280
+ return;
281
+ }
282
+
283
+ const threats = [];
284
+
285
+ // Rate limiting detection
286
+ const rateViolation = this.detectRateLimitViolation(event);
287
+ if (rateViolation) {
288
+ threats.push(rateViolation);
289
+ }
290
+
291
+ // Brute force detection
292
+ const bruteForce = this.detectBruteForce(event);
293
+ if (bruteForce) {
294
+ threats.push(bruteForce);
295
+ }
296
+
297
+ // Suspicious pattern detection
298
+ const suspiciousPattern = this.detectSuspiciousPatterns(event);
299
+ if (suspiciousPattern) {
300
+ threats.push(suspiciousPattern);
301
+ }
302
+
303
+ // Process detected threats
304
+ for (const threat of threats) {
305
+ await this.handleThreat(threat);
306
+ }
307
+ }
308
+
309
+ /**
310
+ * Detect rate limit violations.
311
+ *
312
+ * @private
313
+ * @param {Object} event - Security event
314
+ * @returns {Object|null} Threat detection result
315
+ */
316
+ detectRateLimitViolation(event) {
317
+ const { rateLimitThreshold, timeWindow } = this.config.threatDetection;
318
+ const now = Date.now();
319
+ const windowStart = now - timeWindow;
320
+
321
+ // Count events from the same source in the time window
322
+ const sourceEvents = Array.from(this.securityEvents.values()).filter(
323
+ (e) => e.source === event.source && e.timestamp >= windowStart,
324
+ );
325
+
326
+ if (sourceEvents.length > rateLimitThreshold) {
327
+ return {
328
+ type: 'rate_limit_violation',
329
+ severity: 'high',
330
+ source: event.source,
331
+ details: {
332
+ eventCount: sourceEvents.length,
333
+ threshold: rateLimitThreshold,
334
+ timeWindow: timeWindow,
335
+ events: sourceEvents.slice(-5), // Last 5 events
336
+ },
337
+ };
338
+ }
339
+
340
+ return null;
341
+ }
342
+
343
+ /**
344
+ * Detect brute force attacks.
345
+ *
346
+ * @private
347
+ * @param {Object} event - Security event
348
+ * @returns {Object|null} Threat detection result
349
+ */
350
+ detectBruteForce(event) {
351
+ if (event.type !== 'auth_failure') {
352
+ return null;
353
+ }
354
+
355
+ const { bruteForceThreshold, timeWindow } = this.config.threatDetection;
356
+ const now = Date.now();
357
+ const windowStart = now - timeWindow;
358
+
359
+ // Count authentication failures from the same source
360
+ const authFailures = Array.from(this.securityEvents.values()).filter(
361
+ (e) =>
362
+ e.type === 'auth_failure' &&
363
+ e.source === event.source &&
364
+ e.timestamp >= windowStart,
365
+ );
366
+
367
+ if (authFailures.length >= bruteForceThreshold) {
368
+ return {
369
+ type: 'brute_force_attack',
370
+ severity: 'critical',
371
+ source: event.source,
372
+ details: {
373
+ failureCount: authFailures.length,
374
+ threshold: bruteForceThreshold,
375
+ timeWindow: timeWindow,
376
+ attempts: authFailures.map((e) => ({
377
+ timestamp: e.timestamp,
378
+ details: e.details,
379
+ })),
380
+ },
381
+ };
382
+ }
383
+
384
+ return null;
385
+ }
386
+
387
+ /**
388
+ * Detect suspicious patterns in event data.
389
+ *
390
+ * @private
391
+ * @param {Object} event - Security event
392
+ * @returns {Object|null} Threat detection result
393
+ */
394
+ detectSuspiciousPatterns(event) {
395
+ const { suspiciousPatterns } = this.config.threatDetection;
396
+
397
+ for (const pattern of suspiciousPatterns) {
398
+ const match = this.matchPattern(event, pattern);
399
+ if (match) {
400
+ return {
401
+ type: 'suspicious_pattern',
402
+ severity: pattern.severity || 'medium',
403
+ source: event.source,
404
+ details: {
405
+ pattern: pattern.name || 'unnamed',
406
+ match: match,
407
+ event: event,
408
+ },
409
+ };
410
+ }
411
+ }
412
+
413
+ return null;
414
+ }
415
+
416
+ /**
417
+ * Detect anomalies in security event patterns.
418
+ *
419
+ * @private
420
+ * @param {Object} event - Security event
421
+ */
422
+ async detectAnomalies(event) {
423
+ if (!this.config.anomalyDetection.enabled) {
424
+ return;
425
+ }
426
+
427
+ const baseline = this.getBaseline(event.type);
428
+ if (
429
+ !baseline ||
430
+ baseline.samples.length < this.config.anomalyDetection.minSamples
431
+ ) {
432
+ // Not enough data for anomaly detection
433
+ this.updateBaseline(event);
434
+ return;
435
+ }
436
+
437
+ const currentRate = this.getCurrentRate(event.type);
438
+ const anomaly = this.isAnomaly(currentRate, baseline);
439
+
440
+ if (anomaly) {
441
+ await this.handleAnomaly({
442
+ type: 'anomaly_detected',
443
+ severity: anomaly.severity,
444
+ eventType: event.type,
445
+ details: {
446
+ currentRate,
447
+ expectedRate: baseline.mean,
448
+ deviation: anomaly.deviation,
449
+ threshold: this.config.anomalyDetection.deviationThreshold,
450
+ },
451
+ });
452
+ }
453
+
454
+ // Update baseline with new data
455
+ this.updateBaseline(event);
456
+ }
457
+
458
+ /**
459
+ * Handle detected threats with appropriate response.
460
+ *
461
+ * @private
462
+ * @param {Object} threat - Threat detection result
463
+ */
464
+ async handleThreat(threat) {
465
+ const incidentId = crypto.randomUUID();
466
+ const incident = {
467
+ id: incidentId,
468
+ timestamp: Date.now(),
469
+ threat,
470
+ status: 'active',
471
+ responseActions: [],
472
+ };
473
+
474
+ // Store active incident
475
+ this.activeIncidents.set(incidentId, incident);
476
+
477
+ // Log threat detection
478
+ logger.security('Threat detected', {
479
+ incidentId,
480
+ threatType: threat.type,
481
+ severity: threat.severity,
482
+ source: threat.source,
483
+ });
484
+
485
+ // Send alert
486
+ await this.sendAlert(threat, incidentId);
487
+
488
+ // Execute automated response
489
+ if (this.config.autoResponse.enabled) {
490
+ await this.executeAutoResponse(threat, incident);
491
+ }
492
+
493
+ // Record telemetry
494
+ this.telemetry.recordMetric('threats_detected', 1, {
495
+ type: threat.type,
496
+ severity: threat.severity,
497
+ });
498
+
499
+ // Emit threat event
500
+ this.emit('threatDetected', { threat, incident });
501
+ }
502
+
503
+ /**
504
+ * Execute automated threat response actions.
505
+ *
506
+ * @private
507
+ * @param {Object} threat - Threat data
508
+ * @param {Object} incident - Incident data
509
+ */
510
+ async executeAutoResponse(threat, incident) {
511
+ const actions = [];
512
+
513
+ try {
514
+ // Block suspicious IP/source
515
+ if (this.config.autoResponse.blockSuspiciousIPs && threat.source) {
516
+ await this.blockEntity(threat.source, 'Automated threat response');
517
+ actions.push(`Blocked entity: ${threat.source}`);
518
+ }
519
+
520
+ // Rate limit violators
521
+ if (
522
+ this.config.autoResponse.rateLimitViolators &&
523
+ threat.type === 'rate_limit_violation'
524
+ ) {
525
+ await this.applyRateLimit(threat.source);
526
+ actions.push(`Applied rate limit to: ${threat.source}`);
527
+ }
528
+
529
+ // Quarantine threats
530
+ if (
531
+ this.config.autoResponse.quarantineThreats &&
532
+ threat.severity === 'critical'
533
+ ) {
534
+ await this.quarantineThreat(threat);
535
+ actions.push('Threat quarantined');
536
+ }
537
+
538
+ // Update incident with response actions
539
+ incident.responseActions = actions;
540
+ this.activeIncidents.set(incident.id, incident);
541
+
542
+ logger.info('Automated threat response executed', {
543
+ incidentId: incident.id,
544
+ actions,
545
+ });
546
+ } catch (error) {
547
+ logger.error('Failed to execute automated response', {
548
+ incidentId: incident.id,
549
+ error: error.message,
550
+ });
551
+ }
552
+ }
553
+
554
+ /**
555
+ * Send security alert through configured channels.
556
+ *
557
+ * @private
558
+ * @param {Object} threat - Threat data
559
+ * @param {string} incidentId - Incident identifier
560
+ */
561
+ async sendAlert(threat, incidentId) {
562
+ if (!this.config.alerting.enabled) {
563
+ return;
564
+ }
565
+
566
+ const alert = {
567
+ id: crypto.randomUUID(),
568
+ timestamp: Date.now(),
569
+ incidentId,
570
+ threat,
571
+ severity: threat.severity,
572
+ title: `Security Threat Detected: ${threat.type}`,
573
+ description: this.formatThreatDescription(threat),
574
+ };
575
+
576
+ const channels = this.config.alerting.channels;
577
+
578
+ for (const channel of channels) {
579
+ try {
580
+ switch (channel) {
581
+ case 'log':
582
+ await this.sendLogAlert(alert);
583
+ break;
584
+ case 'webhook':
585
+ await this.sendWebhookAlert(alert);
586
+ break;
587
+ case 'email':
588
+ await this.sendEmailAlert(alert);
589
+ break;
590
+ default:
591
+ logger.warn('Unknown alert channel', { channel });
592
+ }
593
+ } catch (error) {
594
+ logger.error('Failed to send alert', {
595
+ channel,
596
+ alertId: alert.id,
597
+ error: error.message,
598
+ });
599
+ }
600
+ }
601
+ }
602
+
603
+ /**
604
+ * Block an entity (IP, user, etc.) for security reasons.
605
+ *
606
+ * @private
607
+ * @param {string} entity - Entity identifier to block
608
+ * @param {string} reason - Reason for blocking
609
+ */
610
+ async blockEntity(entity, reason) {
611
+ this.blockedEntities.add(entity);
612
+
613
+ logger.security('Entity blocked', {
614
+ entity,
615
+ reason,
616
+ timestamp: Date.now(),
617
+ });
618
+
619
+ // Emit block event for external handlers
620
+ this.emit('entityBlocked', { entity, reason });
621
+ }
622
+
623
+ /**
624
+ * Check if an entity is blocked.
625
+ *
626
+ * @param {string} entity - Entity identifier
627
+ * @returns {boolean} True if blocked
628
+ */
629
+ isBlocked(entity) {
630
+ return this.blockedEntities.has(entity);
631
+ }
632
+
633
+ /**
634
+ * Get security monitoring health status.
635
+ *
636
+ * @returns {Object} Health status
637
+ */
638
+ getHealth() {
639
+ return {
640
+ running: this.isRunning,
641
+ enabled: this.config.enabled,
642
+ activeIncidents: this.activeIncidents.size,
643
+ blockedEntities: this.blockedEntities.size,
644
+ eventsProcessed: this.securityEvents.size,
645
+ threatDetection: this.config.threatDetection.enabled,
646
+ anomalyDetection: this.config.anomalyDetection.enabled,
647
+ autoResponse: this.config.autoResponse.enabled,
648
+ lastCheck: this.lastCheckTime || null,
649
+ };
650
+ }
651
+
652
+ /**
653
+ * Get security metrics for monitoring dashboards.
654
+ *
655
+ * @returns {Object} Security metrics
656
+ */
657
+ getMetrics() {
658
+ const now = Date.now();
659
+ const lastHour = now - 3600000; // 1 hour ago
660
+
661
+ const recentEvents = Array.from(this.securityEvents.values()).filter(
662
+ (e) => e.timestamp >= lastHour,
663
+ );
664
+
665
+ const eventsByType = recentEvents.reduce((acc, event) => {
666
+ acc[event.type] = (acc[event.type] || 0) + 1;
667
+ return acc;
668
+ }, {});
669
+
670
+ const eventsBySeverity = recentEvents.reduce((acc, event) => {
671
+ acc[event.severity] = (acc[event.severity] || 0) + 1;
672
+ return acc;
673
+ }, {});
674
+
675
+ return {
676
+ totalEvents: this.securityEvents.size,
677
+ recentEvents: recentEvents.length,
678
+ eventsByType,
679
+ eventsBySeverity,
680
+ activeIncidents: this.activeIncidents.size,
681
+ blockedEntities: this.blockedEntities.size,
682
+ uptime: this.isRunning ? now - (this.startTime || now) : 0,
683
+ };
684
+ }
685
+
686
+ /**
687
+ * Initialize storage for security events and state.
688
+ *
689
+ * @private
690
+ */
691
+ async initializeStorage() {
692
+ if (this.config.storage.type === 'file') {
693
+ const storageDir = this.config.storage.location;
694
+ try {
695
+ await fs.mkdir(storageDir, { recursive: true });
696
+ logger.debug('Security storage initialized', { storageDir });
697
+ } catch (error) {
698
+ logger.error('Failed to initialize security storage', {
699
+ storageDir,
700
+ error: error.message,
701
+ });
702
+ throw error;
703
+ }
704
+ }
705
+ }
706
+
707
+ /**
708
+ * Start the monitoring loop for periodic checks.
709
+ *
710
+ * @private
711
+ */
712
+ startMonitoringLoop() {
713
+ this.startTime = Date.now();
714
+ this.monitoringInterval = setInterval(async () => {
715
+ try {
716
+ this.lastCheckTime = Date.now();
717
+ await this.performPeriodicChecks();
718
+ } catch (error) {
719
+ logger.error('Error in monitoring loop', {
720
+ error: error.message,
721
+ });
722
+ }
723
+ }, this.config.checkInterval);
724
+ }
725
+
726
+ /**
727
+ * Perform periodic security checks and maintenance.
728
+ *
729
+ * @private
730
+ */
731
+ async performPeriodicChecks() {
732
+ // Clean up old events
733
+ await this.cleanupOldEvents();
734
+
735
+ // Update metrics
736
+ this.updateSecurityMetrics();
737
+
738
+ // Check for resolved incidents
739
+ await this.checkIncidentStatus();
740
+
741
+ // Emit health check event
742
+ this.emit('healthCheck', this.getHealth());
743
+ }
744
+
745
+ /**
746
+ * Clean up old security events based on retention policy.
747
+ *
748
+ * @private
749
+ */
750
+ async cleanupOldEvents() {
751
+ const retentionMs = this.config.retentionDays * 24 * 60 * 60 * 1000;
752
+ const cutoffTime = Date.now() - retentionMs;
753
+
754
+ let cleanedCount = 0;
755
+ for (const [eventId, event] of this.securityEvents) {
756
+ if (event.timestamp < cutoffTime) {
757
+ this.securityEvents.delete(eventId);
758
+ cleanedCount++;
759
+ }
760
+ }
761
+
762
+ if (cleanedCount > 0) {
763
+ logger.debug('Cleaned up old security events', { cleanedCount });
764
+ }
765
+ }
766
+
767
+ /**
768
+ * Update security metrics for monitoring.
769
+ *
770
+ * @private
771
+ */
772
+ updateSecurityMetrics() {
773
+ const metrics = this.getMetrics();
774
+
775
+ // Record telemetry metrics
776
+ this.telemetry.recordMetric('security_events_active', metrics.totalEvents);
777
+ this.telemetry.recordMetric(
778
+ 'security_incidents_active',
779
+ metrics.activeIncidents,
780
+ );
781
+ this.telemetry.recordMetric(
782
+ 'security_entities_blocked',
783
+ metrics.blockedEntities,
784
+ );
785
+
786
+ // Update threat metrics
787
+ this.threatMetrics.set('current', metrics);
788
+ }
789
+
790
+ // Additional helper methods would be implemented here...
791
+ // (matchPattern, getBaseline, updateBaseline, etc.)
792
+ }
793
+
794
+ /**
795
+ * Singleton security monitor instance.
796
+ */
797
+ let securityMonitorInstance = null;
798
+
799
+ /**
800
+ * Get or create the global security monitor instance.
801
+ *
802
+ * @param {Object} options - Configuration options
803
+ * @returns {SecurityMonitor} Security monitor instance
804
+ */
805
+ function getSecurityMonitor(options = {}) {
806
+ if (!securityMonitorInstance) {
807
+ securityMonitorInstance = new SecurityMonitor(options);
808
+ }
809
+ return securityMonitorInstance;
810
+ }
811
+
812
+ /**
813
+ * Initialize the global security monitoring service.
814
+ *
815
+ * @param {Object} options - Configuration options
816
+ * @returns {Promise<SecurityMonitor>} Initialized security monitor
817
+ */
818
+ async function initializeSecurityMonitoring(options = {}) {
819
+ const monitor = getSecurityMonitor(options);
820
+ await monitor.start();
821
+ return monitor;
822
+ }
823
+
824
+ module.exports = {
825
+ SecurityMonitor,
826
+ getSecurityMonitor,
827
+ initializeSecurityMonitoring,
828
+ };
829
+
830
+ module.exports.default = module.exports;