barrikade-lens 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/runner.js ADDED
@@ -0,0 +1,189 @@
1
+ import os from 'node:os';
2
+ import ora from 'ora';
3
+ import chalk from 'chalk';
4
+ import { auditConfigs, auditWorkspaceArtifacts, auditDependencies } from './scanners/config-auditor.js';
5
+ import { scanPorts } from './scanners/port-scanner.js';
6
+ import { scanProcesses } from './scanners/process-scanner.js';
7
+ import { scanEnvFiles } from './scanners/env-scanner.js';
8
+ import { scanHistory } from './scanners/history-scanner.js';
9
+ import { scanConfigsForSecrets } from './scanners/secret-scanner.js';
10
+ import { analyzeCapabilities } from './utils/analyzer.js';
11
+ import { buildTelemetryPayload, promptTelemetryConsent, sendTelemetry } from './utils/telemetry.js';
12
+ import { displayDashboard } from './ui/dashboard.js';
13
+ import { exportJson } from './exporters/json-exporter.js';
14
+ import { exportHtml } from './exporters/html-exporter.js';
15
+
16
+ /**
17
+ * Executes the full capability-based security audit workflow.
18
+ *
19
+ * @param {{
20
+ * json?: boolean,
21
+ * report?: string,
22
+ * html?: string,
23
+ * telemetry?: boolean,
24
+ * verbose?: boolean
25
+ * }} options Command-line flags
26
+ * @returns {Promise<number>} Exit code (0 if clean, 1 if critical/high vulnerabilities found)
27
+ */
28
+ export async function runAudit(options = {}) {
29
+ const isQuiet = options.json === true;
30
+ const isTelemetryOptOut = options.telemetry === false;
31
+
32
+ let spinner;
33
+ if (!isQuiet) {
34
+ spinner = ora({
35
+ text: 'Scanning workspace structures & active processes...',
36
+ color: 'yellow'
37
+ }).start();
38
+ }
39
+
40
+ try {
41
+ // 1. Audit config files
42
+ if (spinner) spinner.text = 'Auditing Shadow AI config files...';
43
+ const configs = await auditConfigs(process.cwd());
44
+
45
+ // 2. Audit workspace directories & rule files
46
+ if (spinner) spinner.text = 'Sweeping agent workspace structures & rule files...';
47
+ const workspaceArtifacts = await auditWorkspaceArtifacts(process.cwd());
48
+
49
+ // 3. Audit project dependencies
50
+ if (spinner) spinner.text = 'Analyzing project dependencies for agent frameworks...';
51
+ const depFrameworks = await auditDependencies(process.cwd());
52
+
53
+ // 4. Scan active processes
54
+ if (spinner) spinner.text = 'Detecting active AI and model inference processes...';
55
+ const processes = await scanProcesses();
56
+
57
+ // 5. Scan local LLM ports
58
+ if (spinner) spinner.text = 'Checking local model server ports...';
59
+ const ports = await scanPorts(300);
60
+
61
+ // 6. Scan environment files for secrets
62
+ if (spinner) spinner.text = 'Scanning workspace .env files for hardcoded secrets...';
63
+ const envSecrets = await scanEnvFiles(process.cwd());
64
+
65
+ // 7. Scan shell history for secrets & commands
66
+ if (spinner) spinner.text = 'Auditing shell history logs...';
67
+ const history = await scanHistory();
68
+
69
+ // 8. Scan configurations for secrets
70
+ if (spinner) spinner.text = 'Analyzing configuration blocks for plaintext credentials...';
71
+ const configSecrets = await scanConfigsForSecrets(configs);
72
+
73
+ if (spinner) {
74
+ spinner.stop();
75
+ }
76
+
77
+ // Strip rawContent to ensure absolute user privacy in reports
78
+ for (const config of configs) {
79
+ delete config.rawContent;
80
+ }
81
+
82
+ // Merge secrets findings from config files, env files, and shell history
83
+ const mergedSecrets = [
84
+ ...configSecrets,
85
+ ...envSecrets,
86
+ ...history.findings
87
+ ];
88
+
89
+ // 9. Run Capability Analysis
90
+ const capabilityResult = analyzeCapabilities({
91
+ configs,
92
+ workspace: workspaceArtifacts,
93
+ dependencies: depFrameworks,
94
+ processes,
95
+ ports,
96
+ secrets: mergedSecrets,
97
+ history
98
+ });
99
+
100
+ // 10. Calculate metrics summary
101
+ const configsCount = configs.filter(c => c.exists).length;
102
+ const serversCount = configs.reduce((acc, c) => acc + (c.exists ? c.servers.length : 0), 0);
103
+ const portsScanned = ports.length;
104
+ const portsOpen = ports.filter(p => p.open).length;
105
+ const portsExposed = ports.filter(p => p.open && p.exposed).length;
106
+ const secretsCount = mergedSecrets.length;
107
+
108
+ const agentsCount = capabilityResult.agents.length;
109
+ const agentsActive = capabilityResult.agents.filter(a => a.status === 'ACTIVE').length;
110
+ const agentsInstalled = capabilityResult.agents.filter(a => a.status === 'INSTALLED').length;
111
+
112
+ const criticalCount = mergedSecrets.filter(s => s.risk === 'CRITICAL').length + portsExposed;
113
+ const highCount = mergedSecrets.filter(s => s.risk === 'HIGH').length;
114
+ const mediumCount = mergedSecrets.filter(s => s.risk === 'MEDIUM').length + configs.filter(c => c.exists && c.malformed).length;
115
+
116
+ const summary = {
117
+ configsCount,
118
+ serversCount,
119
+ portsScanned,
120
+ portsOpen,
121
+ portsExposed,
122
+ secretsCount,
123
+ criticalCount,
124
+ highCount,
125
+ mediumCount,
126
+ agentsCount,
127
+ agentsActive,
128
+ agentsInstalled
129
+ };
130
+
131
+ const aggregatedResults = {
132
+ version: '0.1.0',
133
+ timestamp: new Date().toISOString(),
134
+ platform: os.platform(),
135
+ summary,
136
+ capabilities: capabilityResult.capabilities,
137
+ evidence: capabilityResult.evidence,
138
+ agents: capabilityResult.agents,
139
+ configs,
140
+ ports,
141
+ secrets: mergedSecrets
142
+ };
143
+
144
+ // 12. Handle output formats
145
+ if (options.json) {
146
+ await exportJson(aggregatedResults);
147
+ } else {
148
+ displayDashboard(aggregatedResults);
149
+ }
150
+
151
+ // Optional exports to files
152
+ if (options.report) {
153
+ await exportJson(aggregatedResults, options.report);
154
+ if (!isQuiet) {
155
+ console.log(chalk.green(`\n✔ JSON report written to: `) + chalk.white(options.report));
156
+ }
157
+ }
158
+
159
+ if (options.html) {
160
+ await exportHtml(aggregatedResults, options.html);
161
+ if (!isQuiet) {
162
+ console.log(chalk.green(`✔ HTML CISO-Report written to: `) + chalk.white(options.html));
163
+ }
164
+ }
165
+
166
+ // 13. Telemetry handling at the very end (prompt for consent or send silently in quiet mode)
167
+ if (!isTelemetryOptOut && process.env.BARRIKADE_NO_TELEMETRY !== '1' && process.env.BARRIKADE_NO_TELEMETRY !== 'true') {
168
+ const telemetryPayload = await buildTelemetryPayload(summary, capabilityResult.capabilities);
169
+ if (options.json) {
170
+ sendTelemetry(telemetryPayload).catch(() => { });
171
+ } else {
172
+ const consented = await promptTelemetryConsent(telemetryPayload, 15000);
173
+ if (consented) {
174
+ await sendTelemetry(telemetryPayload).catch(() => { });
175
+ }
176
+ }
177
+ }
178
+
179
+ // Exit with 1 if there are any CRITICAL or HIGH findings, else 0
180
+ return (criticalCount > 0 || highCount > 0) ? 1 : 0;
181
+ } catch (error) {
182
+ if (spinner) spinner.stop();
183
+ console.error(chalk.red('\n✖ Audit execution failed:'), error.message);
184
+ if (options.verbose) {
185
+ console.error(error);
186
+ }
187
+ return 1;
188
+ }
189
+ }