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.
- package/LICENSE +21 -0
- package/README.md +446 -0
- package/deploy/AWS-DEPLOYMENT.md +358 -0
- package/deploy/terraform/main.tf +362 -0
- package/deploy/terraform/terraform.tfvars.example +6 -0
- package/dist/agents/base.d.ts +44 -0
- package/dist/agents/base.js +96 -0
- package/dist/agents/index.d.ts +14 -0
- package/dist/agents/index.js +17 -0
- package/dist/agents/policy/evaluator.d.ts +15 -0
- package/dist/agents/policy/evaluator.js +183 -0
- package/dist/agents/policy/index.d.ts +12 -0
- package/dist/agents/policy/index.js +15 -0
- package/dist/agents/policy/validator.d.ts +15 -0
- package/dist/agents/policy/validator.js +182 -0
- package/dist/agents/scanners/gitleaks.d.ts +14 -0
- package/dist/agents/scanners/gitleaks.js +155 -0
- package/dist/agents/scanners/grype.d.ts +14 -0
- package/dist/agents/scanners/grype.js +109 -0
- package/dist/agents/scanners/index.d.ts +15 -0
- package/dist/agents/scanners/index.js +27 -0
- package/dist/agents/scanners/npm-audit.d.ts +13 -0
- package/dist/agents/scanners/npm-audit.js +129 -0
- package/dist/agents/scanners/semgrep.d.ts +14 -0
- package/dist/agents/scanners/semgrep.js +131 -0
- package/dist/agents/scanners/trivy.d.ts +14 -0
- package/dist/agents/scanners/trivy.js +122 -0
- package/dist/agents/types.d.ts +137 -0
- package/dist/agents/types.js +91 -0
- package/dist/auditor/index.d.ts +3 -0
- package/dist/auditor/index.js +2 -0
- package/dist/auditor/pipeline.d.ts +19 -0
- package/dist/auditor/pipeline.js +240 -0
- package/dist/auditor/validator.d.ts +17 -0
- package/dist/auditor/validator.js +58 -0
- package/dist/aura/client.d.ts +29 -0
- package/dist/aura/client.js +125 -0
- package/dist/aura/index.d.ts +4 -0
- package/dist/aura/index.js +2 -0
- package/dist/aura/server.d.ts +45 -0
- package/dist/aura/server.js +343 -0
- package/dist/cli.d.ts +17 -0
- package/dist/cli.js +1433 -0
- package/dist/client/index.d.ts +41 -0
- package/dist/client/index.js +170 -0
- package/dist/compliance/index.d.ts +40 -0
- package/dist/compliance/index.js +292 -0
- package/dist/database/index.d.ts +77 -0
- package/dist/database/index.js +395 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +762 -0
- package/dist/integrations/aura-scanner.d.ts +69 -0
- package/dist/integrations/aura-scanner.js +155 -0
- package/dist/integrations/aws-scanner.d.ts +63 -0
- package/dist/integrations/aws-scanner.js +624 -0
- package/dist/integrations/config.d.ts +69 -0
- package/dist/integrations/config.js +212 -0
- package/dist/integrations/github.d.ts +45 -0
- package/dist/integrations/github.js +201 -0
- package/dist/integrations/gitlab.d.ts +36 -0
- package/dist/integrations/gitlab.js +110 -0
- package/dist/integrations/index.d.ts +11 -0
- package/dist/integrations/index.js +11 -0
- package/dist/integrations/local-scanner.d.ts +146 -0
- package/dist/integrations/local-scanner.js +1654 -0
- package/dist/integrations/notifications.d.ts +99 -0
- package/dist/integrations/notifications.js +305 -0
- package/dist/integrations/scanners.d.ts +57 -0
- package/dist/integrations/scanners.js +217 -0
- package/dist/integrations/slop-scanner.d.ts +69 -0
- package/dist/integrations/slop-scanner.js +155 -0
- package/dist/integrations/webhook.d.ts +37 -0
- package/dist/integrations/webhook.js +256 -0
- package/dist/orchestrator/index.d.ts +72 -0
- package/dist/orchestrator/index.js +187 -0
- package/dist/output/index.d.ts +152 -0
- package/dist/output/index.js +399 -0
- package/dist/pipeline/index.d.ts +72 -0
- package/dist/pipeline/index.js +313 -0
- package/dist/sbom/index.d.ts +94 -0
- package/dist/sbom/index.js +298 -0
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.js +2 -0
- package/dist/schemas/input.schema.d.ts +87 -0
- package/dist/schemas/input.schema.js +44 -0
- package/dist/schemas/output.schema.d.ts +115 -0
- package/dist/schemas/output.schema.js +64 -0
- package/dist/serve-visualizer.d.ts +2 -0
- package/dist/serve-visualizer.js +78 -0
- package/dist/slop/client.d.ts +29 -0
- package/dist/slop/client.js +125 -0
- package/dist/slop/index.d.ts +4 -0
- package/dist/slop/index.js +2 -0
- package/dist/slop/server.d.ts +45 -0
- package/dist/slop/server.js +343 -0
- package/dist/types/events.d.ts +62 -0
- package/dist/types/events.js +2 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/visualizer/index.d.ts +4 -0
- package/dist/visualizer/index.js +181 -0
- package/dist/websocket/index.d.ts +88 -0
- package/dist/websocket/index.js +195 -0
- package/dist/zones/index.d.ts +7 -0
- package/dist/zones/index.js +7 -0
- package/dist/zones/manager.d.ts +101 -0
- package/dist/zones/manager.js +304 -0
- package/dist/zones/types.d.ts +78 -0
- package/dist/zones/types.js +33 -0
- package/package.json +84 -0
- package/visualizer/app.js +0 -0
- package/visualizer/index-minimal.html +1771 -0
- package/visualizer/index.html +2933 -0
- package/visualizer/landing.html +1328 -0
- package/visualizer/styles.css +0 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
export declare const auditorInputSchema: {
|
|
2
|
+
readonly $schema: "http://json-schema.org/draft-07/schema#";
|
|
3
|
+
readonly type: "object";
|
|
4
|
+
readonly required: readonly ["change_event", "evidence_bundle", "policy_context"];
|
|
5
|
+
readonly additionalProperties: false;
|
|
6
|
+
readonly properties: {
|
|
7
|
+
readonly change_event: {
|
|
8
|
+
readonly type: "object";
|
|
9
|
+
readonly required: readonly ["id", "type", "environment", "repo", "commit", "files_changed", "diff"];
|
|
10
|
+
readonly additionalProperties: false;
|
|
11
|
+
readonly properties: {
|
|
12
|
+
readonly id: {
|
|
13
|
+
readonly type: "string";
|
|
14
|
+
readonly minLength: 1;
|
|
15
|
+
};
|
|
16
|
+
readonly type: {
|
|
17
|
+
readonly type: "string";
|
|
18
|
+
readonly enum: readonly ["pull_request", "deploy", "infra_change"];
|
|
19
|
+
};
|
|
20
|
+
readonly environment: {
|
|
21
|
+
readonly type: "string";
|
|
22
|
+
readonly enum: readonly ["dev", "staging", "prod"];
|
|
23
|
+
};
|
|
24
|
+
readonly repo: {
|
|
25
|
+
readonly type: "string";
|
|
26
|
+
readonly minLength: 1;
|
|
27
|
+
};
|
|
28
|
+
readonly commit: {
|
|
29
|
+
readonly type: "string";
|
|
30
|
+
readonly pattern: "^[a-f0-9]{40}$";
|
|
31
|
+
};
|
|
32
|
+
readonly files_changed: {
|
|
33
|
+
readonly type: "array";
|
|
34
|
+
readonly items: {
|
|
35
|
+
readonly type: "string";
|
|
36
|
+
};
|
|
37
|
+
readonly minItems: 1;
|
|
38
|
+
};
|
|
39
|
+
readonly diff: {
|
|
40
|
+
readonly type: "string";
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
readonly evidence_bundle: {
|
|
45
|
+
readonly type: "object";
|
|
46
|
+
readonly additionalProperties: false;
|
|
47
|
+
readonly properties: {
|
|
48
|
+
readonly sbom: {
|
|
49
|
+
readonly type: "string";
|
|
50
|
+
};
|
|
51
|
+
readonly vuln_scan: {
|
|
52
|
+
readonly type: "string";
|
|
53
|
+
};
|
|
54
|
+
readonly sast_results: {
|
|
55
|
+
readonly type: "string";
|
|
56
|
+
};
|
|
57
|
+
readonly iac_scan: {
|
|
58
|
+
readonly type: "string";
|
|
59
|
+
};
|
|
60
|
+
readonly provenance: {
|
|
61
|
+
readonly type: "string";
|
|
62
|
+
};
|
|
63
|
+
readonly runtime_delta: {
|
|
64
|
+
readonly type: "string";
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
readonly policy_context: {
|
|
69
|
+
readonly type: "object";
|
|
70
|
+
readonly required: readonly ["critical_assets", "risk_tolerance"];
|
|
71
|
+
readonly additionalProperties: false;
|
|
72
|
+
readonly properties: {
|
|
73
|
+
readonly critical_assets: {
|
|
74
|
+
readonly type: "array";
|
|
75
|
+
readonly items: {
|
|
76
|
+
readonly type: "string";
|
|
77
|
+
};
|
|
78
|
+
readonly minItems: 1;
|
|
79
|
+
};
|
|
80
|
+
readonly risk_tolerance: {
|
|
81
|
+
readonly type: "string";
|
|
82
|
+
readonly enum: readonly ["low", "medium", "high"];
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Strict JSON Schema for Auditor Input validation
|
|
2
|
+
export const auditorInputSchema = {
|
|
3
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
4
|
+
type: 'object',
|
|
5
|
+
required: ['change_event', 'evidence_bundle', 'policy_context'],
|
|
6
|
+
additionalProperties: false,
|
|
7
|
+
properties: {
|
|
8
|
+
change_event: {
|
|
9
|
+
type: 'object',
|
|
10
|
+
required: ['id', 'type', 'environment', 'repo', 'commit', 'files_changed', 'diff'],
|
|
11
|
+
additionalProperties: false,
|
|
12
|
+
properties: {
|
|
13
|
+
id: { type: 'string', minLength: 1 },
|
|
14
|
+
type: { type: 'string', enum: ['pull_request', 'deploy', 'infra_change'] },
|
|
15
|
+
environment: { type: 'string', enum: ['dev', 'staging', 'prod'] },
|
|
16
|
+
repo: { type: 'string', minLength: 1 },
|
|
17
|
+
commit: { type: 'string', pattern: '^[a-f0-9]{40}$' },
|
|
18
|
+
files_changed: { type: 'array', items: { type: 'string' }, minItems: 1 },
|
|
19
|
+
diff: { type: 'string' }
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
evidence_bundle: {
|
|
23
|
+
type: 'object',
|
|
24
|
+
additionalProperties: false,
|
|
25
|
+
properties: {
|
|
26
|
+
sbom: { type: 'string' },
|
|
27
|
+
vuln_scan: { type: 'string' },
|
|
28
|
+
sast_results: { type: 'string' },
|
|
29
|
+
iac_scan: { type: 'string' },
|
|
30
|
+
provenance: { type: 'string' },
|
|
31
|
+
runtime_delta: { type: 'string' }
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
policy_context: {
|
|
35
|
+
type: 'object',
|
|
36
|
+
required: ['critical_assets', 'risk_tolerance'],
|
|
37
|
+
additionalProperties: false,
|
|
38
|
+
properties: {
|
|
39
|
+
critical_assets: { type: 'array', items: { type: 'string' }, minItems: 1 },
|
|
40
|
+
risk_tolerance: { type: 'string', enum: ['low', 'medium', 'high'] }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
export declare const auditorOutputSchema: {
|
|
2
|
+
readonly $schema: "http://json-schema.org/draft-07/schema#";
|
|
3
|
+
readonly type: "object";
|
|
4
|
+
readonly required: readonly ["agent_id", "agent_state", "events", "meta"];
|
|
5
|
+
readonly additionalProperties: false;
|
|
6
|
+
readonly properties: {
|
|
7
|
+
readonly agent_id: {
|
|
8
|
+
readonly type: "string";
|
|
9
|
+
readonly const: "exploit-reviewer";
|
|
10
|
+
};
|
|
11
|
+
readonly agent_state: {
|
|
12
|
+
readonly type: "string";
|
|
13
|
+
readonly enum: readonly ["idle", "analyzing", "conflict", "escalated", "blocked"];
|
|
14
|
+
};
|
|
15
|
+
readonly events: {
|
|
16
|
+
readonly type: "array";
|
|
17
|
+
readonly items: {
|
|
18
|
+
readonly type: "object";
|
|
19
|
+
readonly required: readonly ["event_type", "target", "payload", "timestamp"];
|
|
20
|
+
readonly additionalProperties: false;
|
|
21
|
+
readonly properties: {
|
|
22
|
+
readonly event_type: {
|
|
23
|
+
readonly type: "string";
|
|
24
|
+
readonly enum: readonly ["analysis_started", "finding_raised", "conflict_detected", "escalation_triggered"];
|
|
25
|
+
};
|
|
26
|
+
readonly target: {
|
|
27
|
+
readonly type: "string";
|
|
28
|
+
readonly minLength: 1;
|
|
29
|
+
};
|
|
30
|
+
readonly payload: {
|
|
31
|
+
readonly type: "object";
|
|
32
|
+
readonly required: readonly ["severity", "claim", "attack_path", "affected_assets", "evidence_refs", "assurance_break", "confidence"];
|
|
33
|
+
readonly additionalProperties: false;
|
|
34
|
+
readonly properties: {
|
|
35
|
+
readonly severity: {
|
|
36
|
+
readonly type: "string";
|
|
37
|
+
readonly enum: readonly ["low", "medium", "high", "critical"];
|
|
38
|
+
};
|
|
39
|
+
readonly claim: {
|
|
40
|
+
readonly type: "string";
|
|
41
|
+
readonly minLength: 1;
|
|
42
|
+
};
|
|
43
|
+
readonly attack_path: {
|
|
44
|
+
readonly type: "array";
|
|
45
|
+
readonly items: {
|
|
46
|
+
readonly type: "string";
|
|
47
|
+
};
|
|
48
|
+
readonly minItems: 1;
|
|
49
|
+
};
|
|
50
|
+
readonly affected_assets: {
|
|
51
|
+
readonly type: "array";
|
|
52
|
+
readonly items: {
|
|
53
|
+
readonly type: "string";
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
readonly evidence_refs: {
|
|
57
|
+
readonly type: "array";
|
|
58
|
+
readonly items: {
|
|
59
|
+
readonly type: "object";
|
|
60
|
+
readonly required: readonly ["type", "pointer"];
|
|
61
|
+
readonly additionalProperties: false;
|
|
62
|
+
readonly properties: {
|
|
63
|
+
readonly type: {
|
|
64
|
+
readonly type: "string";
|
|
65
|
+
readonly enum: readonly ["diff", "sbom", "scan", "provenance", "runtime"];
|
|
66
|
+
};
|
|
67
|
+
readonly pointer: {
|
|
68
|
+
readonly type: "string";
|
|
69
|
+
readonly minLength: 1;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
readonly assurance_break: {
|
|
75
|
+
readonly type: "array";
|
|
76
|
+
readonly items: {
|
|
77
|
+
readonly type: "string";
|
|
78
|
+
readonly enum: readonly ["integrity", "access_control", "isolation", "auditability"];
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
readonly confidence: {
|
|
82
|
+
readonly type: "number";
|
|
83
|
+
readonly minimum: 0;
|
|
84
|
+
readonly maximum: 1;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
readonly timestamp: {
|
|
89
|
+
readonly type: "string";
|
|
90
|
+
readonly format: "date-time";
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
readonly meta: {
|
|
96
|
+
readonly type: "object";
|
|
97
|
+
readonly required: readonly ["assumptions", "uncertainties"];
|
|
98
|
+
readonly additionalProperties: false;
|
|
99
|
+
readonly properties: {
|
|
100
|
+
readonly assumptions: {
|
|
101
|
+
readonly type: "array";
|
|
102
|
+
readonly items: {
|
|
103
|
+
readonly type: "string";
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
readonly uncertainties: {
|
|
107
|
+
readonly type: "array";
|
|
108
|
+
readonly items: {
|
|
109
|
+
readonly type: "string";
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Strict JSON Schema for Auditor Output validation
|
|
2
|
+
export const auditorOutputSchema = {
|
|
3
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
4
|
+
type: 'object',
|
|
5
|
+
required: ['agent_id', 'agent_state', 'events', 'meta'],
|
|
6
|
+
additionalProperties: false,
|
|
7
|
+
properties: {
|
|
8
|
+
agent_id: { type: 'string', const: 'exploit-reviewer' },
|
|
9
|
+
agent_state: { type: 'string', enum: ['idle', 'analyzing', 'conflict', 'escalated', 'blocked'] },
|
|
10
|
+
events: {
|
|
11
|
+
type: 'array',
|
|
12
|
+
items: {
|
|
13
|
+
type: 'object',
|
|
14
|
+
required: ['event_type', 'target', 'payload', 'timestamp'],
|
|
15
|
+
additionalProperties: false,
|
|
16
|
+
properties: {
|
|
17
|
+
event_type: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
enum: ['analysis_started', 'finding_raised', 'conflict_detected', 'escalation_triggered']
|
|
20
|
+
},
|
|
21
|
+
target: { type: 'string', minLength: 1 },
|
|
22
|
+
payload: {
|
|
23
|
+
type: 'object',
|
|
24
|
+
required: ['severity', 'claim', 'attack_path', 'affected_assets', 'evidence_refs', 'assurance_break', 'confidence'],
|
|
25
|
+
additionalProperties: false,
|
|
26
|
+
properties: {
|
|
27
|
+
severity: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] },
|
|
28
|
+
claim: { type: 'string', minLength: 1 },
|
|
29
|
+
attack_path: { type: 'array', items: { type: 'string' }, minItems: 1 },
|
|
30
|
+
affected_assets: { type: 'array', items: { type: 'string' } },
|
|
31
|
+
evidence_refs: {
|
|
32
|
+
type: 'array',
|
|
33
|
+
items: {
|
|
34
|
+
type: 'object',
|
|
35
|
+
required: ['type', 'pointer'],
|
|
36
|
+
additionalProperties: false,
|
|
37
|
+
properties: {
|
|
38
|
+
type: { type: 'string', enum: ['diff', 'sbom', 'scan', 'provenance', 'runtime'] },
|
|
39
|
+
pointer: { type: 'string', minLength: 1 }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
assurance_break: {
|
|
44
|
+
type: 'array',
|
|
45
|
+
items: { type: 'string', enum: ['integrity', 'access_control', 'isolation', 'auditability'] }
|
|
46
|
+
},
|
|
47
|
+
confidence: { type: 'number', minimum: 0, maximum: 1 }
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
timestamp: { type: 'string', format: 'date-time' }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
meta: {
|
|
55
|
+
type: 'object',
|
|
56
|
+
required: ['assumptions', 'uncertainties'],
|
|
57
|
+
additionalProperties: false,
|
|
58
|
+
properties: {
|
|
59
|
+
assumptions: { type: 'array', items: { type: 'string' } },
|
|
60
|
+
uncertainties: { type: 'array', items: { type: 'string' } }
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Serve the 3D Visualizer
|
|
3
|
+
import { createServer } from 'http';
|
|
4
|
+
import { readFileSync, existsSync } from 'fs';
|
|
5
|
+
import { join, extname } from 'path';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import { dirname } from 'path';
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const VISUALIZER_DIR = join(__dirname, '..', 'visualizer');
|
|
10
|
+
const PORT = parseInt(process.env.VISUALIZER_PORT ?? '8080', 10);
|
|
11
|
+
const MIME_TYPES = {
|
|
12
|
+
'.html': 'text/html',
|
|
13
|
+
'.js': 'application/javascript',
|
|
14
|
+
'.css': 'text/css',
|
|
15
|
+
'.json': 'application/json',
|
|
16
|
+
'.png': 'image/png',
|
|
17
|
+
'.svg': 'image/svg+xml'
|
|
18
|
+
};
|
|
19
|
+
const server = createServer((req, res) => {
|
|
20
|
+
// CORS headers for Aura API access
|
|
21
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
22
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
23
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
24
|
+
if (req.method === 'OPTIONS') {
|
|
25
|
+
res.writeHead(204);
|
|
26
|
+
res.end();
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const url = req.url?.split('?')[0] ?? '/';
|
|
30
|
+
let filePath;
|
|
31
|
+
// Route: / -> landing page
|
|
32
|
+
// Route: /app -> dashboard (3D visualizer)
|
|
33
|
+
// Route: /app/classic -> classic dashboard
|
|
34
|
+
if (url === '/') {
|
|
35
|
+
filePath = join(VISUALIZER_DIR, 'landing.html');
|
|
36
|
+
}
|
|
37
|
+
else if (url === '/app' || url === '/app/') {
|
|
38
|
+
filePath = join(VISUALIZER_DIR, 'index-minimal.html');
|
|
39
|
+
}
|
|
40
|
+
else if (url === '/app/classic') {
|
|
41
|
+
filePath = join(VISUALIZER_DIR, 'index.html');
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
filePath = join(VISUALIZER_DIR, url);
|
|
45
|
+
}
|
|
46
|
+
if (!existsSync(filePath)) {
|
|
47
|
+
res.writeHead(404);
|
|
48
|
+
res.end('Not found');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const ext = extname(filePath);
|
|
52
|
+
const contentType = MIME_TYPES[ext] || 'application/octet-stream';
|
|
53
|
+
try {
|
|
54
|
+
const content = readFileSync(filePath);
|
|
55
|
+
res.writeHead(200, { 'Content-Type': contentType });
|
|
56
|
+
res.end(content);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
res.writeHead(500);
|
|
60
|
+
res.end('Server error');
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
server.listen(PORT, () => {
|
|
64
|
+
console.log(`
|
|
65
|
+
╔═══════════════════════════════════════════════════════════╗
|
|
66
|
+
║ AURASECURITY - WEB SERVER ║
|
|
67
|
+
╠═══════════════════════════════════════════════════════════╣
|
|
68
|
+
║ Landing: http://127.0.0.1:${PORT} ║
|
|
69
|
+
║ Dashboard: http://127.0.0.1:${PORT}/app ║
|
|
70
|
+
║ Aura API: http://127.0.0.1:3000 ║
|
|
71
|
+
╚═══════════════════════════════════════════════════════════╝
|
|
72
|
+
|
|
73
|
+
Routes:
|
|
74
|
+
/ Landing page
|
|
75
|
+
/app 3D Dashboard (visualizer)
|
|
76
|
+
/app/classic Classic dashboard UI
|
|
77
|
+
`);
|
|
78
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface SlopClientConfig {
|
|
2
|
+
baseUrl: string;
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
timeout?: number;
|
|
5
|
+
}
|
|
6
|
+
export interface SlopToolCall {
|
|
7
|
+
tool: string;
|
|
8
|
+
arguments: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
export interface SlopMemoryEntry {
|
|
11
|
+
key: string;
|
|
12
|
+
value: unknown;
|
|
13
|
+
metadata?: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
export declare class SlopConnectionError extends Error {
|
|
16
|
+
constructor(message: string);
|
|
17
|
+
}
|
|
18
|
+
export declare class SlopClient {
|
|
19
|
+
private config;
|
|
20
|
+
private _connected;
|
|
21
|
+
constructor(config: SlopClientConfig);
|
|
22
|
+
get connected(): boolean;
|
|
23
|
+
private headers;
|
|
24
|
+
connect(): Promise<void>;
|
|
25
|
+
disconnect(): Promise<void>;
|
|
26
|
+
publishToMemory(entry: SlopMemoryEntry): Promise<void>;
|
|
27
|
+
callTool(call: SlopToolCall): Promise<unknown>;
|
|
28
|
+
healthCheck(): Promise<boolean>;
|
|
29
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// SLOP Client - Publish-only client for auditor pipeline
|
|
2
|
+
// Implements: /tools, /memory endpoints per SLOP spec
|
|
3
|
+
export class SlopConnectionError extends Error {
|
|
4
|
+
constructor(message) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = 'SlopConnectionError';
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export class SlopClient {
|
|
10
|
+
config;
|
|
11
|
+
_connected = false;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.config = {
|
|
14
|
+
baseUrl: config.baseUrl.replace(/\/$/, ''),
|
|
15
|
+
apiKey: config.apiKey ?? '',
|
|
16
|
+
timeout: config.timeout ?? 30000
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
get connected() {
|
|
20
|
+
return this._connected;
|
|
21
|
+
}
|
|
22
|
+
headers() {
|
|
23
|
+
const h = {
|
|
24
|
+
'Content-Type': 'application/json'
|
|
25
|
+
};
|
|
26
|
+
if (this.config.apiKey) {
|
|
27
|
+
h['Authorization'] = `Bearer ${this.config.apiKey}`;
|
|
28
|
+
}
|
|
29
|
+
return h;
|
|
30
|
+
}
|
|
31
|
+
async connect() {
|
|
32
|
+
// Verify SLOP server is available via /info
|
|
33
|
+
const controller = new AbortController();
|
|
34
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
35
|
+
try {
|
|
36
|
+
const res = await fetch(`${this.config.baseUrl}/info`, {
|
|
37
|
+
method: 'GET',
|
|
38
|
+
headers: this.headers(),
|
|
39
|
+
signal: controller.signal
|
|
40
|
+
});
|
|
41
|
+
clearTimeout(timeoutId);
|
|
42
|
+
if (!res.ok) {
|
|
43
|
+
throw new SlopConnectionError(`SLOP server returned ${res.status}`);
|
|
44
|
+
}
|
|
45
|
+
this._connected = true;
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
clearTimeout(timeoutId);
|
|
49
|
+
if (err instanceof SlopConnectionError)
|
|
50
|
+
throw err;
|
|
51
|
+
throw new SlopConnectionError(`Failed to connect to SLOP server: ${err}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async disconnect() {
|
|
55
|
+
this._connected = false;
|
|
56
|
+
}
|
|
57
|
+
// Fail-closed: throws on any error
|
|
58
|
+
async publishToMemory(entry) {
|
|
59
|
+
if (!this._connected) {
|
|
60
|
+
throw new SlopConnectionError('Not connected to SLOP server');
|
|
61
|
+
}
|
|
62
|
+
const controller = new AbortController();
|
|
63
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
64
|
+
try {
|
|
65
|
+
const res = await fetch(`${this.config.baseUrl}/memory`, {
|
|
66
|
+
method: 'POST',
|
|
67
|
+
headers: this.headers(),
|
|
68
|
+
body: JSON.stringify(entry),
|
|
69
|
+
signal: controller.signal
|
|
70
|
+
});
|
|
71
|
+
clearTimeout(timeoutId);
|
|
72
|
+
if (!res.ok) {
|
|
73
|
+
throw new SlopConnectionError(`Memory publish failed: ${res.status}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
clearTimeout(timeoutId);
|
|
78
|
+
if (err instanceof SlopConnectionError)
|
|
79
|
+
throw err;
|
|
80
|
+
throw new SlopConnectionError(`Memory publish error: ${err}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async callTool(call) {
|
|
84
|
+
if (!this._connected) {
|
|
85
|
+
throw new SlopConnectionError('Not connected to SLOP server');
|
|
86
|
+
}
|
|
87
|
+
const controller = new AbortController();
|
|
88
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
89
|
+
try {
|
|
90
|
+
const res = await fetch(`${this.config.baseUrl}/tools`, {
|
|
91
|
+
method: 'POST',
|
|
92
|
+
headers: this.headers(),
|
|
93
|
+
body: JSON.stringify(call),
|
|
94
|
+
signal: controller.signal
|
|
95
|
+
});
|
|
96
|
+
clearTimeout(timeoutId);
|
|
97
|
+
if (!res.ok) {
|
|
98
|
+
throw new SlopConnectionError(`Tool call failed: ${res.status}`);
|
|
99
|
+
}
|
|
100
|
+
return await res.json();
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
clearTimeout(timeoutId);
|
|
104
|
+
if (err instanceof SlopConnectionError)
|
|
105
|
+
throw err;
|
|
106
|
+
throw new SlopConnectionError(`Tool call error: ${err}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async healthCheck() {
|
|
110
|
+
try {
|
|
111
|
+
const controller = new AbortController();
|
|
112
|
+
const timeoutId = setTimeout(() => controller.abort(), 5000);
|
|
113
|
+
const res = await fetch(`${this.config.baseUrl}/info`, {
|
|
114
|
+
method: 'GET',
|
|
115
|
+
headers: this.headers(),
|
|
116
|
+
signal: controller.signal
|
|
117
|
+
});
|
|
118
|
+
clearTimeout(timeoutId);
|
|
119
|
+
return res.ok;
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type AuditorDatabase } from '../database/index.js';
|
|
2
|
+
import { NotificationService } from '../integrations/notifications.js';
|
|
3
|
+
export interface SlopTool {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
parameters: Record<string, unknown>;
|
|
7
|
+
handler: (args: Record<string, unknown>) => Promise<unknown>;
|
|
8
|
+
}
|
|
9
|
+
export interface SlopServerConfig {
|
|
10
|
+
port: number;
|
|
11
|
+
host?: string;
|
|
12
|
+
dbPath?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class SlopServer {
|
|
15
|
+
private server;
|
|
16
|
+
private tools;
|
|
17
|
+
private memory;
|
|
18
|
+
private config;
|
|
19
|
+
private db;
|
|
20
|
+
private notificationService;
|
|
21
|
+
constructor(config: SlopServerConfig);
|
|
22
|
+
getNotificationService(): NotificationService;
|
|
23
|
+
reloadNotifications(): void;
|
|
24
|
+
registerTool(tool: SlopTool): void;
|
|
25
|
+
getDatabase(): AuditorDatabase;
|
|
26
|
+
private handleRequest;
|
|
27
|
+
private handleInfo;
|
|
28
|
+
private handleListTools;
|
|
29
|
+
private handleCallTool;
|
|
30
|
+
private handleMemoryWrite;
|
|
31
|
+
private handleMemoryRead;
|
|
32
|
+
private handleGetSettings;
|
|
33
|
+
private handleSaveSettings;
|
|
34
|
+
private handleGetAudits;
|
|
35
|
+
private handleGetAudit;
|
|
36
|
+
private handleDeleteAudit;
|
|
37
|
+
private handleGetStats;
|
|
38
|
+
private handleGetNotifications;
|
|
39
|
+
private handleTestNotification;
|
|
40
|
+
private handleSendNotification;
|
|
41
|
+
private readBody;
|
|
42
|
+
start(): Promise<void>;
|
|
43
|
+
stop(): Promise<void>;
|
|
44
|
+
getMemorySnapshot(): Map<string, unknown>;
|
|
45
|
+
}
|