cipher-security 5.0.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 (75) hide show
  1. package/bin/cipher.js +465 -0
  2. package/lib/api/billing.js +321 -0
  3. package/lib/api/compliance.js +693 -0
  4. package/lib/api/controls.js +1401 -0
  5. package/lib/api/index.js +49 -0
  6. package/lib/api/marketplace.js +467 -0
  7. package/lib/api/openai-proxy.js +383 -0
  8. package/lib/api/server.js +685 -0
  9. package/lib/autonomous/feedback-loop.js +554 -0
  10. package/lib/autonomous/framework.js +512 -0
  11. package/lib/autonomous/index.js +97 -0
  12. package/lib/autonomous/leaderboard.js +594 -0
  13. package/lib/autonomous/modes/architect.js +412 -0
  14. package/lib/autonomous/modes/blue.js +386 -0
  15. package/lib/autonomous/modes/incident.js +684 -0
  16. package/lib/autonomous/modes/privacy.js +369 -0
  17. package/lib/autonomous/modes/purple.js +294 -0
  18. package/lib/autonomous/modes/recon.js +250 -0
  19. package/lib/autonomous/parallel.js +587 -0
  20. package/lib/autonomous/researcher.js +583 -0
  21. package/lib/autonomous/runner.js +955 -0
  22. package/lib/autonomous/scheduler.js +615 -0
  23. package/lib/autonomous/task-parser.js +127 -0
  24. package/lib/autonomous/validators/forensic.js +266 -0
  25. package/lib/autonomous/validators/osint.js +216 -0
  26. package/lib/autonomous/validators/privacy.js +296 -0
  27. package/lib/autonomous/validators/purple.js +298 -0
  28. package/lib/autonomous/validators/sigma.js +248 -0
  29. package/lib/autonomous/validators/threat-model.js +363 -0
  30. package/lib/benchmark/agent.js +119 -0
  31. package/lib/benchmark/baselines.js +43 -0
  32. package/lib/benchmark/builder.js +143 -0
  33. package/lib/benchmark/config.js +35 -0
  34. package/lib/benchmark/coordinator.js +91 -0
  35. package/lib/benchmark/index.js +20 -0
  36. package/lib/benchmark/llm.js +58 -0
  37. package/lib/benchmark/models.js +137 -0
  38. package/lib/benchmark/reporter.js +103 -0
  39. package/lib/benchmark/runner.js +103 -0
  40. package/lib/benchmark/sandbox.js +96 -0
  41. package/lib/benchmark/scorer.js +32 -0
  42. package/lib/benchmark/solver.js +166 -0
  43. package/lib/benchmark/tools.js +62 -0
  44. package/lib/bot/bot.js +130 -0
  45. package/lib/commands.js +99 -0
  46. package/lib/complexity.js +377 -0
  47. package/lib/config.js +213 -0
  48. package/lib/gateway/client.js +309 -0
  49. package/lib/gateway/commands.js +830 -0
  50. package/lib/gateway/config-validate.js +109 -0
  51. package/lib/gateway/gateway.js +367 -0
  52. package/lib/gateway/index.js +62 -0
  53. package/lib/gateway/mode.js +309 -0
  54. package/lib/gateway/plugins.js +222 -0
  55. package/lib/gateway/prompt.js +214 -0
  56. package/lib/mcp/server.js +262 -0
  57. package/lib/memory/compressor.js +425 -0
  58. package/lib/memory/engine.js +763 -0
  59. package/lib/memory/evolution.js +668 -0
  60. package/lib/memory/index.js +58 -0
  61. package/lib/memory/orchestrator.js +506 -0
  62. package/lib/memory/retriever.js +515 -0
  63. package/lib/memory/synthesizer.js +333 -0
  64. package/lib/pipeline/async-scanner.js +510 -0
  65. package/lib/pipeline/binary-analysis.js +1043 -0
  66. package/lib/pipeline/dom-xss-scanner.js +435 -0
  67. package/lib/pipeline/github-actions.js +792 -0
  68. package/lib/pipeline/index.js +124 -0
  69. package/lib/pipeline/osint.js +498 -0
  70. package/lib/pipeline/sarif.js +373 -0
  71. package/lib/pipeline/scanner.js +880 -0
  72. package/lib/pipeline/template-manager.js +525 -0
  73. package/lib/pipeline/xss-scanner.js +353 -0
  74. package/lib/setup-wizard.js +229 -0
  75. package/package.json +30 -0
@@ -0,0 +1,412 @@
1
+ // Copyright (c) 2026 defconxt. All rights reserved.
2
+ // Licensed under AGPL-3.0 — see LICENSE file for details.
3
+ // CIPHER is a trademark of defconxt.
4
+
5
+ /**
6
+ * ARCHITECT mode agent — Threat Modeling.
7
+ *
8
+ * Performs autonomous threat modeling using STRIDE + DREAD.
9
+ * Ported from autonomous/modes/architect.py.
10
+ *
11
+ * @module autonomous/modes/architect
12
+ */
13
+
14
+ import { ModeAgentConfig, ToolRegistry } from '../framework.js';
15
+ import { ThreatModelValidator } from '../validators/threat-model.js';
16
+
17
+ // ---------------------------------------------------------------------------
18
+ // Architecture analysis keywords for system decomposition
19
+ // ---------------------------------------------------------------------------
20
+
21
+ const _PROCESS_KEYWORDS = [
22
+ 'service', 'server', 'api', 'gateway', 'proxy', 'worker',
23
+ 'handler', 'controller', 'middleware', 'microservice',
24
+ 'application', 'app', 'frontend', 'backend', 'engine',
25
+ 'processor', 'scheduler', 'daemon', 'auth', 'authentication',
26
+ 'authorization', 'load balancer', 'reverse proxy',
27
+ ];
28
+
29
+ const _DATA_STORE_KEYWORDS = [
30
+ 'database', 'db', 'postgresql', 'postgres', 'mysql', 'mariadb',
31
+ 'mongodb', 'redis', 'memcached', 'cache', 'elasticsearch',
32
+ 'sqlite', 'dynamodb', 'cassandra', 's3', 'blob storage',
33
+ 'file system', 'data warehouse', 'data lake', 'queue',
34
+ 'message broker', 'kafka', 'rabbitmq', 'sqs',
35
+ ];
36
+
37
+ const _EXTERNAL_ENTITY_KEYWORDS = [
38
+ 'external api', 'third-party', 'third party', '3rd party',
39
+ 'stripe', 'twilio', 'sendgrid', 'aws', 'azure', 'gcp',
40
+ 'oauth', 'sso', 'ldap', 'saml', 'webhook', 'cdn',
41
+ 'payment', 'email service', 'sms', 'push notification',
42
+ 'analytics', 'monitoring service', 'logging service',
43
+ ];
44
+
45
+ // ---------------------------------------------------------------------------
46
+ // Tool handlers
47
+ // ---------------------------------------------------------------------------
48
+
49
+ /**
50
+ * Decompose a system description into architectural components.
51
+ * @param {*} context
52
+ * @param {Object} toolInput
53
+ * @returns {string}
54
+ */
55
+ export function _architectAnalyzeArchitecture(context, toolInput) {
56
+ const description = toolInput.system_description || '';
57
+ if (!description || !description.trim()) {
58
+ return "ERROR: 'system_description' parameter is required and must not be empty.";
59
+ }
60
+
61
+ const descLower = description.toLowerCase();
62
+
63
+ // Identify processes/services
64
+ const components = [];
65
+ for (const keyword of _PROCESS_KEYWORDS) {
66
+ if (descLower.includes(keyword)) {
67
+ const idx = descLower.indexOf(keyword);
68
+ const start = Math.max(0, idx - 40);
69
+ const end = Math.min(description.length, idx + keyword.length + 40);
70
+ const snippet = description.slice(start, end).trim();
71
+ components.push({
72
+ name: keyword.split(' ').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' '),
73
+ type: 'process',
74
+ source: snippet,
75
+ });
76
+ }
77
+ }
78
+
79
+ // Identify data stores
80
+ const dataStores = [];
81
+ for (const keyword of _DATA_STORE_KEYWORDS) {
82
+ if (descLower.includes(keyword)) {
83
+ dataStores.push({
84
+ name: keyword.split(' ').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' '),
85
+ type: 'data_store',
86
+ });
87
+ }
88
+ }
89
+
90
+ // Identify external entities
91
+ const externalEntities = [];
92
+ for (const keyword of _EXTERNAL_ENTITY_KEYWORDS) {
93
+ if (descLower.includes(keyword)) {
94
+ externalEntities.push({
95
+ name: keyword.split(' ').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' '),
96
+ type: 'external_entity',
97
+ });
98
+ }
99
+ }
100
+
101
+ // Infer data flows between consecutive identified components
102
+ const allNames = [
103
+ ...components.map(c => c.name),
104
+ ...dataStores.map(d => d.name),
105
+ ...externalEntities.map(e => e.name),
106
+ ];
107
+ const dataFlows = [];
108
+ for (let i = 0; i < allNames.length - 1; i++) {
109
+ dataFlows.push({
110
+ from: allNames[i],
111
+ to: allNames[i + 1],
112
+ description: `Data flow from ${allNames[i]} to ${allNames[i + 1]}`,
113
+ });
114
+ }
115
+
116
+ return JSON.stringify({
117
+ components,
118
+ data_stores: dataStores,
119
+ external_entities: externalEntities,
120
+ data_flows: dataFlows,
121
+ total_identified: components.length + dataStores.length + externalEntities.length,
122
+ }, null, 2);
123
+ }
124
+
125
+ /**
126
+ * Validate and score threats using DREAD risk methodology.
127
+ * @param {*} context
128
+ * @param {Object} toolInput
129
+ * @returns {string}
130
+ */
131
+ export function _architectScoreThreats(context, toolInput) {
132
+ const threats = toolInput.threats || [];
133
+ if (!threats.length) {
134
+ return "ERROR: 'threats' parameter is required and must not be empty.";
135
+ }
136
+
137
+ const dreadDimensions = [
138
+ 'Damage', 'Reproducibility', 'Exploitability',
139
+ 'Affected Users', 'Discoverability',
140
+ ];
141
+
142
+ const scoredThreats = [];
143
+ let highestRisk = 'Low';
144
+ const riskPriority = { Critical: 4, High: 3, Medium: 2, Low: 1 };
145
+
146
+ for (let i = 0; i < threats.length; i++) {
147
+ const threat = threats[i];
148
+ if (typeof threat !== 'object' || threat === null) {
149
+ return `ERROR: threats[${i}] must be a dict (got ${typeof threat}).`;
150
+ }
151
+
152
+ const dread = threat.dread || {};
153
+ if (typeof dread !== 'object' || dread === null) {
154
+ return `ERROR: threats[${i}].dread must be a dict (got ${typeof dread}).`;
155
+ }
156
+
157
+ // Validate each DREAD dimension
158
+ let total = 0;
159
+ for (const dim of dreadDimensions) {
160
+ const val = dread[dim];
161
+ if (val === undefined || val === null) {
162
+ return `ERROR: threats[${i}].dread missing dimension: ${dim}`;
163
+ }
164
+ if (typeof val !== 'number') {
165
+ return `ERROR: threats[${i}].dread.${dim} must be an integer (got ${typeof val})`;
166
+ }
167
+ const valInt = Math.floor(val);
168
+ if (valInt < 1 || valInt > 10) {
169
+ return `ERROR: threats[${i}].dread.${dim} must be 1-10 (got ${valInt})`;
170
+ }
171
+ total += valInt;
172
+ }
173
+
174
+ const average = total / dreadDimensions.length;
175
+
176
+ // Assign risk level
177
+ let riskLevel;
178
+ if (average >= 8) riskLevel = 'Critical';
179
+ else if (average >= 6) riskLevel = 'High';
180
+ else if (average >= 4) riskLevel = 'Medium';
181
+ else riskLevel = 'Low';
182
+
183
+ if ((riskPriority[riskLevel] || 0) > (riskPriority[highestRisk] || 0)) {
184
+ highestRisk = riskLevel;
185
+ }
186
+
187
+ scoredThreats.push({
188
+ component: threat.component || 'unknown',
189
+ threat_type: threat.threat_type || 'unknown',
190
+ description: threat.description || '',
191
+ dread,
192
+ average_score: Math.round(average * 100) / 100,
193
+ risk_level: riskLevel,
194
+ });
195
+ }
196
+
197
+ return JSON.stringify({
198
+ scored_threats: scoredThreats,
199
+ total_threats: scoredThreats.length,
200
+ highest_risk_level: highestRisk,
201
+ }, null, 2);
202
+ }
203
+
204
+ /**
205
+ * Store a structured JSON threat model report in context.
206
+ * @param {*} context
207
+ * @param {Object} toolInput
208
+ * @returns {string}
209
+ */
210
+ export function _architectWriteThreatModel(context, toolInput) {
211
+ const report = toolInput.report || '';
212
+
213
+ if (typeof context !== 'object' || context === null) {
214
+ return 'ERROR: Context must be a dict.';
215
+ }
216
+
217
+ let reportData;
218
+ if (typeof report === 'string') {
219
+ try {
220
+ reportData = JSON.parse(report);
221
+ } catch {
222
+ reportData = report;
223
+ }
224
+ } else {
225
+ reportData = report;
226
+ }
227
+
228
+ context.report = reportData;
229
+ const filename = toolInput.filename || 'threat_model.json';
230
+
231
+ return (
232
+ `Threat model report stored as ${filename}. ` +
233
+ `Report is available in context['report'].`
234
+ );
235
+ }
236
+
237
+ // ---------------------------------------------------------------------------
238
+ // Tool schemas (Anthropic format)
239
+ // ---------------------------------------------------------------------------
240
+
241
+ const _ARCHITECT_ANALYZE_ARCHITECTURE_SCHEMA = {
242
+ name: 'analyze_architecture',
243
+ description:
244
+ 'Decompose a system description into architectural components: ' +
245
+ 'processes/services, data stores, external entities, and data flows.',
246
+ input_schema: {
247
+ type: 'object',
248
+ properties: {
249
+ system_description: {
250
+ type: 'string',
251
+ description: 'Natural language description of the system architecture',
252
+ },
253
+ },
254
+ required: ['system_description'],
255
+ },
256
+ };
257
+
258
+ const _ARCHITECT_SCORE_THREATS_SCHEMA = {
259
+ name: 'score_threats',
260
+ description:
261
+ 'Validate and score threats using DREAD risk methodology. Each threat ' +
262
+ 'needs DREAD dimension scores (1-10). Returns scored threats with risk levels.',
263
+ input_schema: {
264
+ type: 'object',
265
+ properties: {
266
+ threats: {
267
+ type: 'array',
268
+ description: 'List of threat objects with component, threat_type, description, dread scores',
269
+ items: {
270
+ type: 'object',
271
+ properties: {
272
+ component: { type: 'string', description: 'Component being threatened' },
273
+ threat_type: {
274
+ type: 'string',
275
+ description: 'STRIDE category: Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, or Elevation of Privilege',
276
+ },
277
+ description: { type: 'string', description: 'Description of the threat' },
278
+ dread: {
279
+ type: 'object',
280
+ description: 'DREAD scores: Damage, Reproducibility, Exploitability, Affected Users, Discoverability (each 1-10)',
281
+ },
282
+ },
283
+ required: ['component', 'threat_type', 'description', 'dread'],
284
+ },
285
+ },
286
+ },
287
+ required: ['threats'],
288
+ },
289
+ };
290
+
291
+ const _ARCHITECT_WRITE_THREAT_MODEL_SCHEMA = {
292
+ name: 'write_threat_model',
293
+ description:
294
+ 'Submit the completed threat model report as JSON with required sections: ' +
295
+ 'system_description, components, trust_boundaries, stride_analysis, ' +
296
+ 'dread_scores, mitigations, dfd_mermaid.',
297
+ input_schema: {
298
+ type: 'object',
299
+ properties: {
300
+ report: {
301
+ type: 'string',
302
+ description: 'Full JSON threat model report as a string.',
303
+ },
304
+ filename: {
305
+ type: 'string',
306
+ description: 'Filename for the report (e.g. threat_model.json)',
307
+ },
308
+ },
309
+ required: ['report'],
310
+ },
311
+ };
312
+
313
+ // ---------------------------------------------------------------------------
314
+ // System prompt template
315
+ // ---------------------------------------------------------------------------
316
+
317
+ const _ARCHITECT_SYSTEM_PROMPT = `\
318
+ You are an expert security architect performing threat modeling using the \
319
+ STRIDE methodology with DREAD risk scoring. Analyze the system description \
320
+ and produce a comprehensive structured threat model.
321
+
322
+ ## System Description
323
+ {system_description}
324
+
325
+ ## Instructions
326
+ 1. Use \`analyze_architecture\` to decompose the system into components.
327
+ 2. Perform STRIDE analysis on each component and data flow.
328
+ 3. Use \`score_threats\` to compute DREAD risk scores for each threat.
329
+ 4. Generate a Mermaid DFD showing components, trust boundaries, and data flows.
330
+ 5. Use \`write_threat_model\` to submit the final report.
331
+
332
+ ## Rules
333
+ - Analyze EVERY component for ALL 6 STRIDE categories
334
+ - Score EVERY threat with ALL 5 DREAD dimensions (integers 1-10)
335
+ - Include trust boundaries between all architectural tiers
336
+ - Generate valid Mermaid DFD syntax (starts with 'graph' or 'flowchart')
337
+ - Provide specific, actionable mitigations
338
+ `;
339
+
340
+ // ---------------------------------------------------------------------------
341
+ // Output parser (fallback for text-based output)
342
+ // ---------------------------------------------------------------------------
343
+
344
+ /**
345
+ * Extract JSON threat model from LLM text output.
346
+ * @param {string} text
347
+ * @returns {Object}
348
+ */
349
+ export function _architectOutputParser(text) {
350
+ if (!text || !text.trim()) {
351
+ return { raw_text: text, parse_error: 'empty output' };
352
+ }
353
+
354
+ let matches = [...text.matchAll(/```json\s*\n(.*?)```/gs)].map(m => m[1]);
355
+ if (matches.length > 0) {
356
+ const jsonText = matches.join('\n');
357
+ try { return JSON.parse(jsonText); } catch (e) {
358
+ return { raw_text: text, parse_error: e.message };
359
+ }
360
+ }
361
+
362
+ matches = [...text.matchAll(/```\s*\n(.*?)```/gs)].map(m => m[1]);
363
+ if (matches.length > 0) {
364
+ const jsonText = matches.join('\n');
365
+ try { return JSON.parse(jsonText); } catch (e) {
366
+ return { raw_text: text, parse_error: e.message };
367
+ }
368
+ }
369
+
370
+ try { return JSON.parse(text); } catch (e) {
371
+ return { raw_text: text, parse_error: e.message };
372
+ }
373
+ }
374
+
375
+ // ---------------------------------------------------------------------------
376
+ // Factory function
377
+ // ---------------------------------------------------------------------------
378
+
379
+ /**
380
+ * Build an ARCHITECT-mode ModeAgentConfig for threat modeling.
381
+ * @returns {ModeAgentConfig}
382
+ */
383
+ function _makeArchitectConfig() {
384
+ const reg = new ToolRegistry();
385
+ reg.register('analyze_architecture', _ARCHITECT_ANALYZE_ARCHITECTURE_SCHEMA, _architectAnalyzeArchitecture);
386
+ reg.register('score_threats', _ARCHITECT_SCORE_THREATS_SCHEMA, _architectScoreThreats);
387
+ reg.register('write_threat_model', _ARCHITECT_WRITE_THREAT_MODEL_SCHEMA, _architectWriteThreatModel);
388
+
389
+ return new ModeAgentConfig({
390
+ mode: 'ARCHITECT',
391
+ toolRegistry: reg,
392
+ systemPromptTemplate: _ARCHITECT_SYSTEM_PROMPT,
393
+ validator: new ThreatModelValidator(),
394
+ maxTurns: 15,
395
+ requiresSandbox: false,
396
+ completionCheck: null,
397
+ outputParser: _architectOutputParser,
398
+ outputFormat: 'json',
399
+ });
400
+ }
401
+
402
+ // ---------------------------------------------------------------------------
403
+ // Registration function — called by runner.initModes()
404
+ // ---------------------------------------------------------------------------
405
+
406
+ /**
407
+ * Register ARCHITECT mode with the given registerMode function.
408
+ * @param {Function} registerMode
409
+ */
410
+ export function register(registerMode) {
411
+ registerMode('ARCHITECT', _makeArchitectConfig);
412
+ }