vaspera 2.10.1 → 2.12.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 (166) hide show
  1. package/dist/__tests__/audit-trail.test.d.ts +7 -0
  2. package/dist/__tests__/audit-trail.test.d.ts.map +1 -0
  3. package/dist/__tests__/audit-trail.test.js +336 -0
  4. package/dist/__tests__/audit-trail.test.js.map +1 -0
  5. package/dist/__tests__/property-test-helpers.d.ts +1 -1
  6. package/dist/action/pr-comment.test.js +9 -0
  7. package/dist/action/pr-comment.test.js.map +1 -1
  8. package/dist/action/sarif-upload.test.js +9 -0
  9. package/dist/action/sarif-upload.test.js.map +1 -1
  10. package/dist/autofix/ast/__tests__/typescript.test.d.ts +5 -0
  11. package/dist/autofix/ast/__tests__/typescript.test.d.ts.map +1 -0
  12. package/dist/autofix/ast/__tests__/typescript.test.js +210 -0
  13. package/dist/autofix/ast/__tests__/typescript.test.js.map +1 -0
  14. package/dist/autofix/ast/index.d.ts +11 -0
  15. package/dist/autofix/ast/index.d.ts.map +1 -0
  16. package/dist/autofix/ast/index.js +11 -0
  17. package/dist/autofix/ast/index.js.map +1 -0
  18. package/dist/autofix/ast/types.d.ts +77 -0
  19. package/dist/autofix/ast/types.d.ts.map +1 -0
  20. package/dist/autofix/ast/types.js +9 -0
  21. package/dist/autofix/ast/types.js.map +1 -0
  22. package/dist/autofix/ast/typescript.d.ts +17 -0
  23. package/dist/autofix/ast/typescript.d.ts.map +1 -0
  24. package/dist/autofix/ast/typescript.js +427 -0
  25. package/dist/autofix/ast/typescript.js.map +1 -0
  26. package/dist/autofix/constitution.schema.d.ts +21 -21
  27. package/dist/autofix/index.d.ts +1 -0
  28. package/dist/autofix/index.d.ts.map +1 -1
  29. package/dist/autofix/index.js +2 -0
  30. package/dist/autofix/index.js.map +1 -1
  31. package/dist/config/flags.d.ts +6 -6
  32. package/dist/history/store.d.ts +55 -1
  33. package/dist/history/store.d.ts.map +1 -1
  34. package/dist/history/store.js +152 -4
  35. package/dist/history/store.js.map +1 -1
  36. package/dist/history/types.d.ts +9 -5
  37. package/dist/history/types.d.ts.map +1 -1
  38. package/dist/history/verify.d.ts.map +1 -1
  39. package/dist/history/verify.js +5 -3
  40. package/dist/history/verify.js.map +1 -1
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +627 -0
  43. package/dist/index.js.map +1 -1
  44. package/dist/integrations/siem/datadog.d.ts +44 -0
  45. package/dist/integrations/siem/datadog.d.ts.map +1 -0
  46. package/dist/integrations/siem/datadog.js +211 -0
  47. package/dist/integrations/siem/datadog.js.map +1 -0
  48. package/dist/integrations/siem/format.d.ts +59 -0
  49. package/dist/integrations/siem/format.d.ts.map +1 -0
  50. package/dist/integrations/siem/format.js +360 -0
  51. package/dist/integrations/siem/format.js.map +1 -0
  52. package/dist/integrations/siem/index.d.ts +56 -0
  53. package/dist/integrations/siem/index.d.ts.map +1 -0
  54. package/dist/integrations/siem/index.js +117 -0
  55. package/dist/integrations/siem/index.js.map +1 -0
  56. package/dist/integrations/siem/sentinel.d.ts +53 -0
  57. package/dist/integrations/siem/sentinel.d.ts.map +1 -0
  58. package/dist/integrations/siem/sentinel.js +231 -0
  59. package/dist/integrations/siem/sentinel.js.map +1 -0
  60. package/dist/integrations/siem/splunk.d.ts +46 -0
  61. package/dist/integrations/siem/splunk.d.ts.map +1 -0
  62. package/dist/integrations/siem/splunk.js +210 -0
  63. package/dist/integrations/siem/splunk.js.map +1 -0
  64. package/dist/integrations/siem/types.d.ts +210 -0
  65. package/dist/integrations/siem/types.d.ts.map +1 -0
  66. package/dist/integrations/siem/types.js +9 -0
  67. package/dist/integrations/siem/types.js.map +1 -0
  68. package/dist/persistence/__tests__/persistence.test.d.ts +5 -0
  69. package/dist/persistence/__tests__/persistence.test.d.ts.map +1 -0
  70. package/dist/persistence/__tests__/persistence.test.js +369 -0
  71. package/dist/persistence/__tests__/persistence.test.js.map +1 -0
  72. package/dist/persistence/db.d.ts +15 -0
  73. package/dist/persistence/db.d.ts.map +1 -0
  74. package/dist/persistence/db.js +79 -0
  75. package/dist/persistence/db.js.map +1 -0
  76. package/dist/persistence/index.d.ts +66 -0
  77. package/dist/persistence/index.d.ts.map +1 -0
  78. package/dist/persistence/index.js +143 -0
  79. package/dist/persistence/index.js.map +1 -0
  80. package/dist/persistence/migrations/index.d.ts +10 -0
  81. package/dist/persistence/migrations/index.d.ts.map +1 -0
  82. package/dist/persistence/migrations/index.js +125 -0
  83. package/dist/persistence/migrations/index.js.map +1 -0
  84. package/dist/persistence/repositories/findings.d.ts +41 -0
  85. package/dist/persistence/repositories/findings.d.ts.map +1 -0
  86. package/dist/persistence/repositories/findings.js +238 -0
  87. package/dist/persistence/repositories/findings.js.map +1 -0
  88. package/dist/persistence/repositories/projects.d.ts +22 -0
  89. package/dist/persistence/repositories/projects.d.ts.map +1 -0
  90. package/dist/persistence/repositories/projects.js +71 -0
  91. package/dist/persistence/repositories/projects.js.map +1 -0
  92. package/dist/persistence/repositories/scans.d.ts +30 -0
  93. package/dist/persistence/repositories/scans.d.ts.map +1 -0
  94. package/dist/persistence/repositories/scans.js +107 -0
  95. package/dist/persistence/repositories/scans.js.map +1 -0
  96. package/dist/persistence/repositories/trends.d.ts +42 -0
  97. package/dist/persistence/repositories/trends.d.ts.map +1 -0
  98. package/dist/persistence/repositories/trends.js +178 -0
  99. package/dist/persistence/repositories/trends.js.map +1 -0
  100. package/dist/persistence/types.d.ts +105 -0
  101. package/dist/persistence/types.d.ts.map +1 -0
  102. package/dist/persistence/types.js +13 -0
  103. package/dist/persistence/types.js.map +1 -0
  104. package/dist/plugins/types.d.ts +2 -2
  105. package/dist/scanners/ai-code/types.d.ts +12 -12
  106. package/dist/scanners/cache.d.ts.map +1 -1
  107. package/dist/scanners/cache.js +9 -0
  108. package/dist/scanners/cache.js.map +1 -1
  109. package/dist/scanners/dast.d.ts +40 -0
  110. package/dist/scanners/dast.d.ts.map +1 -0
  111. package/dist/scanners/dast.js +228 -0
  112. package/dist/scanners/dast.js.map +1 -0
  113. package/dist/scanners/deploy/types.d.ts +19 -19
  114. package/dist/scanners/detection/__tests__/detection.test.d.ts +5 -0
  115. package/dist/scanners/detection/__tests__/detection.test.d.ts.map +1 -0
  116. package/dist/scanners/detection/__tests__/detection.test.js +265 -0
  117. package/dist/scanners/detection/__tests__/detection.test.js.map +1 -0
  118. package/dist/scanners/detection/engines/ast-query.d.ts +23 -0
  119. package/dist/scanners/detection/engines/ast-query.d.ts.map +1 -0
  120. package/dist/scanners/detection/engines/ast-query.js +232 -0
  121. package/dist/scanners/detection/engines/ast-query.js.map +1 -0
  122. package/dist/scanners/detection/engines/data-flow.d.ts +12 -0
  123. package/dist/scanners/detection/engines/data-flow.d.ts.map +1 -0
  124. package/dist/scanners/detection/engines/data-flow.js +269 -0
  125. package/dist/scanners/detection/engines/data-flow.js.map +1 -0
  126. package/dist/scanners/detection/index.d.ts +29 -0
  127. package/dist/scanners/detection/index.d.ts.map +1 -0
  128. package/dist/scanners/detection/index.js +140 -0
  129. package/dist/scanners/detection/index.js.map +1 -0
  130. package/dist/scanners/detection/rules/builtin.d.ts +14 -0
  131. package/dist/scanners/detection/rules/builtin.d.ts.map +1 -0
  132. package/dist/scanners/detection/rules/builtin.js +307 -0
  133. package/dist/scanners/detection/rules/builtin.js.map +1 -0
  134. package/dist/scanners/detection/rules/loader.d.ts +19 -0
  135. package/dist/scanners/detection/rules/loader.d.ts.map +1 -0
  136. package/dist/scanners/detection/rules/loader.js +111 -0
  137. package/dist/scanners/detection/rules/loader.js.map +1 -0
  138. package/dist/scanners/detection/types.d.ts +171 -0
  139. package/dist/scanners/detection/types.d.ts.map +1 -0
  140. package/dist/scanners/detection/types.js +36 -0
  141. package/dist/scanners/detection/types.js.map +1 -0
  142. package/dist/scanners/index.d.ts +13 -5
  143. package/dist/scanners/index.d.ts.map +1 -1
  144. package/dist/scanners/index.js +197 -15
  145. package/dist/scanners/index.js.map +1 -1
  146. package/dist/scanners/index.test.js +6 -6
  147. package/dist/scanners/index.test.js.map +1 -1
  148. package/dist/scanners/openapi.d.ts +20 -0
  149. package/dist/scanners/openapi.d.ts.map +1 -0
  150. package/dist/scanners/openapi.js +226 -0
  151. package/dist/scanners/openapi.js.map +1 -0
  152. package/dist/scanners/runtime/types.d.ts +4 -4
  153. package/dist/scanners/rust.d.ts +22 -0
  154. package/dist/scanners/rust.d.ts.map +1 -0
  155. package/dist/scanners/rust.js +239 -0
  156. package/dist/scanners/rust.js.map +1 -0
  157. package/dist/scanners/scale/types.d.ts +19 -19
  158. package/dist/scanners/terraform.d.ts +23 -0
  159. package/dist/scanners/terraform.d.ts.map +1 -0
  160. package/dist/scanners/terraform.js +207 -0
  161. package/dist/scanners/terraform.js.map +1 -0
  162. package/dist/scanners/types.d.ts +1 -1
  163. package/dist/scanners/types.d.ts.map +1 -1
  164. package/dist/scanners/types.js +9 -0
  165. package/dist/scanners/types.js.map +1 -1
  166. package/package.json +5 -1
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Datadog Logs Client
3
+ *
4
+ * Logs API client for Datadog integration.
5
+ *
6
+ * @module integrations/siem/datadog
7
+ */
8
+ import type { SIEMClient, SIEMEvent, SIEMTestResult, SIEMSendResult, SIEMBatchResult, DatadogConfig } from "./types.js";
9
+ /**
10
+ * Datadog Logs API client
11
+ */
12
+ export declare class DatadogClient implements SIEMClient {
13
+ readonly provider: "datadog";
14
+ private config;
15
+ private endpoint;
16
+ constructor(config: DatadogConfig);
17
+ /**
18
+ * Test connection to Datadog
19
+ */
20
+ testConnection(): Promise<SIEMTestResult>;
21
+ /**
22
+ * Send a single event to Datadog
23
+ */
24
+ sendEvent(event: SIEMEvent): Promise<SIEMSendResult>;
25
+ /**
26
+ * Send multiple events in batch
27
+ */
28
+ sendEvents(events: SIEMEvent[]): Promise<SIEMBatchResult>;
29
+ /**
30
+ * Close connection
31
+ */
32
+ close(): Promise<void>;
33
+ }
34
+ /**
35
+ * Create a Datadog client from configuration
36
+ */
37
+ export declare function createDatadogClient(config: {
38
+ apiKey: string;
39
+ site?: string;
40
+ service?: string;
41
+ env?: string;
42
+ tags?: string[];
43
+ }): DatadogClient;
44
+ //# sourceMappingURL=datadog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datadog.d.ts","sourceRoot":"","sources":["../../../src/integrations/siem/datadog.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EACV,UAAU,EACV,SAAS,EACT,cAAc,EACd,cAAc,EACd,eAAe,EACf,aAAa,EACd,MAAM,YAAY,CAAC;AAcpB;;GAEG;AACH,qBAAa,aAAc,YAAW,UAAU;IAC9C,QAAQ,CAAC,QAAQ,EAAG,SAAS,CAAU;IACvC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,QAAQ,CAAS;gBAEb,MAAM,EAAE,aAAa;IAMjC;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC;IAuC/C;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC;IAsD1D;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC;IAsE/D;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,GAAG,aAAa,CAehB"}
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Datadog Logs Client
3
+ *
4
+ * Logs API client for Datadog integration.
5
+ *
6
+ * @module integrations/siem/datadog
7
+ */
8
+ import { logger } from "../../logger.js";
9
+ import { formatForDatadog } from "./format.js";
10
+ /**
11
+ * Datadog site to API endpoint mapping
12
+ */
13
+ const DATADOG_ENDPOINTS = {
14
+ "datadoghq.com": "https://http-intake.logs.datadoghq.com",
15
+ "us3.datadoghq.com": "https://http-intake.logs.us3.datadoghq.com",
16
+ "us5.datadoghq.com": "https://http-intake.logs.us5.datadoghq.com",
17
+ "datadoghq.eu": "https://http-intake.logs.datadoghq.eu",
18
+ "ap1.datadoghq.com": "https://http-intake.logs.ap1.datadoghq.com",
19
+ "ddog-gov.com": "https://http-intake.logs.ddog-gov.com",
20
+ };
21
+ /**
22
+ * Datadog Logs API client
23
+ */
24
+ export class DatadogClient {
25
+ provider = "datadog";
26
+ config;
27
+ endpoint;
28
+ constructor(config) {
29
+ this.config = config;
30
+ const site = config.options?.site || "datadoghq.com";
31
+ this.endpoint = DATADOG_ENDPOINTS[site] || DATADOG_ENDPOINTS["datadoghq.com"];
32
+ }
33
+ /**
34
+ * Test connection to Datadog
35
+ */
36
+ async testConnection() {
37
+ const startTime = Date.now();
38
+ try {
39
+ // Datadog validates the API key on first request
40
+ const testEvent = {
41
+ timestamp: new Date().toISOString(),
42
+ eventType: "scan.started",
43
+ severity: "informational",
44
+ project: "test",
45
+ message: "Vaspera connection test",
46
+ source: "vaspera",
47
+ data: { test: true },
48
+ };
49
+ const result = await this.sendEvent(testEvent);
50
+ return {
51
+ success: result.success,
52
+ provider: "datadog",
53
+ endpoint: this.endpoint,
54
+ latencyMs: Date.now() - startTime,
55
+ error: result.error,
56
+ details: {
57
+ site: this.config.options?.site || "datadoghq.com",
58
+ service: this.config.options?.service,
59
+ },
60
+ };
61
+ }
62
+ catch (error) {
63
+ return {
64
+ success: false,
65
+ provider: "datadog",
66
+ endpoint: this.endpoint,
67
+ latencyMs: Date.now() - startTime,
68
+ error: error instanceof Error ? error.message : String(error),
69
+ };
70
+ }
71
+ }
72
+ /**
73
+ * Send a single event to Datadog
74
+ */
75
+ async sendEvent(event) {
76
+ const timestamp = new Date().toISOString();
77
+ try {
78
+ const payload = formatForDatadog(event, {
79
+ service: this.config.options?.service,
80
+ env: this.config.options?.env,
81
+ tags: this.config.options?.tags,
82
+ });
83
+ const response = await fetch(`${this.endpoint}/api/v2/logs`, {
84
+ method: "POST",
85
+ headers: {
86
+ "Content-Type": "application/json",
87
+ "DD-API-KEY": this.config.token,
88
+ },
89
+ body: JSON.stringify([payload]),
90
+ signal: AbortSignal.timeout(30000),
91
+ });
92
+ if (response.ok || response.status === 202) {
93
+ logger.debug("siem.datadog.event_sent", {
94
+ eventType: event.eventType,
95
+ });
96
+ return {
97
+ success: true,
98
+ timestamp,
99
+ };
100
+ }
101
+ const errorText = await response.text();
102
+ logger.warn("siem.datadog.send_failed", {
103
+ status: response.status,
104
+ error: errorText,
105
+ });
106
+ return {
107
+ success: false,
108
+ timestamp,
109
+ error: `HTTP ${response.status}: ${errorText}`,
110
+ };
111
+ }
112
+ catch (error) {
113
+ const errorMessage = error instanceof Error ? error.message : String(error);
114
+ logger.error("siem.datadog.send_error", { error: errorMessage });
115
+ return {
116
+ success: false,
117
+ timestamp,
118
+ error: errorMessage,
119
+ };
120
+ }
121
+ }
122
+ /**
123
+ * Send multiple events in batch
124
+ */
125
+ async sendEvents(events) {
126
+ if (events.length === 0) {
127
+ return {
128
+ success: true,
129
+ totalEvents: 0,
130
+ successCount: 0,
131
+ failureCount: 0,
132
+ };
133
+ }
134
+ try {
135
+ const payloads = events.map((event) => formatForDatadog(event, {
136
+ service: this.config.options?.service,
137
+ env: this.config.options?.env,
138
+ tags: this.config.options?.tags,
139
+ }));
140
+ const response = await fetch(`${this.endpoint}/api/v2/logs`, {
141
+ method: "POST",
142
+ headers: {
143
+ "Content-Type": "application/json",
144
+ "DD-API-KEY": this.config.token,
145
+ },
146
+ body: JSON.stringify(payloads),
147
+ signal: AbortSignal.timeout(60000),
148
+ });
149
+ if (response.ok || response.status === 202) {
150
+ logger.info("siem.datadog.batch_sent", {
151
+ eventCount: events.length,
152
+ });
153
+ return {
154
+ success: true,
155
+ totalEvents: events.length,
156
+ successCount: events.length,
157
+ failureCount: 0,
158
+ };
159
+ }
160
+ const errorText = await response.text();
161
+ logger.warn("siem.datadog.batch_failed", {
162
+ status: response.status,
163
+ error: errorText,
164
+ eventCount: events.length,
165
+ });
166
+ return {
167
+ success: false,
168
+ totalEvents: events.length,
169
+ successCount: 0,
170
+ failureCount: events.length,
171
+ errors: [{ index: 0, error: `HTTP ${response.status}: ${errorText}` }],
172
+ };
173
+ }
174
+ catch (error) {
175
+ const errorMessage = error instanceof Error ? error.message : String(error);
176
+ logger.error("siem.datadog.batch_error", { error: errorMessage });
177
+ return {
178
+ success: false,
179
+ totalEvents: events.length,
180
+ successCount: 0,
181
+ failureCount: events.length,
182
+ errors: [{ index: 0, error: errorMessage }],
183
+ };
184
+ }
185
+ }
186
+ /**
187
+ * Close connection
188
+ */
189
+ async close() {
190
+ // No persistent connection to close for Datadog API
191
+ }
192
+ }
193
+ /**
194
+ * Create a Datadog client from configuration
195
+ */
196
+ export function createDatadogClient(config) {
197
+ const site = config.site || "datadoghq.com";
198
+ return new DatadogClient({
199
+ provider: "datadog",
200
+ enabled: true,
201
+ endpoint: DATADOG_ENDPOINTS[site] || DATADOG_ENDPOINTS["datadoghq.com"],
202
+ token: config.apiKey,
203
+ options: {
204
+ site,
205
+ service: config.service || "vaspera-hardening",
206
+ env: config.env,
207
+ tags: config.tags,
208
+ },
209
+ });
210
+ }
211
+ //# sourceMappingURL=datadog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datadog.js","sourceRoot":"","sources":["../../../src/integrations/siem/datadog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * SIEM Event Formatting
3
+ *
4
+ * Converts Vaspera events to SIEM-compatible formats (CEF, JSON).
5
+ *
6
+ * @module integrations/siem/format
7
+ */
8
+ import type { Severity } from "../../certification/types.js";
9
+ import type { SIEMEvent, SIEMSeverity, FindingEventData, ScanEventData, CertificationEventData } from "./types.js";
10
+ /**
11
+ * Map Vaspera severity to SIEM severity
12
+ */
13
+ export declare function mapSeverity(severity: Severity): SIEMSeverity;
14
+ /**
15
+ * Map SIEM severity to CEF numeric severity (0-10)
16
+ */
17
+ export declare function severityToCEF(severity: SIEMSeverity): number;
18
+ /**
19
+ * Format event as CEF string
20
+ */
21
+ export declare function formatAsCEF(event: SIEMEvent): string;
22
+ /**
23
+ * Format event as JSON for generic SIEM ingestion
24
+ */
25
+ export declare function formatAsJSON(event: SIEMEvent): object;
26
+ /**
27
+ * Format event for Splunk HEC
28
+ */
29
+ export declare function formatForSplunk(event: SIEMEvent, options?: {
30
+ index?: string;
31
+ source?: string;
32
+ sourceType?: string;
33
+ host?: string;
34
+ }): object;
35
+ /**
36
+ * Format event for Microsoft Sentinel (Log Analytics)
37
+ */
38
+ export declare function formatForSentinel(event: SIEMEvent): object;
39
+ /**
40
+ * Format event for Datadog
41
+ */
42
+ export declare function formatForDatadog(event: SIEMEvent, options?: {
43
+ service?: string;
44
+ env?: string;
45
+ tags?: string[];
46
+ }): object;
47
+ /**
48
+ * Create a finding event
49
+ */
50
+ export declare function createFindingEvent(project: string, eventType: "finding.new" | "finding.fixed" | "finding.false_positive", finding: FindingEventData, certificationId?: string): SIEMEvent;
51
+ /**
52
+ * Create a scan event
53
+ */
54
+ export declare function createScanEvent(project: string, eventType: "scan.started" | "scan.completed" | "scan.failed", scan: ScanEventData, certificationId?: string): SIEMEvent;
55
+ /**
56
+ * Create a certification event
57
+ */
58
+ export declare function createCertificationEvent(project: string, eventType: "certification.started" | "certification.completed", certification: CertificationEventData): SIEMEvent;
59
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/integrations/siem/format.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,KAAK,EACV,SAAS,EAET,YAAY,EAEZ,gBAAgB,EAChB,aAAa,EACb,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAMpB;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,YAAY,CAe5D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAe5D;AAsDD;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAqEpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAsBrD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,EAChB,OAAO,GAAE;IACP,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACV,GACL,MAAM,CASR;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAa1D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,EAChB,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACZ,GACL,MAAM,CA0BR;AAmDD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,aAAa,GAAG,eAAe,GAAG,wBAAwB,EACrE,OAAO,EAAE,gBAAgB,EACzB,eAAe,CAAC,EAAE,MAAM,GACvB,SAAS,CAaX;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,cAAc,GAAG,gBAAgB,GAAG,aAAa,EAC5D,IAAI,EAAE,aAAa,EACnB,eAAe,CAAC,EAAE,MAAM,GACvB,SAAS,CA4BX;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,uBAAuB,GAAG,yBAAyB,EAC9D,aAAa,EAAE,sBAAsB,GACpC,SAAS,CAqBX"}
@@ -0,0 +1,360 @@
1
+ /**
2
+ * SIEM Event Formatting
3
+ *
4
+ * Converts Vaspera events to SIEM-compatible formats (CEF, JSON).
5
+ *
6
+ * @module integrations/siem/format
7
+ */
8
+ const DEVICE_VENDOR = "Vaspera";
9
+ const DEVICE_PRODUCT = "Hardening MCP";
10
+ const DEVICE_VERSION = "2.11.0";
11
+ /**
12
+ * Map Vaspera severity to SIEM severity
13
+ */
14
+ export function mapSeverity(severity) {
15
+ switch (severity) {
16
+ case "critical":
17
+ return "critical";
18
+ case "high":
19
+ return "high";
20
+ case "medium":
21
+ return "medium";
22
+ case "low":
23
+ return "low";
24
+ case "info":
25
+ return "informational";
26
+ default:
27
+ return "informational";
28
+ }
29
+ }
30
+ /**
31
+ * Map SIEM severity to CEF numeric severity (0-10)
32
+ */
33
+ export function severityToCEF(severity) {
34
+ switch (severity) {
35
+ case "critical":
36
+ return 10;
37
+ case "high":
38
+ return 8;
39
+ case "medium":
40
+ return 5;
41
+ case "low":
42
+ return 3;
43
+ case "informational":
44
+ return 1;
45
+ default:
46
+ return 0;
47
+ }
48
+ }
49
+ /**
50
+ * Map event type to signature ID
51
+ */
52
+ function eventTypeToSignatureId(eventType) {
53
+ const mapping = {
54
+ "finding.new": "VASP-001",
55
+ "finding.fixed": "VASP-002",
56
+ "finding.false_positive": "VASP-003",
57
+ "scan.started": "VASP-010",
58
+ "scan.completed": "VASP-011",
59
+ "scan.failed": "VASP-012",
60
+ "certification.started": "VASP-020",
61
+ "certification.completed": "VASP-021",
62
+ "compliance.report": "VASP-030",
63
+ "autofix.applied": "VASP-040",
64
+ "autofix.pr_created": "VASP-041",
65
+ };
66
+ return mapping[eventType] || "VASP-999";
67
+ }
68
+ /**
69
+ * Map event type to human-readable name
70
+ */
71
+ function eventTypeToName(eventType) {
72
+ const mapping = {
73
+ "finding.new": "New Security Finding",
74
+ "finding.fixed": "Security Finding Fixed",
75
+ "finding.false_positive": "Finding Marked False Positive",
76
+ "scan.started": "Security Scan Started",
77
+ "scan.completed": "Security Scan Completed",
78
+ "scan.failed": "Security Scan Failed",
79
+ "certification.started": "Certification Started",
80
+ "certification.completed": "Certification Completed",
81
+ "compliance.report": "Compliance Report Generated",
82
+ "autofix.applied": "Autofix Applied",
83
+ "autofix.pr_created": "Autofix Pull Request Created",
84
+ };
85
+ return mapping[eventType] || "Unknown Event";
86
+ }
87
+ /**
88
+ * Escape CEF special characters
89
+ */
90
+ function escapeCEF(value) {
91
+ return value
92
+ .replace(/\\/g, "\\\\")
93
+ .replace(/=/g, "\\=")
94
+ .replace(/\|/g, "\\|")
95
+ .replace(/\n/g, "\\n")
96
+ .replace(/\r/g, "\\r");
97
+ }
98
+ /**
99
+ * Format event as CEF string
100
+ */
101
+ export function formatAsCEF(event) {
102
+ const fields = {
103
+ version: 0,
104
+ deviceVendor: DEVICE_VENDOR,
105
+ deviceProduct: DEVICE_PRODUCT,
106
+ deviceVersion: DEVICE_VERSION,
107
+ signatureId: eventTypeToSignatureId(event.eventType),
108
+ name: eventTypeToName(event.eventType),
109
+ severity: severityToCEF(event.severity),
110
+ extension: {},
111
+ };
112
+ // Build extension fields
113
+ const ext = fields.extension;
114
+ ext["rt"] = new Date(event.timestamp).getTime();
115
+ ext["msg"] = escapeCEF(event.message);
116
+ ext["src"] = event.source;
117
+ ext["cs1"] = event.project;
118
+ ext["cs1Label"] = "project";
119
+ if (event.certificationId) {
120
+ ext["cs2"] = event.certificationId;
121
+ ext["cs2Label"] = "certificationId";
122
+ }
123
+ // Add finding-specific fields
124
+ const data = event.data;
125
+ if (data.findingId) {
126
+ ext["externalId"] = data.findingId;
127
+ }
128
+ if (data.file) {
129
+ ext["filePath"] = escapeCEF(data.file);
130
+ }
131
+ if (data.line) {
132
+ ext["fileId"] = data.line;
133
+ }
134
+ if (data.category) {
135
+ ext["cat"] = escapeCEF(data.category);
136
+ }
137
+ if (data.scanner) {
138
+ ext["deviceCustomString3"] = escapeCEF(data.scanner);
139
+ ext["deviceCustomString3Label"] = "scanner";
140
+ }
141
+ if (data.ruleId) {
142
+ ext["cs4"] = escapeCEF(data.ruleId);
143
+ ext["cs4Label"] = "ruleId";
144
+ }
145
+ if (data.cweIds && data.cweIds.length > 0) {
146
+ ext["cs5"] = data.cweIds.join(",");
147
+ ext["cs5Label"] = "cweIds";
148
+ }
149
+ // Format CEF header
150
+ const header = [
151
+ `CEF:${fields.version}`,
152
+ escapeCEF(fields.deviceVendor),
153
+ escapeCEF(fields.deviceProduct),
154
+ escapeCEF(fields.deviceVersion),
155
+ escapeCEF(fields.signatureId),
156
+ escapeCEF(fields.name),
157
+ fields.severity.toString(),
158
+ ].join("|");
159
+ // Format extension
160
+ const extension = Object.entries(ext)
161
+ .map(([key, value]) => `${key}=${value}`)
162
+ .join(" ");
163
+ return `${header}|${extension}`;
164
+ }
165
+ /**
166
+ * Format event as JSON for generic SIEM ingestion
167
+ */
168
+ export function formatAsJSON(event) {
169
+ return {
170
+ "@timestamp": event.timestamp,
171
+ event: {
172
+ kind: "event",
173
+ category: ["security"],
174
+ type: [event.eventType.split(".")[0]],
175
+ action: event.eventType,
176
+ severity: severityToCEF(event.severity),
177
+ severity_name: event.severity,
178
+ },
179
+ message: event.message,
180
+ source: {
181
+ provider: event.source,
182
+ version: DEVICE_VERSION,
183
+ },
184
+ project: {
185
+ path: event.project,
186
+ certification_id: event.certificationId,
187
+ },
188
+ vaspera: event.data,
189
+ };
190
+ }
191
+ /**
192
+ * Format event for Splunk HEC
193
+ */
194
+ export function formatForSplunk(event, options = {}) {
195
+ return {
196
+ time: Math.floor(new Date(event.timestamp).getTime() / 1000),
197
+ host: options.host || "vaspera",
198
+ source: options.source || "vaspera:hardening",
199
+ sourcetype: options.sourceType || "_json",
200
+ index: options.index,
201
+ event: formatAsJSON(event),
202
+ };
203
+ }
204
+ /**
205
+ * Format event for Microsoft Sentinel (Log Analytics)
206
+ */
207
+ export function formatForSentinel(event) {
208
+ const json = formatAsJSON(event);
209
+ return {
210
+ TimeGenerated: event.timestamp,
211
+ EventType_s: event.eventType,
212
+ Severity_s: event.severity,
213
+ Project_s: event.project,
214
+ CertificationId_g: event.certificationId || "",
215
+ Message_s: event.message,
216
+ Source_s: event.source,
217
+ RawEvent_s: JSON.stringify(event.data),
218
+ ...flattenData(event.data, "_"),
219
+ };
220
+ }
221
+ /**
222
+ * Format event for Datadog
223
+ */
224
+ export function formatForDatadog(event, options = {}) {
225
+ const tags = [
226
+ `project:${event.project}`,
227
+ `event_type:${event.eventType}`,
228
+ `severity:${event.severity}`,
229
+ ...(event.certificationId ? [`certification_id:${event.certificationId}`] : []),
230
+ ...(options.tags || []),
231
+ ];
232
+ if (options.env) {
233
+ tags.push(`env:${options.env}`);
234
+ }
235
+ return {
236
+ ddsource: "vaspera",
237
+ ddtags: tags.join(","),
238
+ hostname: "vaspera-mcp",
239
+ service: options.service || "vaspera-hardening",
240
+ status: mapSeverityToDatadogStatus(event.severity),
241
+ message: event.message,
242
+ "@timestamp": event.timestamp,
243
+ event_type: event.eventType,
244
+ project: event.project,
245
+ certification_id: event.certificationId,
246
+ data: event.data,
247
+ };
248
+ }
249
+ /**
250
+ * Map SIEM severity to Datadog status
251
+ */
252
+ function mapSeverityToDatadogStatus(severity) {
253
+ switch (severity) {
254
+ case "critical":
255
+ return "emergency";
256
+ case "high":
257
+ return "error";
258
+ case "medium":
259
+ return "warning";
260
+ case "low":
261
+ return "info";
262
+ case "informational":
263
+ return "debug";
264
+ default:
265
+ return "info";
266
+ }
267
+ }
268
+ /**
269
+ * Flatten nested data object for Sentinel
270
+ */
271
+ function flattenData(data, suffix, prefix = "") {
272
+ const result = {};
273
+ for (const [key, value] of Object.entries(data)) {
274
+ const newKey = prefix ? `${prefix}_${key}${suffix}` : `${key}${suffix}`;
275
+ if (value === null || value === undefined) {
276
+ continue;
277
+ }
278
+ if (typeof value === "object" && !Array.isArray(value)) {
279
+ Object.assign(result, flattenData(value, suffix, key));
280
+ }
281
+ else if (Array.isArray(value)) {
282
+ result[newKey] = value.join(",");
283
+ }
284
+ else if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
285
+ result[newKey] = value;
286
+ }
287
+ }
288
+ return result;
289
+ }
290
+ /**
291
+ * Create a finding event
292
+ */
293
+ export function createFindingEvent(project, eventType, finding, certificationId) {
294
+ const actionVerb = eventType === "finding.new" ? "detected" : eventType === "finding.fixed" ? "fixed" : "marked as false positive";
295
+ return {
296
+ timestamp: new Date().toISOString(),
297
+ eventType,
298
+ severity: mapSeverity(finding.severity),
299
+ project,
300
+ certificationId,
301
+ message: `Security finding ${actionVerb}: ${finding.category} in ${finding.file || "unknown"}${finding.line ? `:${finding.line}` : ""}`,
302
+ source: "vaspera",
303
+ data: finding,
304
+ };
305
+ }
306
+ /**
307
+ * Create a scan event
308
+ */
309
+ export function createScanEvent(project, eventType, scan, certificationId) {
310
+ let severity = "informational";
311
+ let message;
312
+ switch (eventType) {
313
+ case "scan.started":
314
+ message = `Security scan started with scanners: ${scan.scanners.join(", ")}`;
315
+ break;
316
+ case "scan.completed":
317
+ severity = scan.bySeverity.critical > 0 ? "critical" : scan.bySeverity.high > 0 ? "high" : "informational";
318
+ message = `Security scan completed: ${scan.findingsCount} findings (${scan.bySeverity.critical} critical, ${scan.bySeverity.high} high)`;
319
+ break;
320
+ case "scan.failed":
321
+ severity = "high";
322
+ message = `Security scan failed: ${scan.error || "Unknown error"}`;
323
+ break;
324
+ }
325
+ return {
326
+ timestamp: new Date().toISOString(),
327
+ eventType,
328
+ severity,
329
+ project,
330
+ certificationId,
331
+ message,
332
+ source: "vaspera",
333
+ data: scan,
334
+ };
335
+ }
336
+ /**
337
+ * Create a certification event
338
+ */
339
+ export function createCertificationEvent(project, eventType, certification) {
340
+ let severity = "informational";
341
+ let message;
342
+ if (eventType === "certification.started") {
343
+ message = `Certification started: ${certification.certificationId}`;
344
+ }
345
+ else {
346
+ severity = certification.score && certification.score >= 80 ? "informational" : "medium";
347
+ message = `Certification completed: ${certification.level || "unknown"} (score: ${certification.score || 0})`;
348
+ }
349
+ return {
350
+ timestamp: new Date().toISOString(),
351
+ eventType,
352
+ severity,
353
+ project,
354
+ certificationId: certification.certificationId,
355
+ message,
356
+ source: "vaspera",
357
+ data: certification,
358
+ };
359
+ }
360
+ //# sourceMappingURL=format.js.map