aura-security 0.4.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 (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +446 -0
  3. package/deploy/AWS-DEPLOYMENT.md +358 -0
  4. package/deploy/terraform/main.tf +362 -0
  5. package/deploy/terraform/terraform.tfvars.example +6 -0
  6. package/dist/agents/base.d.ts +44 -0
  7. package/dist/agents/base.js +96 -0
  8. package/dist/agents/index.d.ts +14 -0
  9. package/dist/agents/index.js +17 -0
  10. package/dist/agents/policy/evaluator.d.ts +15 -0
  11. package/dist/agents/policy/evaluator.js +183 -0
  12. package/dist/agents/policy/index.d.ts +12 -0
  13. package/dist/agents/policy/index.js +15 -0
  14. package/dist/agents/policy/validator.d.ts +15 -0
  15. package/dist/agents/policy/validator.js +182 -0
  16. package/dist/agents/scanners/gitleaks.d.ts +14 -0
  17. package/dist/agents/scanners/gitleaks.js +155 -0
  18. package/dist/agents/scanners/grype.d.ts +14 -0
  19. package/dist/agents/scanners/grype.js +109 -0
  20. package/dist/agents/scanners/index.d.ts +15 -0
  21. package/dist/agents/scanners/index.js +27 -0
  22. package/dist/agents/scanners/npm-audit.d.ts +13 -0
  23. package/dist/agents/scanners/npm-audit.js +129 -0
  24. package/dist/agents/scanners/semgrep.d.ts +14 -0
  25. package/dist/agents/scanners/semgrep.js +131 -0
  26. package/dist/agents/scanners/trivy.d.ts +14 -0
  27. package/dist/agents/scanners/trivy.js +122 -0
  28. package/dist/agents/types.d.ts +137 -0
  29. package/dist/agents/types.js +91 -0
  30. package/dist/auditor/index.d.ts +3 -0
  31. package/dist/auditor/index.js +2 -0
  32. package/dist/auditor/pipeline.d.ts +19 -0
  33. package/dist/auditor/pipeline.js +240 -0
  34. package/dist/auditor/validator.d.ts +17 -0
  35. package/dist/auditor/validator.js +58 -0
  36. package/dist/aura/client.d.ts +29 -0
  37. package/dist/aura/client.js +125 -0
  38. package/dist/aura/index.d.ts +4 -0
  39. package/dist/aura/index.js +2 -0
  40. package/dist/aura/server.d.ts +45 -0
  41. package/dist/aura/server.js +343 -0
  42. package/dist/cli.d.ts +17 -0
  43. package/dist/cli.js +1433 -0
  44. package/dist/client/index.d.ts +41 -0
  45. package/dist/client/index.js +170 -0
  46. package/dist/compliance/index.d.ts +40 -0
  47. package/dist/compliance/index.js +292 -0
  48. package/dist/database/index.d.ts +77 -0
  49. package/dist/database/index.js +395 -0
  50. package/dist/index.d.ts +25 -0
  51. package/dist/index.js +762 -0
  52. package/dist/integrations/aura-scanner.d.ts +69 -0
  53. package/dist/integrations/aura-scanner.js +155 -0
  54. package/dist/integrations/aws-scanner.d.ts +63 -0
  55. package/dist/integrations/aws-scanner.js +624 -0
  56. package/dist/integrations/config.d.ts +69 -0
  57. package/dist/integrations/config.js +212 -0
  58. package/dist/integrations/github.d.ts +45 -0
  59. package/dist/integrations/github.js +201 -0
  60. package/dist/integrations/gitlab.d.ts +36 -0
  61. package/dist/integrations/gitlab.js +110 -0
  62. package/dist/integrations/index.d.ts +11 -0
  63. package/dist/integrations/index.js +11 -0
  64. package/dist/integrations/local-scanner.d.ts +146 -0
  65. package/dist/integrations/local-scanner.js +1654 -0
  66. package/dist/integrations/notifications.d.ts +99 -0
  67. package/dist/integrations/notifications.js +305 -0
  68. package/dist/integrations/scanners.d.ts +57 -0
  69. package/dist/integrations/scanners.js +217 -0
  70. package/dist/integrations/slop-scanner.d.ts +69 -0
  71. package/dist/integrations/slop-scanner.js +155 -0
  72. package/dist/integrations/webhook.d.ts +37 -0
  73. package/dist/integrations/webhook.js +256 -0
  74. package/dist/orchestrator/index.d.ts +72 -0
  75. package/dist/orchestrator/index.js +187 -0
  76. package/dist/output/index.d.ts +152 -0
  77. package/dist/output/index.js +399 -0
  78. package/dist/pipeline/index.d.ts +72 -0
  79. package/dist/pipeline/index.js +313 -0
  80. package/dist/sbom/index.d.ts +94 -0
  81. package/dist/sbom/index.js +298 -0
  82. package/dist/schemas/index.d.ts +2 -0
  83. package/dist/schemas/index.js +2 -0
  84. package/dist/schemas/input.schema.d.ts +87 -0
  85. package/dist/schemas/input.schema.js +44 -0
  86. package/dist/schemas/output.schema.d.ts +115 -0
  87. package/dist/schemas/output.schema.js +64 -0
  88. package/dist/serve-visualizer.d.ts +2 -0
  89. package/dist/serve-visualizer.js +78 -0
  90. package/dist/slop/client.d.ts +29 -0
  91. package/dist/slop/client.js +125 -0
  92. package/dist/slop/index.d.ts +4 -0
  93. package/dist/slop/index.js +2 -0
  94. package/dist/slop/server.d.ts +45 -0
  95. package/dist/slop/server.js +343 -0
  96. package/dist/types/events.d.ts +62 -0
  97. package/dist/types/events.js +2 -0
  98. package/dist/types/index.d.ts +1 -0
  99. package/dist/types/index.js +1 -0
  100. package/dist/visualizer/index.d.ts +4 -0
  101. package/dist/visualizer/index.js +181 -0
  102. package/dist/websocket/index.d.ts +88 -0
  103. package/dist/websocket/index.js +195 -0
  104. package/dist/zones/index.d.ts +7 -0
  105. package/dist/zones/index.js +7 -0
  106. package/dist/zones/manager.d.ts +101 -0
  107. package/dist/zones/manager.js +304 -0
  108. package/dist/zones/types.d.ts +78 -0
  109. package/dist/zones/types.js +33 -0
  110. package/package.json +84 -0
  111. package/visualizer/app.js +0 -0
  112. package/visualizer/index-minimal.html +1771 -0
  113. package/visualizer/index.html +2933 -0
  114. package/visualizer/landing.html +1328 -0
  115. package/visualizer/styles.css +0 -0
@@ -0,0 +1,69 @@
1
+ /**
2
+ * SLOP Protocol Scanner
3
+ *
4
+ * Wrapper that uses the SLOP Protocol multi-agent architecture
5
+ * while maintaining backward compatibility with the existing scanner interface.
6
+ */
7
+ import { orchestrator, OrchestratorResult } from '../orchestrator/index.js';
8
+ import { ZoneFinding } from '../zones/types.js';
9
+ import type { LocalScanResult } from './local-scanner.js';
10
+ export interface SlopScanConfig {
11
+ targetPath: string;
12
+ fullScan?: boolean;
13
+ enableScannerZone?: boolean;
14
+ enablePolicyZone?: boolean;
15
+ }
16
+ export interface SlopScanResult {
17
+ legacy: LocalScanResult;
18
+ slop: {
19
+ zones: Array<{
20
+ id: string;
21
+ name: string;
22
+ type: string;
23
+ color: string;
24
+ status: string;
25
+ findingCount: number;
26
+ duration: number;
27
+ }>;
28
+ agents: Array<{
29
+ id: string;
30
+ name: string;
31
+ role: string;
32
+ status: string;
33
+ findingCount: number;
34
+ duration: number;
35
+ }>;
36
+ findings: ZoneFinding[];
37
+ summary: OrchestratorResult['summary'];
38
+ };
39
+ }
40
+ /**
41
+ * Run a security scan using the SLOP Protocol architecture
42
+ */
43
+ export declare function slopScan(config: SlopScanConfig): Promise<SlopScanResult>;
44
+ /**
45
+ * Get orchestrator state for visualization
46
+ */
47
+ export declare function getSlopState(): {
48
+ zones: Array<{
49
+ id: string;
50
+ name: string;
51
+ type: string;
52
+ color: string;
53
+ status: import("../zones/types.js").ZoneStatus;
54
+ agentCount: number;
55
+ findingCount: number;
56
+ }>;
57
+ agents: Array<{
58
+ id: string;
59
+ name: string;
60
+ role: string;
61
+ zoneId: string | null;
62
+ status: string;
63
+ }>;
64
+ };
65
+ /**
66
+ * Get available agents
67
+ */
68
+ export declare function getAvailableAgents(): Promise<import("../agents/types.js").Agent[]>;
69
+ export { orchestrator };
@@ -0,0 +1,155 @@
1
+ /**
2
+ * SLOP Protocol Scanner
3
+ *
4
+ * Wrapper that uses the SLOP Protocol multi-agent architecture
5
+ * while maintaining backward compatibility with the existing scanner interface.
6
+ */
7
+ import * as os from 'os';
8
+ import { orchestrator } from '../orchestrator/index.js';
9
+ /**
10
+ * Run a security scan using the SLOP Protocol architecture
11
+ */
12
+ export async function slopScan(config) {
13
+ console.log('[SLOP] Starting SLOP Protocol scan...');
14
+ console.log(`[SLOP] Target: ${config.targetPath}`);
15
+ // Run orchestrator
16
+ const result = config.fullScan !== false
17
+ ? await orchestrator.fullScan(config.targetPath)
18
+ : await orchestrator.quickScan(config.targetPath);
19
+ console.log(`[SLOP] Scan complete in ${result.duration}ms`);
20
+ console.log(`[SLOP] Agents used: ${result.summary.agentsUsed.join(', ')}`);
21
+ console.log(`[SLOP] Total findings: ${result.summary.totalFindings}`);
22
+ // Convert to legacy format
23
+ const legacy = convertToLegacyFormat(result);
24
+ // Build SLOP format with zone info
25
+ const zones = Array.from(result.zoneResults.entries()).map(([zoneId, zoneResult]) => ({
26
+ id: zoneId,
27
+ name: zoneResult.zoneName,
28
+ type: zoneResult.zoneType,
29
+ color: getZoneColor(zoneResult.zoneType),
30
+ status: zoneResult.status,
31
+ findingCount: zoneResult.findings.length,
32
+ duration: zoneResult.duration,
33
+ }));
34
+ const agents = Array.from(result.zoneResults.values()).flatMap((zoneResult) => zoneResult.agentResults.map((agentResult) => ({
35
+ id: agentResult.agentId,
36
+ name: agentResult.agentName,
37
+ role: getAgentRole(agentResult.agentId),
38
+ status: agentResult.status,
39
+ findingCount: agentResult.findings.length,
40
+ duration: agentResult.duration,
41
+ })));
42
+ return {
43
+ legacy,
44
+ slop: {
45
+ zones,
46
+ agents,
47
+ findings: result.findings,
48
+ summary: result.summary,
49
+ },
50
+ };
51
+ }
52
+ /**
53
+ * Convert orchestrator result to legacy LocalScanResult format
54
+ */
55
+ function convertToLegacyFormat(result) {
56
+ const secrets = [];
57
+ const packages = [];
58
+ const sastFindings = [];
59
+ const iacFindings = [];
60
+ for (const finding of result.findings) {
61
+ if (finding.type === 'secret') {
62
+ secrets.push({
63
+ file: finding.file || '',
64
+ line: finding.line || 0,
65
+ type: finding.title,
66
+ snippet: finding.metadata?.match || '***',
67
+ severity: finding.severity,
68
+ });
69
+ }
70
+ else if (finding.type === 'vulnerability') {
71
+ packages.push({
72
+ name: finding.metadata?.package || finding.title,
73
+ version: finding.metadata?.installedVersion || finding.metadata?.version || 'unknown',
74
+ vulnerabilities: 1,
75
+ severity: finding.severity,
76
+ vulnId: finding.metadata?.vulnerabilityId || undefined,
77
+ title: finding.title,
78
+ fixedVersion: finding.metadata?.fixedVersion || finding.metadata?.fixVersions?.[0],
79
+ });
80
+ }
81
+ else if (finding.type === 'policy_violation') {
82
+ // Map policy violations to SAST findings
83
+ sastFindings.push({
84
+ file: finding.file || '',
85
+ line: finding.line || 0,
86
+ rule: finding.title,
87
+ message: finding.description,
88
+ severity: finding.severity,
89
+ });
90
+ }
91
+ }
92
+ return {
93
+ path: result.targetPath,
94
+ timestamp: new Date().toISOString(),
95
+ secrets,
96
+ packages,
97
+ sastFindings,
98
+ iacFindings,
99
+ dockerfileFindings: [],
100
+ gitInfo: null,
101
+ envFiles: [],
102
+ systemInfo: {
103
+ platform: process.platform,
104
+ hostname: os.hostname(),
105
+ user: os.userInfo().username,
106
+ nodeVersion: process.version,
107
+ cwd: process.cwd(),
108
+ },
109
+ discoveredServices: [],
110
+ discoveredModules: [],
111
+ toolsUsed: result.summary.agentsUsed,
112
+ languagesDetected: [],
113
+ };
114
+ }
115
+ function getZoneColor(zoneType) {
116
+ switch (zoneType) {
117
+ case 'scanner':
118
+ return '#22c55e'; // Green
119
+ case 'policy':
120
+ return '#ef4444'; // Red
121
+ case 'reporting':
122
+ return '#3b82f6'; // Blue
123
+ default:
124
+ return '#888888';
125
+ }
126
+ }
127
+ function getAgentRole(agentId) {
128
+ const scannerAgents = ['gitleaks', 'trivy', 'semgrep', 'grype', 'npm-audit'];
129
+ const policyAgents = ['policy-evaluator', 'validator'];
130
+ const reporterAgents = ['sarif-reporter'];
131
+ const notifierAgents = ['slack-notifier', 'discord-notifier'];
132
+ if (scannerAgents.includes(agentId))
133
+ return 'scanner';
134
+ if (policyAgents.includes(agentId))
135
+ return 'policy';
136
+ if (reporterAgents.includes(agentId))
137
+ return 'reporter';
138
+ if (notifierAgents.includes(agentId))
139
+ return 'notifier';
140
+ return 'unknown';
141
+ }
142
+ /**
143
+ * Get orchestrator state for visualization
144
+ */
145
+ export function getSlopState() {
146
+ return orchestrator.getState();
147
+ }
148
+ /**
149
+ * Get available agents
150
+ */
151
+ export async function getAvailableAgents() {
152
+ return orchestrator.getAvailableAgents();
153
+ }
154
+ // Export orchestrator for direct access
155
+ export { orchestrator };
@@ -0,0 +1,37 @@
1
+ import type { AuditorInput } from '../types/events.js';
2
+ export interface WebhookConfig {
3
+ port: number;
4
+ secret?: string;
5
+ allowedSources?: string[];
6
+ }
7
+ export interface WebhookEvent {
8
+ source: 'github' | 'gitlab' | 'jenkins' | 'custom';
9
+ type: string;
10
+ payload: Record<string, unknown>;
11
+ timestamp: string;
12
+ signature?: string;
13
+ }
14
+ export type WebhookHandler = (event: WebhookEvent) => Promise<AuditorInput | null>;
15
+ export declare class WebhookServer {
16
+ private server;
17
+ private config;
18
+ private handlers;
19
+ private onAuditRequest;
20
+ constructor(config: WebhookConfig);
21
+ registerHandler(eventType: string, handler: WebhookHandler): void;
22
+ onAudit(callback: (input: AuditorInput) => Promise<void>): void;
23
+ private handleRequest;
24
+ private detectSource;
25
+ private getSignature;
26
+ private getEventType;
27
+ private verifySignature;
28
+ private readBody;
29
+ start(): Promise<void>;
30
+ stop(): Promise<void>;
31
+ }
32
+ export declare const defaultHandlers: {
33
+ 'github:pull_request': (event: WebhookEvent) => Promise<AuditorInput | null>;
34
+ 'github:push': (event: WebhookEvent) => Promise<AuditorInput | null>;
35
+ 'gitlab:merge_request': (event: WebhookEvent) => Promise<AuditorInput | null>;
36
+ 'jenkins:build': (event: WebhookEvent) => Promise<AuditorInput | null>;
37
+ };
@@ -0,0 +1,256 @@
1
+ // Webhook Server - Receive events from external systems
2
+ // Supports GitHub, GitLab, Jenkins, and custom webhooks
3
+ import { createServer } from 'http';
4
+ import { createHmac } from 'crypto';
5
+ export class WebhookServer {
6
+ server = null;
7
+ config;
8
+ handlers = new Map();
9
+ onAuditRequest = null;
10
+ constructor(config) {
11
+ this.config = config;
12
+ }
13
+ // Register handler for specific event types
14
+ registerHandler(eventType, handler) {
15
+ this.handlers.set(eventType, handler);
16
+ }
17
+ // Set callback for when audit should be triggered
18
+ onAudit(callback) {
19
+ this.onAuditRequest = callback;
20
+ }
21
+ async handleRequest(req, res) {
22
+ // CORS
23
+ res.setHeader('Access-Control-Allow-Origin', '*');
24
+ res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
25
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-Hub-Signature-256, X-GitLab-Token');
26
+ res.setHeader('Content-Type', 'application/json');
27
+ if (req.method === 'OPTIONS') {
28
+ res.statusCode = 204;
29
+ res.end();
30
+ return;
31
+ }
32
+ if (req.method !== 'POST') {
33
+ res.statusCode = 405;
34
+ res.end(JSON.stringify({ error: 'Method not allowed' }));
35
+ return;
36
+ }
37
+ const url = new URL(req.url ?? '/', `http://${req.headers.host}`);
38
+ const path = url.pathname;
39
+ try {
40
+ const body = await this.readBody(req);
41
+ const payload = JSON.parse(body);
42
+ // Detect source and verify signature
43
+ const source = this.detectSource(req, path);
44
+ const signature = this.getSignature(req);
45
+ if (this.config.secret && !this.verifySignature(body, signature, source)) {
46
+ res.statusCode = 401;
47
+ res.end(JSON.stringify({ error: 'Invalid signature' }));
48
+ return;
49
+ }
50
+ // Create webhook event
51
+ const event = {
52
+ source,
53
+ type: this.getEventType(req, source, payload),
54
+ payload,
55
+ timestamp: new Date().toISOString(),
56
+ signature
57
+ };
58
+ console.log(`[Webhook] Received ${event.source}:${event.type}`);
59
+ // Find handler
60
+ const handler = this.handlers.get(`${event.source}:${event.type}`) ||
61
+ this.handlers.get(event.source) ||
62
+ this.handlers.get('*');
63
+ if (handler) {
64
+ const auditInput = await handler(event);
65
+ if (auditInput && this.onAuditRequest) {
66
+ await this.onAuditRequest(auditInput);
67
+ res.statusCode = 200;
68
+ res.end(JSON.stringify({ status: 'audit_triggered', event_id: auditInput.change_event.id }));
69
+ return;
70
+ }
71
+ }
72
+ res.statusCode = 200;
73
+ res.end(JSON.stringify({ status: 'received', processed: !!handler }));
74
+ }
75
+ catch (err) {
76
+ console.error('[Webhook] Error:', err);
77
+ res.statusCode = 500;
78
+ res.end(JSON.stringify({ error: 'Internal error' }));
79
+ }
80
+ }
81
+ detectSource(req, path) {
82
+ if (req.headers['x-github-event'] || path.includes('github'))
83
+ return 'github';
84
+ if (req.headers['x-gitlab-event'] || path.includes('gitlab'))
85
+ return 'gitlab';
86
+ if (req.headers['x-jenkins-event'] || path.includes('jenkins'))
87
+ return 'jenkins';
88
+ return 'custom';
89
+ }
90
+ getSignature(req) {
91
+ return req.headers['x-hub-signature-256'] ||
92
+ req.headers['x-gitlab-token'] ||
93
+ req.headers['x-signature'];
94
+ }
95
+ getEventType(req, source, payload) {
96
+ if (source === 'github') {
97
+ return req.headers['x-github-event'] || 'unknown';
98
+ }
99
+ if (source === 'gitlab') {
100
+ return payload.object_kind || req.headers['x-gitlab-event'] || 'unknown';
101
+ }
102
+ if (source === 'jenkins') {
103
+ const build = payload.build;
104
+ return build?.phase || 'build';
105
+ }
106
+ return payload.type || 'unknown';
107
+ }
108
+ verifySignature(body, signature, source) {
109
+ if (!signature || !this.config.secret)
110
+ return false;
111
+ if (source === 'github') {
112
+ const expected = 'sha256=' + createHmac('sha256', this.config.secret).update(body).digest('hex');
113
+ return signature === expected;
114
+ }
115
+ if (source === 'gitlab') {
116
+ return signature === this.config.secret;
117
+ }
118
+ // Generic HMAC verification
119
+ const expected = createHmac('sha256', this.config.secret).update(body).digest('hex');
120
+ return signature === expected;
121
+ }
122
+ readBody(req) {
123
+ return new Promise((resolve, reject) => {
124
+ const chunks = [];
125
+ req.on('data', chunk => chunks.push(chunk));
126
+ req.on('end', () => resolve(Buffer.concat(chunks).toString()));
127
+ req.on('error', reject);
128
+ });
129
+ }
130
+ async start() {
131
+ return new Promise((resolve, reject) => {
132
+ this.server = createServer((req, res) => {
133
+ this.handleRequest(req, res).catch(() => {
134
+ res.statusCode = 500;
135
+ res.end(JSON.stringify({ error: 'Internal error' }));
136
+ });
137
+ });
138
+ this.server.on('error', reject);
139
+ this.server.listen(this.config.port, '0.0.0.0', () => {
140
+ console.log(`[Webhook] Server listening on port ${this.config.port}`);
141
+ resolve();
142
+ });
143
+ });
144
+ }
145
+ async stop() {
146
+ return new Promise((resolve) => {
147
+ if (this.server) {
148
+ this.server.close(() => resolve());
149
+ }
150
+ else {
151
+ resolve();
152
+ }
153
+ });
154
+ }
155
+ }
156
+ // Default handlers for common webhook types
157
+ export const defaultHandlers = {
158
+ // GitHub Pull Request
159
+ 'github:pull_request': async (event) => {
160
+ const pr = event.payload.pull_request;
161
+ const repo = event.payload.repository;
162
+ const action = event.payload.action;
163
+ if (!['opened', 'synchronize', 'reopened'].includes(action)) {
164
+ return null;
165
+ }
166
+ return {
167
+ change_event: {
168
+ id: `github-pr-${pr.number}`,
169
+ type: 'pull_request',
170
+ environment: pr.base?.ref === 'main' ? 'prod' : 'staging',
171
+ repo: repo.full_name,
172
+ commit: pr.head?.sha,
173
+ files_changed: [], // Would need separate API call
174
+ diff: '' // Would need separate API call
175
+ },
176
+ evidence_bundle: {},
177
+ policy_context: {
178
+ critical_assets: ['auth', 'billing', 'database', 'secrets'],
179
+ risk_tolerance: 'medium'
180
+ }
181
+ };
182
+ },
183
+ // GitHub Push
184
+ 'github:push': async (event) => {
185
+ const repo = event.payload.repository;
186
+ const commits = event.payload.commits || [];
187
+ const ref = event.payload.ref;
188
+ const isProd = ref === 'refs/heads/main' || ref === 'refs/heads/master';
189
+ return {
190
+ change_event: {
191
+ id: `github-push-${event.payload.after}`,
192
+ type: isProd ? 'deploy' : 'pull_request',
193
+ environment: isProd ? 'prod' : 'dev',
194
+ repo: repo.full_name,
195
+ commit: event.payload.after,
196
+ files_changed: commits.flatMap(c => [
197
+ ...(c.added || []),
198
+ ...(c.modified || [])
199
+ ]),
200
+ diff: commits.map(c => c.message).join('\n')
201
+ },
202
+ evidence_bundle: {},
203
+ policy_context: {
204
+ critical_assets: ['auth', 'billing', 'database', 'secrets'],
205
+ risk_tolerance: isProd ? 'low' : 'medium'
206
+ }
207
+ };
208
+ },
209
+ // GitLab Merge Request
210
+ 'gitlab:merge_request': async (event) => {
211
+ const mr = event.payload.object_attributes;
212
+ const project = event.payload.project;
213
+ if (!['open', 'reopen', 'update'].includes(mr.action)) {
214
+ return null;
215
+ }
216
+ return {
217
+ change_event: {
218
+ id: `gitlab-mr-${mr.iid}`,
219
+ type: 'pull_request',
220
+ environment: mr.target_branch === 'main' ? 'prod' : 'staging',
221
+ repo: project.path_with_namespace,
222
+ commit: mr.last_commit,
223
+ files_changed: [],
224
+ diff: ''
225
+ },
226
+ evidence_bundle: {},
227
+ policy_context: {
228
+ critical_assets: ['auth', 'billing', 'database', 'secrets'],
229
+ risk_tolerance: 'medium'
230
+ }
231
+ };
232
+ },
233
+ // Jenkins Build
234
+ 'jenkins:build': async (event) => {
235
+ const build = event.payload.build || {};
236
+ const params = build.parameters || {};
237
+ const envVal = params.ENVIRONMENT;
238
+ const environment = (envVal === 'prod' || envVal === 'staging' || envVal === 'dev') ? envVal : 'staging';
239
+ return {
240
+ change_event: {
241
+ id: `jenkins-${build.number || Date.now()}`,
242
+ type: 'deploy',
243
+ environment,
244
+ repo: event.payload.name || 'unknown',
245
+ commit: build.scm?.commit || '',
246
+ files_changed: [],
247
+ diff: ''
248
+ },
249
+ evidence_bundle: {},
250
+ policy_context: {
251
+ critical_assets: ['auth', 'billing', 'database', 'secrets'],
252
+ risk_tolerance: 'medium'
253
+ }
254
+ };
255
+ }
256
+ };
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Aura Protocol - Parallel Orchestrator
3
+ *
4
+ * Orchestrates parallel execution of zones and manages data flow between them.
5
+ * This is the main entry point for running security scans using the Aura architecture.
6
+ */
7
+ import { EventEmitter } from 'events';
8
+ import { ZoneManager } from '../zones/manager.js';
9
+ import { ZoneConfig, ZoneResult, ZoneFinding } from '../zones/types.js';
10
+ import { Agent } from '../agents/types.js';
11
+ export interface OrchestratorConfig {
12
+ targetPath: string;
13
+ zones?: string[];
14
+ runPolicyZone?: boolean;
15
+ customZones?: ZoneConfig[];
16
+ }
17
+ export interface OrchestratorResult {
18
+ success: boolean;
19
+ duration: number;
20
+ targetPath: string;
21
+ zoneResults: Map<string, ZoneResult>;
22
+ findings: ZoneFinding[];
23
+ summary: {
24
+ totalFindings: number;
25
+ byType: Record<string, number>;
26
+ bySeverity: Record<string, number>;
27
+ byZone: Record<string, number>;
28
+ agentsUsed: string[];
29
+ };
30
+ }
31
+ export declare class ParallelOrchestrator extends EventEmitter {
32
+ private manager;
33
+ private agents;
34
+ private initialized;
35
+ constructor(manager?: ZoneManager);
36
+ /**
37
+ * Initialize the orchestrator with all agents
38
+ */
39
+ initialize(): Promise<void>;
40
+ /**
41
+ * Run a full security scan using Aura Protocol
42
+ *
43
+ * Execution flow:
44
+ * 1. Scanner Zone - Run all scanners in parallel
45
+ * 2. Policy Zone - Evaluate and validate findings (sequential)
46
+ */
47
+ scan(config: OrchestratorConfig): Promise<OrchestratorResult>;
48
+ /**
49
+ * Run only the scanner zone (faster, no policy evaluation)
50
+ */
51
+ quickScan(targetPath: string): Promise<OrchestratorResult>;
52
+ /**
53
+ * Run a full scan with policy evaluation
54
+ */
55
+ fullScan(targetPath: string): Promise<OrchestratorResult>;
56
+ /**
57
+ * Get available agents
58
+ */
59
+ getAvailableAgents(): Promise<Agent[]>;
60
+ /**
61
+ * Get current state for visualization
62
+ */
63
+ getState(): ReturnType<ZoneManager['exportState']>;
64
+ /**
65
+ * Reset all zones
66
+ */
67
+ reset(): void;
68
+ private buildSummary;
69
+ }
70
+ export declare const orchestrator: ParallelOrchestrator;
71
+ export * from '../zones/types.js';
72
+ export * from '../zones/manager.js';