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,44 @@
1
+ /**
2
+ * Aura Protocol - Base Agent
3
+ *
4
+ * Abstract base class for all agents.
5
+ */
6
+ import { Agent, AgentConfig, AgentCapabilities, AgentStatus, AgentResult } from './types.js';
7
+ import { ZoneContext, ZoneFinding } from '../zones/types.js';
8
+ export declare abstract class BaseAgent implements Agent {
9
+ readonly config: AgentConfig;
10
+ readonly capabilities: AgentCapabilities;
11
+ protected status: AgentStatus;
12
+ constructor(config: AgentConfig, capabilities: AgentCapabilities);
13
+ /**
14
+ * Check if external tool is installed
15
+ */
16
+ protected checkToolAvailable(toolName: string): Promise<boolean>;
17
+ /**
18
+ * Execute a command and return output
19
+ */
20
+ protected executeCommand(command: string, args: string[], options?: {
21
+ cwd?: string;
22
+ timeout?: number;
23
+ }): Promise<{
24
+ stdout: string;
25
+ stderr: string;
26
+ exitCode: number;
27
+ }>;
28
+ /**
29
+ * Check if agent is available
30
+ */
31
+ isAvailable(): Promise<boolean>;
32
+ /**
33
+ * Get current status
34
+ */
35
+ getStatus(): AgentStatus;
36
+ /**
37
+ * Execute the agent
38
+ */
39
+ abstract execute(context: ZoneContext): Promise<AgentResult>;
40
+ /**
41
+ * Helper to create a finding
42
+ */
43
+ protected createFinding(agentId: string, partial: Omit<ZoneFinding, 'id' | 'agentId' | 'timestamp'>): ZoneFinding;
44
+ }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Aura Protocol - Base Agent
3
+ *
4
+ * Abstract base class for all agents.
5
+ */
6
+ import { execSync, spawn } from 'child_process';
7
+ export class BaseAgent {
8
+ config;
9
+ capabilities;
10
+ status = 'idle';
11
+ constructor(config, capabilities) {
12
+ this.config = config;
13
+ this.capabilities = capabilities;
14
+ }
15
+ /**
16
+ * Check if external tool is installed
17
+ */
18
+ async checkToolAvailable(toolName) {
19
+ try {
20
+ execSync(`which ${toolName}`, { stdio: 'ignore' });
21
+ return true;
22
+ }
23
+ catch {
24
+ // Try Windows-style check
25
+ try {
26
+ execSync(`where ${toolName}`, { stdio: 'ignore' });
27
+ return true;
28
+ }
29
+ catch {
30
+ return false;
31
+ }
32
+ }
33
+ }
34
+ /**
35
+ * Execute a command and return output
36
+ */
37
+ async executeCommand(command, args, options = {}) {
38
+ return new Promise((resolve) => {
39
+ const proc = spawn(command, args, {
40
+ cwd: options.cwd,
41
+ shell: true,
42
+ timeout: options.timeout || 300000, // 5 minute default
43
+ });
44
+ let stdout = '';
45
+ let stderr = '';
46
+ proc.stdout?.on('data', (data) => {
47
+ stdout += data.toString();
48
+ });
49
+ proc.stderr?.on('data', (data) => {
50
+ stderr += data.toString();
51
+ });
52
+ proc.on('close', (code) => {
53
+ resolve({
54
+ stdout,
55
+ stderr,
56
+ exitCode: code || 0,
57
+ });
58
+ });
59
+ proc.on('error', (err) => {
60
+ resolve({
61
+ stdout,
62
+ stderr: err.message,
63
+ exitCode: 1,
64
+ });
65
+ });
66
+ });
67
+ }
68
+ /**
69
+ * Check if agent is available
70
+ */
71
+ async isAvailable() {
72
+ if (!this.config.enabled)
73
+ return false;
74
+ if (this.config.externalTool) {
75
+ return this.checkToolAvailable(this.config.externalTool);
76
+ }
77
+ return true;
78
+ }
79
+ /**
80
+ * Get current status
81
+ */
82
+ getStatus() {
83
+ return this.status;
84
+ }
85
+ /**
86
+ * Helper to create a finding
87
+ */
88
+ createFinding(agentId, partial) {
89
+ return {
90
+ ...partial,
91
+ id: `${agentId}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
92
+ agentId,
93
+ timestamp: Date.now(),
94
+ };
95
+ }
96
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Aura Protocol - Agents
3
+ *
4
+ * Export all agents and agent utilities.
5
+ */
6
+ export * from './types.js';
7
+ export * from './base.js';
8
+ export * from './scanners/index.js';
9
+ export * from './policy/index.js';
10
+ import { Agent } from './types.js';
11
+ /**
12
+ * Create all default agents
13
+ */
14
+ export declare function createAllAgents(): Agent[];
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Aura Protocol - Agents
3
+ *
4
+ * Export all agents and agent utilities.
5
+ */
6
+ export * from './types.js';
7
+ export * from './base.js';
8
+ export * from './scanners/index.js';
9
+ export * from './policy/index.js';
10
+ import { createScannerAgents } from './scanners/index.js';
11
+ import { createPolicyAgents } from './policy/index.js';
12
+ /**
13
+ * Create all default agents
14
+ */
15
+ export function createAllAgents() {
16
+ return [...createScannerAgents(), ...createPolicyAgents()];
17
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Aura Protocol - Policy Evaluator Agent
3
+ *
4
+ * Evaluates findings against security policies.
5
+ * This agent provides context-aware analysis of findings.
6
+ */
7
+ import { BaseAgent } from '../base.js';
8
+ import { AgentResult } from '../types.js';
9
+ import { ZoneContext } from '../../zones/types.js';
10
+ export declare class PolicyEvaluatorAgent extends BaseAgent {
11
+ constructor();
12
+ execute(context: ZoneContext): Promise<AgentResult>;
13
+ private evaluateFinding;
14
+ private reduceSeverity;
15
+ }
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Aura Protocol - Policy Evaluator Agent
3
+ *
4
+ * Evaluates findings against security policies.
5
+ * This agent provides context-aware analysis of findings.
6
+ */
7
+ import { BaseAgent } from '../base.js';
8
+ const CONFIG = {
9
+ id: 'policy-evaluator',
10
+ name: 'Policy Evaluator',
11
+ role: 'policy',
12
+ description: 'Evaluate findings against security policies',
13
+ enabled: true,
14
+ };
15
+ const CAPABILITIES = {
16
+ requiresExternalTool: false,
17
+ supportsParallel: false, // Policy evaluation should be sequential
18
+ };
19
+ // File patterns that indicate test/dev context
20
+ const TEST_PATTERNS = [
21
+ /test[s]?\//i,
22
+ /spec[s]?\//i,
23
+ /__test__/i,
24
+ /\.test\./i,
25
+ /\.spec\./i,
26
+ /mock[s]?\//i,
27
+ /fixture[s]?\//i,
28
+ /example[s]?\//i,
29
+ /sample[s]?\//i,
30
+ /demo\//i,
31
+ ];
32
+ // File patterns that indicate generated/vendored code
33
+ const GENERATED_PATTERNS = [
34
+ /node_modules\//i,
35
+ /vendor\//i,
36
+ /dist\//i,
37
+ /build\//i,
38
+ /\.min\./i,
39
+ /bundle\./i,
40
+ /generated\//i,
41
+ ];
42
+ // Packages known to have false positive vulnerabilities or low impact
43
+ const LOW_PRIORITY_PACKAGES = [
44
+ 'lodash', // Often has low-severity prototype pollution
45
+ 'minimist', // Prototype pollution, but rarely exploitable
46
+ 'qs', // Prototype pollution in old versions
47
+ ];
48
+ export class PolicyEvaluatorAgent extends BaseAgent {
49
+ constructor() {
50
+ super(CONFIG, CAPABILITIES);
51
+ }
52
+ async execute(context) {
53
+ const startTime = Date.now();
54
+ this.status = 'running';
55
+ const processedFindings = [];
56
+ try {
57
+ context.log('info', 'Policy Evaluator analyzing findings');
58
+ // Get findings from scanner zone (passed via memory)
59
+ const scannerFindings = context.memory.data.get('scanner_findings') || [];
60
+ if (scannerFindings.length === 0) {
61
+ context.log('info', 'No findings to evaluate');
62
+ this.status = 'complete';
63
+ return {
64
+ agentId: this.config.id,
65
+ agentName: this.config.name,
66
+ status: 'success',
67
+ findings: [],
68
+ duration: Date.now() - startTime,
69
+ };
70
+ }
71
+ context.log('info', `Evaluating ${scannerFindings.length} findings`);
72
+ for (const finding of scannerFindings) {
73
+ const evaluation = this.evaluateFinding(finding);
74
+ // Create annotated finding with policy metadata
75
+ const annotatedFinding = this.createFinding('policy-evaluator', {
76
+ ...finding,
77
+ metadata: {
78
+ ...finding.metadata,
79
+ policyEvaluation: evaluation,
80
+ originalSeverity: finding.severity,
81
+ },
82
+ severity: evaluation.adjustedSeverity,
83
+ });
84
+ // Add context notes
85
+ if (evaluation.notes.length > 0) {
86
+ annotatedFinding.description += `\n\nPolicy Notes:\n${evaluation.notes.map(n => `• ${n}`).join('\n')}`;
87
+ }
88
+ processedFindings.push(annotatedFinding);
89
+ context.addFinding(annotatedFinding);
90
+ }
91
+ // Store evaluated findings for validator
92
+ context.memory.data.set('evaluated_findings', processedFindings);
93
+ this.status = 'complete';
94
+ context.log('info', `Policy evaluation complete: ${processedFindings.length} findings processed`);
95
+ return {
96
+ agentId: this.config.id,
97
+ agentName: this.config.name,
98
+ status: 'success',
99
+ findings: processedFindings,
100
+ duration: Date.now() - startTime,
101
+ };
102
+ }
103
+ catch (error) {
104
+ this.status = 'error';
105
+ const errorMsg = error instanceof Error ? error.message : String(error);
106
+ context.log('error', `Policy evaluation error: ${errorMsg}`);
107
+ return {
108
+ agentId: this.config.id,
109
+ agentName: this.config.name,
110
+ status: 'error',
111
+ findings: processedFindings,
112
+ duration: Date.now() - startTime,
113
+ error: errorMsg,
114
+ };
115
+ }
116
+ }
117
+ evaluateFinding(finding) {
118
+ const notes = [];
119
+ let adjustedSeverity = finding.severity;
120
+ let isTestContext = false;
121
+ let isGenerated = false;
122
+ let shouldSuppress = false;
123
+ const filePath = finding.file || '';
124
+ // Check if in test context
125
+ if (TEST_PATTERNS.some((p) => p.test(filePath))) {
126
+ isTestContext = true;
127
+ notes.push('Found in test/example context - lower priority');
128
+ adjustedSeverity = this.reduceSeverity(adjustedSeverity);
129
+ }
130
+ // Check if generated/vendored
131
+ if (GENERATED_PATTERNS.some((p) => p.test(filePath))) {
132
+ isGenerated = true;
133
+ notes.push('Found in generated/vendored code');
134
+ shouldSuppress = true;
135
+ }
136
+ // Check for low-priority packages
137
+ const pkgName = finding.metadata?.package || '';
138
+ if (LOW_PRIORITY_PACKAGES.some((p) => pkgName.toLowerCase().includes(p))) {
139
+ notes.push(`${pkgName} is known for low-impact vulnerabilities`);
140
+ adjustedSeverity = this.reduceSeverity(adjustedSeverity);
141
+ }
142
+ // Secrets in env.example or sample files are likely intentional
143
+ if (finding.type === 'secret' &&
144
+ /\.(example|sample|template)/i.test(filePath)) {
145
+ notes.push('Secret in example/template file - likely placeholder');
146
+ shouldSuppress = true;
147
+ }
148
+ // Check for fix availability
149
+ const fixAvailable = finding.metadata?.fixAvailable;
150
+ if (fixAvailable === false) {
151
+ notes.push('No fix available yet');
152
+ }
153
+ else if (typeof fixAvailable === 'object' && fixAvailable && 'version' in fixAvailable && fixAvailable.version) {
154
+ notes.push(`Fix available: upgrade to ${fixAvailable.version}`);
155
+ }
156
+ // Direct dependencies are higher priority
157
+ if (finding.metadata?.isDirect === true) {
158
+ notes.push('Direct dependency - higher priority');
159
+ if (finding.severity === 'medium') {
160
+ adjustedSeverity = 'high';
161
+ }
162
+ }
163
+ return {
164
+ adjustedSeverity,
165
+ notes,
166
+ isTestContext,
167
+ isGenerated,
168
+ shouldSuppress,
169
+ };
170
+ }
171
+ reduceSeverity(severity) {
172
+ switch (severity) {
173
+ case 'critical':
174
+ return 'high';
175
+ case 'high':
176
+ return 'medium';
177
+ case 'medium':
178
+ return 'low';
179
+ default:
180
+ return 'info';
181
+ }
182
+ }
183
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Aura Protocol - Policy Agents
3
+ *
4
+ * Export all policy agents.
5
+ */
6
+ export { PolicyEvaluatorAgent } from './evaluator.js';
7
+ export { ValidatorAgent } from './validator.js';
8
+ import { Agent } from '../types.js';
9
+ /**
10
+ * Create all policy agents
11
+ */
12
+ export declare function createPolicyAgents(): Agent[];
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Aura Protocol - Policy Agents
3
+ *
4
+ * Export all policy agents.
5
+ */
6
+ export { PolicyEvaluatorAgent } from './evaluator.js';
7
+ export { ValidatorAgent } from './validator.js';
8
+ import { PolicyEvaluatorAgent } from './evaluator.js';
9
+ import { ValidatorAgent } from './validator.js';
10
+ /**
11
+ * Create all policy agents
12
+ */
13
+ export function createPolicyAgents() {
14
+ return [new PolicyEvaluatorAgent(), new ValidatorAgent()];
15
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Aura Protocol - Validator Agent
3
+ *
4
+ * Validates and deduplicates findings, removes false positives.
5
+ */
6
+ import { BaseAgent } from '../base.js';
7
+ import { AgentResult } from '../types.js';
8
+ import { ZoneContext } from '../../zones/types.js';
9
+ export declare class ValidatorAgent extends BaseAgent {
10
+ constructor();
11
+ execute(context: ZoneContext): Promise<AgentResult>;
12
+ private createFingerprint;
13
+ private isFalsePositive;
14
+ private calculateEntropy;
15
+ }
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Aura Protocol - Validator Agent
3
+ *
4
+ * Validates and deduplicates findings, removes false positives.
5
+ */
6
+ import { BaseAgent } from '../base.js';
7
+ const CONFIG = {
8
+ id: 'validator',
9
+ name: 'Finding Validator',
10
+ role: 'validator',
11
+ description: 'Validate and deduplicate findings, remove false positives',
12
+ enabled: true,
13
+ };
14
+ const CAPABILITIES = {
15
+ requiresExternalTool: false,
16
+ supportsParallel: false,
17
+ };
18
+ // Patterns that indicate false positive secrets
19
+ const FALSE_POSITIVE_PATTERNS = [
20
+ // SHA hashes (commit hashes, file hashes)
21
+ /^[a-f0-9]{40}$/i,
22
+ /^[a-f0-9]{64}$/i,
23
+ // UUIDs
24
+ /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i,
25
+ // NPM package integrity hashes
26
+ /^sha512-/i,
27
+ /^sha256-/i,
28
+ // Example/placeholder values
29
+ /^(xxx|aaa|test|example|sample|placeholder|dummy|fake)/i,
30
+ /^your[-_]?(api[-_]?key|secret|token|password)/i,
31
+ // Version strings
32
+ /^\d+\.\d+\.\d+$/,
33
+ ];
34
+ // File paths that commonly have false positives
35
+ const FALSE_POSITIVE_PATHS = [
36
+ /package-lock\.json$/i,
37
+ /yarn\.lock$/i,
38
+ /pnpm-lock\.yaml$/i,
39
+ /composer\.lock$/i,
40
+ /\.sum$/i,
41
+ /integrity.*\.txt$/i,
42
+ ];
43
+ export class ValidatorAgent extends BaseAgent {
44
+ constructor() {
45
+ super(CONFIG, CAPABILITIES);
46
+ }
47
+ async execute(context) {
48
+ const startTime = Date.now();
49
+ this.status = 'running';
50
+ const validatedFindings = [];
51
+ try {
52
+ context.log('info', 'Validator analyzing findings');
53
+ // Get findings from policy zone
54
+ const evaluatedFindings = context.memory.data.get('evaluated_findings') ||
55
+ context.memory.data.get('scanner_findings') ||
56
+ [];
57
+ if (evaluatedFindings.length === 0) {
58
+ context.log('info', 'No findings to validate');
59
+ this.status = 'complete';
60
+ return {
61
+ agentId: this.config.id,
62
+ agentName: this.config.name,
63
+ status: 'success',
64
+ findings: [],
65
+ duration: Date.now() - startTime,
66
+ };
67
+ }
68
+ context.log('info', `Validating ${evaluatedFindings.length} findings`);
69
+ const seenFindings = new Set();
70
+ let falsePositives = 0;
71
+ let duplicates = 0;
72
+ let suppressed = 0;
73
+ for (const finding of evaluatedFindings) {
74
+ // Check for duplicates
75
+ const fingerprint = this.createFingerprint(finding);
76
+ if (seenFindings.has(fingerprint)) {
77
+ duplicates++;
78
+ continue;
79
+ }
80
+ seenFindings.add(fingerprint);
81
+ // Check if suppressed by policy
82
+ if (finding.metadata?.policyEvaluation?.shouldSuppress) {
83
+ suppressed++;
84
+ continue;
85
+ }
86
+ // Check for false positives
87
+ if (this.isFalsePositive(finding)) {
88
+ falsePositives++;
89
+ continue;
90
+ }
91
+ // Valid finding
92
+ const validatedFinding = this.createFinding('validator', {
93
+ ...finding,
94
+ metadata: {
95
+ ...finding.metadata,
96
+ validated: true,
97
+ fingerprint,
98
+ },
99
+ });
100
+ validatedFindings.push(validatedFinding);
101
+ context.addFinding(validatedFinding);
102
+ }
103
+ // Store validated findings
104
+ context.memory.data.set('validated_findings', validatedFindings);
105
+ this.status = 'complete';
106
+ context.log('info', `Validation complete: ${validatedFindings.length} valid, ` +
107
+ `${falsePositives} false positives, ${duplicates} duplicates, ${suppressed} suppressed`);
108
+ return {
109
+ agentId: this.config.id,
110
+ agentName: this.config.name,
111
+ status: 'success',
112
+ findings: validatedFindings,
113
+ duration: Date.now() - startTime,
114
+ };
115
+ }
116
+ catch (error) {
117
+ this.status = 'error';
118
+ const errorMsg = error instanceof Error ? error.message : String(error);
119
+ context.log('error', `Validation error: ${errorMsg}`);
120
+ return {
121
+ agentId: this.config.id,
122
+ agentName: this.config.name,
123
+ status: 'error',
124
+ findings: validatedFindings,
125
+ duration: Date.now() - startTime,
126
+ error: errorMsg,
127
+ };
128
+ }
129
+ }
130
+ createFingerprint(finding) {
131
+ // Create a unique fingerprint for deduplication
132
+ const parts = [
133
+ finding.type,
134
+ finding.file || '',
135
+ finding.line?.toString() || '',
136
+ finding.title,
137
+ finding.metadata?.vulnerabilityId || '',
138
+ finding.metadata?.package || '',
139
+ ];
140
+ return parts.join('::').toLowerCase();
141
+ }
142
+ isFalsePositive(finding) {
143
+ const filePath = finding.file || '';
144
+ // Check file path patterns
145
+ if (FALSE_POSITIVE_PATHS.some((p) => p.test(filePath))) {
146
+ return true;
147
+ }
148
+ // Check secret-specific false positives
149
+ if (finding.type === 'secret') {
150
+ const match = finding.metadata?.match || '';
151
+ // Check against false positive patterns
152
+ if (FALSE_POSITIVE_PATTERNS.some((p) => p.test(match))) {
153
+ return true;
154
+ }
155
+ // Very short matches are likely false positives
156
+ if (match.length < 16) {
157
+ return true;
158
+ }
159
+ // Check for low entropy (unlikely to be real secrets)
160
+ const entropy = this.calculateEntropy(match);
161
+ if (entropy < 2.5) {
162
+ return true;
163
+ }
164
+ }
165
+ return false;
166
+ }
167
+ calculateEntropy(str) {
168
+ const len = str.length;
169
+ if (len === 0)
170
+ return 0;
171
+ const freq = {};
172
+ for (const char of str) {
173
+ freq[char] = (freq[char] || 0) + 1;
174
+ }
175
+ let entropy = 0;
176
+ for (const count of Object.values(freq)) {
177
+ const p = count / len;
178
+ entropy -= p * Math.log2(p);
179
+ }
180
+ return entropy;
181
+ }
182
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Aura Protocol - Gitleaks Agent
3
+ *
4
+ * Scans for secrets and API keys using gitleaks.
5
+ */
6
+ import { BaseAgent } from '../base.js';
7
+ import { AgentResult } from '../types.js';
8
+ import { ZoneContext } from '../../zones/types.js';
9
+ export declare class GitleaksAgent extends BaseAgent {
10
+ constructor();
11
+ execute(context: ZoneContext): Promise<AgentResult>;
12
+ private getSeverity;
13
+ private maskSecret;
14
+ }