@ayurak/aribot-cli 1.0.4 → 1.0.7
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/README.md +222 -39
- package/aribot-report-183b4bd7.json +1569 -0
- package/dist/cli.d.ts +10 -1
- package/dist/cli.js +956 -12
- package/dist/index.d.ts +19 -0
- package/dist/index.js +35 -0
- package/dist/sdk.d.ts +349 -0
- package/dist/sdk.js +808 -0
- package/package.json +34 -4
- package/src/cli.ts +1015 -13
- package/src/index.ts +42 -0
- package/src/sdk.ts +1017 -0
package/dist/sdk.js
ADDED
|
@@ -0,0 +1,808 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Aribot Node.js SDK - Economic, Regulatory & Security APIs for Modern Applications
|
|
4
|
+
*
|
|
5
|
+
* Analyze your tech stack. Optimize architecture. Model costs. Identify threats dynamically.
|
|
6
|
+
* APIs that help you build better systems with practical, actionable recommendations.
|
|
7
|
+
*
|
|
8
|
+
* Platform Capabilities:
|
|
9
|
+
* - Advanced Threat Modeling: Multi-framework (STRIDE, PASTA, NIST, Aristiun Framework)
|
|
10
|
+
* - Cloud Security: Real-time CSPM, CNAPP, misconfiguration detection
|
|
11
|
+
* - Living Architecture: Dynamic architecture diagrams with real-time updates
|
|
12
|
+
* - Economic Intelligence: Security ROI, TCO analysis, risk quantification in real dollars
|
|
13
|
+
* - FinOps: Cloud cost optimization, security spend tracking
|
|
14
|
+
* - Compliance: 100+ regulatory standards (SOC2, ISO27001, NIST, PCI-DSS, GDPR, HIPAA, etc.)
|
|
15
|
+
* - Red Team: Automated attack simulations, penetration testing orchestration
|
|
16
|
+
*
|
|
17
|
+
* Usage:
|
|
18
|
+
* import { AribotClient } from '@ayurak/aribot-cli';
|
|
19
|
+
*
|
|
20
|
+
* const client = new AribotClient({ apiKey: 'ak_...' });
|
|
21
|
+
*
|
|
22
|
+
* // Threat Modeling
|
|
23
|
+
* const diagram = await client.threatModeling.upload('architecture.png');
|
|
24
|
+
* const threats = await client.threatModeling.getThreats(diagram.id);
|
|
25
|
+
*
|
|
26
|
+
* // Compliance
|
|
27
|
+
* const assessment = await client.compliance.assess(diagramId, 'SOC2');
|
|
28
|
+
*
|
|
29
|
+
* // Red Team
|
|
30
|
+
* const simulation = await client.redteam.runSimulation(targetId, 'lateral_movement');
|
|
31
|
+
*/
|
|
32
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
33
|
+
if (k2 === undefined) k2 = k;
|
|
34
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
35
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
36
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
37
|
+
}
|
|
38
|
+
Object.defineProperty(o, k2, desc);
|
|
39
|
+
}) : (function(o, m, k, k2) {
|
|
40
|
+
if (k2 === undefined) k2 = k;
|
|
41
|
+
o[k2] = m[k];
|
|
42
|
+
}));
|
|
43
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
44
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
45
|
+
}) : function(o, v) {
|
|
46
|
+
o["default"] = v;
|
|
47
|
+
});
|
|
48
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
49
|
+
var ownKeys = function(o) {
|
|
50
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
51
|
+
var ar = [];
|
|
52
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
53
|
+
return ar;
|
|
54
|
+
};
|
|
55
|
+
return ownKeys(o);
|
|
56
|
+
};
|
|
57
|
+
return function (mod) {
|
|
58
|
+
if (mod && mod.__esModule) return mod;
|
|
59
|
+
var result = {};
|
|
60
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
61
|
+
__setModuleDefault(result, mod);
|
|
62
|
+
return result;
|
|
63
|
+
};
|
|
64
|
+
})();
|
|
65
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
66
|
+
exports.SecureCredentialManager = exports.RequestSigner = exports.AribotClient = exports.APIError = exports.RateLimitError = exports.AuthenticationError = exports.AribotError = void 0;
|
|
67
|
+
exports.analyzeDiagram = analyzeDiagram;
|
|
68
|
+
exports.runComplianceCheck = runComplianceCheck;
|
|
69
|
+
const fs = __importStar(require("fs"));
|
|
70
|
+
const path = __importStar(require("path"));
|
|
71
|
+
const crypto = __importStar(require("crypto"));
|
|
72
|
+
const VERSION = '1.0.6';
|
|
73
|
+
const DEFAULT_BASE_URL = 'https://api.aribot.ayurak.com/aribot-api';
|
|
74
|
+
// =============================================================================
|
|
75
|
+
// ERRORS
|
|
76
|
+
// =============================================================================
|
|
77
|
+
class AribotError extends Error {
|
|
78
|
+
constructor(message) {
|
|
79
|
+
super(message);
|
|
80
|
+
this.name = 'AribotError';
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.AribotError = AribotError;
|
|
84
|
+
class AuthenticationError extends AribotError {
|
|
85
|
+
constructor(message = 'Invalid or expired API key') {
|
|
86
|
+
super(message);
|
|
87
|
+
this.name = 'AuthenticationError';
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.AuthenticationError = AuthenticationError;
|
|
91
|
+
class RateLimitError extends AribotError {
|
|
92
|
+
retryAfter;
|
|
93
|
+
constructor(message = 'Rate limit exceeded', retryAfter) {
|
|
94
|
+
super(message);
|
|
95
|
+
this.name = 'RateLimitError';
|
|
96
|
+
this.retryAfter = retryAfter;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.RateLimitError = RateLimitError;
|
|
100
|
+
class APIError extends AribotError {
|
|
101
|
+
statusCode;
|
|
102
|
+
response;
|
|
103
|
+
constructor(message, statusCode, response) {
|
|
104
|
+
super(message);
|
|
105
|
+
this.name = 'APIError';
|
|
106
|
+
this.statusCode = statusCode;
|
|
107
|
+
this.response = response;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.APIError = APIError;
|
|
111
|
+
// =============================================================================
|
|
112
|
+
// API CLIENT
|
|
113
|
+
// =============================================================================
|
|
114
|
+
class AribotClient {
|
|
115
|
+
apiKey;
|
|
116
|
+
baseUrl;
|
|
117
|
+
timeout;
|
|
118
|
+
maxRetries;
|
|
119
|
+
// Resource managers
|
|
120
|
+
threatModeling;
|
|
121
|
+
cloudSecurity;
|
|
122
|
+
compliance;
|
|
123
|
+
economics;
|
|
124
|
+
finops;
|
|
125
|
+
redteam;
|
|
126
|
+
architecture;
|
|
127
|
+
user;
|
|
128
|
+
ai; // Secure AI usage management
|
|
129
|
+
// Aliases
|
|
130
|
+
diagrams;
|
|
131
|
+
constructor(config = {}) {
|
|
132
|
+
this.apiKey = config.apiKey || process.env.ARIBOT_API_KEY || '';
|
|
133
|
+
if (!this.apiKey) {
|
|
134
|
+
throw new AuthenticationError('API key required. Pass apiKey in config or set ARIBOT_API_KEY env var.');
|
|
135
|
+
}
|
|
136
|
+
this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, '');
|
|
137
|
+
this.timeout = config.timeout || 60000;
|
|
138
|
+
this.maxRetries = config.maxRetries || 3;
|
|
139
|
+
// Initialize resources
|
|
140
|
+
this.threatModeling = new ThreatModelingResource(this);
|
|
141
|
+
this.cloudSecurity = new CloudSecurityResource(this);
|
|
142
|
+
this.compliance = new ComplianceResource(this);
|
|
143
|
+
this.economics = new EconomicsResource(this);
|
|
144
|
+
this.finops = new FinOpsResource(this);
|
|
145
|
+
this.redteam = new RedTeamResource(this);
|
|
146
|
+
this.architecture = new ArchitectureResource(this);
|
|
147
|
+
this.user = new UserResource(this);
|
|
148
|
+
this.ai = new AIResource(this);
|
|
149
|
+
// Aliases
|
|
150
|
+
this.diagrams = this.threatModeling;
|
|
151
|
+
}
|
|
152
|
+
getHeaders(contentType = 'application/json') {
|
|
153
|
+
const headers = {
|
|
154
|
+
'X-API-Key': this.apiKey,
|
|
155
|
+
'User-Agent': `aribot-sdk/${VERSION} (Node.js)`,
|
|
156
|
+
'X-Request-ID': crypto.randomBytes(16).toString('base64url'),
|
|
157
|
+
'X-Request-Timestamp': new Date().toISOString(),
|
|
158
|
+
};
|
|
159
|
+
if (contentType) {
|
|
160
|
+
headers['Content-Type'] = contentType;
|
|
161
|
+
}
|
|
162
|
+
return headers;
|
|
163
|
+
}
|
|
164
|
+
getAuthHeader() {
|
|
165
|
+
return {
|
|
166
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
167
|
+
'User-Agent': `aribot-sdk/${VERSION} (Node.js)`,
|
|
168
|
+
'X-Request-ID': crypto.randomBytes(16).toString('base64url'),
|
|
169
|
+
'X-Request-Timestamp': new Date().toISOString(),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
async request(method, endpoint, options = {}) {
|
|
173
|
+
const fetch = (await import('node-fetch')).default;
|
|
174
|
+
const url = new URL(`${this.baseUrl}${endpoint}`);
|
|
175
|
+
if (options.params) {
|
|
176
|
+
Object.entries(options.params).forEach(([key, value]) => {
|
|
177
|
+
url.searchParams.set(key, String(value));
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
const headers = options.formData ? this.getAuthHeader() : this.getHeaders();
|
|
181
|
+
let lastError = null;
|
|
182
|
+
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
|
|
183
|
+
try {
|
|
184
|
+
const requestOptions = {
|
|
185
|
+
method,
|
|
186
|
+
headers,
|
|
187
|
+
timeout: this.timeout,
|
|
188
|
+
};
|
|
189
|
+
if (options.formData) {
|
|
190
|
+
requestOptions.body = options.formData;
|
|
191
|
+
}
|
|
192
|
+
else if (options.body) {
|
|
193
|
+
requestOptions.body = JSON.stringify(options.body);
|
|
194
|
+
}
|
|
195
|
+
const response = await fetch(url.toString(), requestOptions);
|
|
196
|
+
if (response.ok) {
|
|
197
|
+
const contentType = response.headers.get('content-type');
|
|
198
|
+
if (contentType?.includes('application/json')) {
|
|
199
|
+
return await response.json();
|
|
200
|
+
}
|
|
201
|
+
return await response.buffer();
|
|
202
|
+
}
|
|
203
|
+
if (response.status === 401) {
|
|
204
|
+
throw new AuthenticationError();
|
|
205
|
+
}
|
|
206
|
+
if (response.status === 403) {
|
|
207
|
+
throw new AuthenticationError('Access denied. Check API key permissions.');
|
|
208
|
+
}
|
|
209
|
+
if (response.status === 429) {
|
|
210
|
+
const retryAfter = response.headers.get('Retry-After');
|
|
211
|
+
throw new RateLimitError('Rate limit exceeded', retryAfter ? parseInt(retryAfter) : undefined);
|
|
212
|
+
}
|
|
213
|
+
let errorMessage;
|
|
214
|
+
try {
|
|
215
|
+
const errorData = await response.json();
|
|
216
|
+
errorMessage = errorData.detail || errorData.message || JSON.stringify(errorData);
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
errorMessage = `HTTP ${response.status}`;
|
|
220
|
+
}
|
|
221
|
+
throw new APIError(errorMessage, response.status);
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
lastError = error;
|
|
225
|
+
if (error instanceof AuthenticationError) {
|
|
226
|
+
throw error;
|
|
227
|
+
}
|
|
228
|
+
if (error instanceof RateLimitError && error.retryAfter) {
|
|
229
|
+
await this.sleep(error.retryAfter * 1000);
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
if (error.code === 'ETIMEDOUT' || error.code === 'ECONNRESET') {
|
|
233
|
+
const sleepTime = Math.pow(2, attempt) * 1000 + Math.random() * 1000;
|
|
234
|
+
await this.sleep(sleepTime);
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
throw error;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
throw lastError || new APIError(`Request failed after ${this.maxRetries} attempts`);
|
|
241
|
+
}
|
|
242
|
+
sleep(ms) {
|
|
243
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
exports.AribotClient = AribotClient;
|
|
247
|
+
// =============================================================================
|
|
248
|
+
// THREAT MODELING RESOURCE
|
|
249
|
+
// =============================================================================
|
|
250
|
+
class ThreatModelingResource {
|
|
251
|
+
client;
|
|
252
|
+
constructor(client) {
|
|
253
|
+
this.client = client;
|
|
254
|
+
}
|
|
255
|
+
async list(options = {}) {
|
|
256
|
+
return this.client.request('GET', '/v2/threat-modeling/diagrams/', {
|
|
257
|
+
params: { limit: options.limit || 20, offset: options.offset || 0 }
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
async get(diagramId) {
|
|
261
|
+
return this.client.request('GET', `/v2/threat-modeling/diagrams/${diagramId}/`);
|
|
262
|
+
}
|
|
263
|
+
async upload(filePath, options = {}) {
|
|
264
|
+
const FormData = (await import('form-data')).default;
|
|
265
|
+
const form = new FormData();
|
|
266
|
+
form.append('file', fs.createReadStream(filePath));
|
|
267
|
+
form.append('name', options.name || path.basename(filePath, path.extname(filePath)));
|
|
268
|
+
form.append('auto_generate_threats', String(options.autoGenerateThreats !== false));
|
|
269
|
+
return this.client.request('POST', '/v2/threat-modeling/diagrams/upload-analyze/', {
|
|
270
|
+
formData: form
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
async getThreats(diagramId, options = {}) {
|
|
274
|
+
const data = await this.client.request('GET', `/v2/threat-modeling/diagrams/${diagramId}/threats/`, {
|
|
275
|
+
params: options.severity ? { severity: options.severity } : {}
|
|
276
|
+
});
|
|
277
|
+
return data.threats || data.results || [];
|
|
278
|
+
}
|
|
279
|
+
async generateThreats(diagramId, options = {}) {
|
|
280
|
+
await this.client.request('POST', `/v2/threat-modeling/diagrams/${diagramId}/generate-threats/`);
|
|
281
|
+
if (options.waitForCompletion !== false) {
|
|
282
|
+
const timeout = options.timeout || 120000;
|
|
283
|
+
const start = Date.now();
|
|
284
|
+
while (Date.now() - start < timeout) {
|
|
285
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
286
|
+
const status = await this.get(diagramId);
|
|
287
|
+
if (status.stage === 'completed') {
|
|
288
|
+
return status;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return this.get(diagramId);
|
|
293
|
+
}
|
|
294
|
+
async export(diagramId, options = {}) {
|
|
295
|
+
const format = options.format || 'json';
|
|
296
|
+
const data = await this.client.request('GET', `/v2/threat-modeling/diagrams/${diagramId}/export/`, {
|
|
297
|
+
params: { format }
|
|
298
|
+
});
|
|
299
|
+
if (options.outputPath) {
|
|
300
|
+
if (format === 'json') {
|
|
301
|
+
fs.writeFileSync(options.outputPath, JSON.stringify(data, null, 2));
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
fs.writeFileSync(options.outputPath, data);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return data;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
// =============================================================================
|
|
311
|
+
// CLOUD SECURITY RESOURCE
|
|
312
|
+
// =============================================================================
|
|
313
|
+
class CloudSecurityResource {
|
|
314
|
+
client;
|
|
315
|
+
constructor(client) {
|
|
316
|
+
this.client = client;
|
|
317
|
+
}
|
|
318
|
+
async scanPosture(cloudProvider) {
|
|
319
|
+
return this.client.request('POST', '/v2/cloud-security/scan/', {
|
|
320
|
+
params: cloudProvider ? { provider: cloudProvider } : {}
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
async getFindings(options = {}) {
|
|
324
|
+
const data = await this.client.request('GET', '/v2/cloud-security/findings/', {
|
|
325
|
+
params: {
|
|
326
|
+
status: options.status || 'open',
|
|
327
|
+
limit: options.limit || 50,
|
|
328
|
+
...(options.severity && { severity: options.severity })
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
return data.results || data.findings || [];
|
|
332
|
+
}
|
|
333
|
+
async getDashboard() {
|
|
334
|
+
return this.client.request('GET', '/v2/cloud-security/dashboard/');
|
|
335
|
+
}
|
|
336
|
+
async remediate(findingId, autoFix = false) {
|
|
337
|
+
return this.client.request('POST', `/v2/cloud-security/findings/${findingId}/remediate/`, {
|
|
338
|
+
body: { auto_fix: autoFix }
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// =============================================================================
|
|
343
|
+
// COMPLIANCE RESOURCE
|
|
344
|
+
// =============================================================================
|
|
345
|
+
class ComplianceResource {
|
|
346
|
+
client;
|
|
347
|
+
// 100+ supported standards
|
|
348
|
+
static SUPPORTED_STANDARDS = [
|
|
349
|
+
'SOC2', 'ISO27001', 'ISO27017', 'ISO27018', 'ISO22301',
|
|
350
|
+
'NIST-CSF', 'NIST-800-53', 'NIST-800-171',
|
|
351
|
+
'PCI-DSS', 'PCI-DSS-4.0',
|
|
352
|
+
'GDPR', 'CCPA', 'LGPD', 'PIPEDA',
|
|
353
|
+
'HIPAA', 'HITRUST',
|
|
354
|
+
'FedRAMP-Low', 'FedRAMP-Moderate', 'FedRAMP-High',
|
|
355
|
+
'CIS-AWS', 'CIS-Azure', 'CIS-GCP', 'CIS-Kubernetes',
|
|
356
|
+
'SOX', 'GLBA', 'FISMA',
|
|
357
|
+
'CSA-CCM', 'CSA-STAR',
|
|
358
|
+
'MITRE-ATT&CK', 'OWASP-TOP-10',
|
|
359
|
+
];
|
|
360
|
+
constructor(client) {
|
|
361
|
+
this.client = client;
|
|
362
|
+
}
|
|
363
|
+
async listStandards() {
|
|
364
|
+
return this.client.request('GET', '/v2/compliances/custom-standards/');
|
|
365
|
+
}
|
|
366
|
+
async assess(diagramId, standard = 'SOC2', includeRecommendations = true) {
|
|
367
|
+
return this.client.request('POST', '/v2/compliances/assess_diagram/', {
|
|
368
|
+
body: {
|
|
369
|
+
diagram_id: diagramId,
|
|
370
|
+
standard,
|
|
371
|
+
include_recommendations: includeRecommendations
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
async getAssessment(assessmentId) {
|
|
376
|
+
return this.client.request('GET', `/v2/compliances/compliance-reports/${assessmentId}/`);
|
|
377
|
+
}
|
|
378
|
+
async listReports(limit = 20) {
|
|
379
|
+
const data = await this.client.request('GET', '/v2/compliances/reports/', {
|
|
380
|
+
params: { limit }
|
|
381
|
+
});
|
|
382
|
+
return data.results || [];
|
|
383
|
+
}
|
|
384
|
+
async runScan(targetId, standards = ['SOC2', 'ISO27001'], scanType = 'comprehensive') {
|
|
385
|
+
return this.client.request('POST', '/v2/compliances/scan/', {
|
|
386
|
+
body: { target_id: targetId, standards, scan_type: scanType }
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
async getRemediation(findingId) {
|
|
390
|
+
return this.client.request('GET', `/v2/compliances/remediation/${findingId}/`);
|
|
391
|
+
}
|
|
392
|
+
async getDashboard() {
|
|
393
|
+
return this.client.request('GET', '/v2/compliances/dashboard/trends/');
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
// =============================================================================
|
|
397
|
+
// ECONOMICS INTELLIGENCE RESOURCE
|
|
398
|
+
// =============================================================================
|
|
399
|
+
class EconomicsResource {
|
|
400
|
+
client;
|
|
401
|
+
constructor(client) {
|
|
402
|
+
this.client = client;
|
|
403
|
+
}
|
|
404
|
+
async calculateROI(securityInvestment, riskReductionPercent = 50, timeHorizonYears = 3) {
|
|
405
|
+
return this.client.request('POST', '/v2/economic-intelligence/v2/roi/create/', {
|
|
406
|
+
body: {
|
|
407
|
+
investment: securityInvestment,
|
|
408
|
+
risk_reduction: riskReductionPercent,
|
|
409
|
+
time_horizon: timeHorizonYears
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
async calculateTCO(cloudProvider, workloadType = 'general', durationMonths = 36) {
|
|
414
|
+
return this.client.request('POST', '/v2/economic-intelligence/tco/', {
|
|
415
|
+
body: {
|
|
416
|
+
provider: cloudProvider,
|
|
417
|
+
workload_type: workloadType,
|
|
418
|
+
duration_months: durationMonths
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
async analyzeCosts(diagramId) {
|
|
423
|
+
return this.client.request('POST', '/v2/economic-intelligence/analyze/', {
|
|
424
|
+
body: { diagram_id: diagramId }
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
async getMarketIntelligence() {
|
|
428
|
+
return this.client.request('GET', '/v2/economic-intelligence/v2/intelligence/');
|
|
429
|
+
}
|
|
430
|
+
async getDashboard() {
|
|
431
|
+
return this.client.request('GET', '/v2/economic-intelligence/v2/dashboard/');
|
|
432
|
+
}
|
|
433
|
+
async createForecast(months = 12) {
|
|
434
|
+
return this.client.request('POST', '/v2/economic-intelligence/v2/forecast/create/', {
|
|
435
|
+
body: { forecast_months: months }
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
// =============================================================================
|
|
440
|
+
// FINOPS RESOURCE
|
|
441
|
+
// =============================================================================
|
|
442
|
+
class FinOpsResource {
|
|
443
|
+
client;
|
|
444
|
+
constructor(client) {
|
|
445
|
+
this.client = client;
|
|
446
|
+
}
|
|
447
|
+
async getCloudCosts(options = {}) {
|
|
448
|
+
return this.client.request('GET', '/v2/finops/costs/', {
|
|
449
|
+
params: {
|
|
450
|
+
period: options.period || 'month',
|
|
451
|
+
...(options.provider && { provider: options.provider })
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
async getSecuritySpend() {
|
|
456
|
+
return this.client.request('GET', '/v2/finops/security-spend/');
|
|
457
|
+
}
|
|
458
|
+
async getOptimizationRecommendations() {
|
|
459
|
+
const data = await this.client.request('GET', '/v2/finops/recommendations/');
|
|
460
|
+
return data.recommendations || [];
|
|
461
|
+
}
|
|
462
|
+
async getPricing(service, provider = 'aws') {
|
|
463
|
+
return this.client.request('GET', '/v2/economic-intelligence/pricing/', {
|
|
464
|
+
params: { service, provider }
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
// =============================================================================
|
|
469
|
+
// RED TEAM RESOURCE
|
|
470
|
+
// =============================================================================
|
|
471
|
+
class RedTeamResource {
|
|
472
|
+
client;
|
|
473
|
+
static ATTACK_TYPES = [
|
|
474
|
+
'lateral_movement',
|
|
475
|
+
'privilege_escalation',
|
|
476
|
+
'data_exfiltration',
|
|
477
|
+
'ransomware',
|
|
478
|
+
'supply_chain',
|
|
479
|
+
'insider_threat',
|
|
480
|
+
'credential_theft',
|
|
481
|
+
'api_abuse',
|
|
482
|
+
];
|
|
483
|
+
constructor(client) {
|
|
484
|
+
this.client = client;
|
|
485
|
+
}
|
|
486
|
+
async runSimulation(targetId, attackType = 'lateral_movement', intensity = 'medium') {
|
|
487
|
+
if (!RedTeamResource.ATTACK_TYPES.includes(attackType)) {
|
|
488
|
+
throw new AribotError(`Invalid attack type. Choose from: ${RedTeamResource.ATTACK_TYPES.join(', ')}`);
|
|
489
|
+
}
|
|
490
|
+
return this.client.request('POST', '/v2/redteam/simulate/', {
|
|
491
|
+
body: {
|
|
492
|
+
target_id: targetId,
|
|
493
|
+
attack_type: attackType,
|
|
494
|
+
intensity
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
async getAttackPaths(diagramId) {
|
|
499
|
+
const data = await this.client.request('GET', `/v2/threat-modeling/diagrams/${diagramId}/attack-paths/`);
|
|
500
|
+
return data.attack_paths || [];
|
|
501
|
+
}
|
|
502
|
+
async listSimulations(limit = 20) {
|
|
503
|
+
const data = await this.client.request('GET', '/v2/redteam/simulations/', {
|
|
504
|
+
params: { limit }
|
|
505
|
+
});
|
|
506
|
+
return data.results || [];
|
|
507
|
+
}
|
|
508
|
+
async getSimulation(simulationId) {
|
|
509
|
+
return this.client.request('GET', `/v2/redteam/simulations/${simulationId}/`);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
// =============================================================================
|
|
513
|
+
// ARCHITECTURE RESOURCE
|
|
514
|
+
// =============================================================================
|
|
515
|
+
class ArchitectureResource {
|
|
516
|
+
client;
|
|
517
|
+
constructor(client) {
|
|
518
|
+
this.client = client;
|
|
519
|
+
}
|
|
520
|
+
async listComponents(diagramId) {
|
|
521
|
+
const data = await this.client.request('GET', `/v2/threat-modeling/diagrams/${diagramId}/components/`);
|
|
522
|
+
return data.components || data.results || [];
|
|
523
|
+
}
|
|
524
|
+
async getComponent(diagramId, componentId) {
|
|
525
|
+
return this.client.request('GET', `/v2/threat-modeling/diagrams/${diagramId}/components/${componentId}/`);
|
|
526
|
+
}
|
|
527
|
+
async updateComponent(diagramId, componentId, updates) {
|
|
528
|
+
return this.client.request('PATCH', `/v2/threat-modeling/diagrams/${diagramId}/components/${componentId}/`, {
|
|
529
|
+
body: updates
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
async getConnections(diagramId) {
|
|
533
|
+
const data = await this.client.request('GET', `/v2/threat-modeling/diagrams/${diagramId}/connections/`);
|
|
534
|
+
return data.connections || data.results || [];
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
// =============================================================================
|
|
538
|
+
// USER RESOURCE
|
|
539
|
+
// =============================================================================
|
|
540
|
+
class UserResource {
|
|
541
|
+
client;
|
|
542
|
+
constructor(client) {
|
|
543
|
+
this.client = client;
|
|
544
|
+
}
|
|
545
|
+
async me() {
|
|
546
|
+
return this.client.request('GET', '/v1/users/me/');
|
|
547
|
+
}
|
|
548
|
+
async apiKeys() {
|
|
549
|
+
return this.client.request('GET', '/v1/developer/api-keys/');
|
|
550
|
+
}
|
|
551
|
+
async getUsage() {
|
|
552
|
+
return this.client.request('GET', '/v1/developer/usage/');
|
|
553
|
+
}
|
|
554
|
+
async getRateLimits() {
|
|
555
|
+
return this.client.request('GET', '/v1/developer/rate-limits/');
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
// =============================================================================
|
|
559
|
+
// AI RESOURCE - Secure AI Usage Management
|
|
560
|
+
// =============================================================================
|
|
561
|
+
class AIResource {
|
|
562
|
+
client;
|
|
563
|
+
/**
|
|
564
|
+
* Secure AI usage management and configuration.
|
|
565
|
+
*
|
|
566
|
+
* Features:
|
|
567
|
+
* - AI model selection and configuration
|
|
568
|
+
* - Usage tracking and quotas
|
|
569
|
+
* - Cost monitoring for AI operations
|
|
570
|
+
* - Secure prompt/response handling
|
|
571
|
+
* - AI processing queue management
|
|
572
|
+
*
|
|
573
|
+
* Security:
|
|
574
|
+
* - All AI requests are signed and authenticated
|
|
575
|
+
* - Sensitive data is sanitized before AI processing
|
|
576
|
+
* - Usage is tracked per API key for audit compliance
|
|
577
|
+
* - Rate limiting prevents abuse
|
|
578
|
+
*/
|
|
579
|
+
static AI_OPERATIONS = [
|
|
580
|
+
'threat_analysis',
|
|
581
|
+
'diagram_parsing',
|
|
582
|
+
'compliance_mapping',
|
|
583
|
+
'risk_scoring',
|
|
584
|
+
'attack_path_analysis',
|
|
585
|
+
'remediation_generation',
|
|
586
|
+
'architecture_optimization',
|
|
587
|
+
];
|
|
588
|
+
static MODEL_TIERS = ['standard', 'advanced', 'enterprise'];
|
|
589
|
+
constructor(client) {
|
|
590
|
+
this.client = client;
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Get AI usage statistics for the current billing period.
|
|
594
|
+
*/
|
|
595
|
+
async getUsage() {
|
|
596
|
+
return this.client.request('GET', '/v2/ai/usage/');
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Get current AI quota and limits.
|
|
600
|
+
*/
|
|
601
|
+
async getQuota() {
|
|
602
|
+
return this.client.request('GET', '/v2/ai/quota/');
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* List available AI models for your subscription tier.
|
|
606
|
+
*/
|
|
607
|
+
async getModels() {
|
|
608
|
+
return this.client.request('GET', '/v2/ai/models/');
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Configure AI settings for your account.
|
|
612
|
+
*/
|
|
613
|
+
async configure(options = {}) {
|
|
614
|
+
const modelTier = options.modelTier || 'standard';
|
|
615
|
+
if (!AIResource.MODEL_TIERS.includes(modelTier)) {
|
|
616
|
+
throw new AribotError(`Invalid model tier. Choose from: ${AIResource.MODEL_TIERS.join(', ')}`);
|
|
617
|
+
}
|
|
618
|
+
return this.client.request('POST', '/v2/ai/configure/', {
|
|
619
|
+
body: {
|
|
620
|
+
model_tier: modelTier,
|
|
621
|
+
max_tokens: options.maxTokens || 4000,
|
|
622
|
+
temperature: options.temperature || 0.7,
|
|
623
|
+
enable_caching: options.enableCaching !== false,
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Run AI analysis on content.
|
|
629
|
+
*/
|
|
630
|
+
async analyze(content, options = {}) {
|
|
631
|
+
const operation = options.operation || 'threat_analysis';
|
|
632
|
+
if (!AIResource.AI_OPERATIONS.includes(operation)) {
|
|
633
|
+
throw new AribotError(`Invalid operation. Choose from: ${AIResource.AI_OPERATIONS.join(', ')}`);
|
|
634
|
+
}
|
|
635
|
+
return this.client.request('POST', '/v2/ai/analyze/', {
|
|
636
|
+
body: {
|
|
637
|
+
content,
|
|
638
|
+
operation,
|
|
639
|
+
context: options.context || {},
|
|
640
|
+
sanitize_pii: options.sanitizePii !== false,
|
|
641
|
+
}
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Get status of pending AI processing jobs.
|
|
646
|
+
*/
|
|
647
|
+
async getQueueStatus() {
|
|
648
|
+
return this.client.request('GET', '/v2/ai/queue/status/');
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* List AI processing jobs.
|
|
652
|
+
*/
|
|
653
|
+
async listJobs(options = {}) {
|
|
654
|
+
const data = await this.client.request('GET', '/v2/ai/jobs/', {
|
|
655
|
+
params: {
|
|
656
|
+
status: options.status || 'all',
|
|
657
|
+
limit: options.limit || 20,
|
|
658
|
+
}
|
|
659
|
+
});
|
|
660
|
+
return data.results || [];
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Get details of a specific AI job.
|
|
664
|
+
*/
|
|
665
|
+
async getJob(jobId) {
|
|
666
|
+
return this.client.request('GET', `/v2/ai/jobs/${jobId}/`);
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Cancel a pending AI job.
|
|
670
|
+
*/
|
|
671
|
+
async cancelJob(jobId) {
|
|
672
|
+
return this.client.request('POST', `/v2/ai/jobs/${jobId}/cancel/`);
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Get cost estimate for an AI operation before executing.
|
|
676
|
+
*/
|
|
677
|
+
async getCostEstimate(operation, contentLength, modelTier = 'standard') {
|
|
678
|
+
return this.client.request('POST', '/v2/ai/estimate/', {
|
|
679
|
+
body: {
|
|
680
|
+
operation,
|
|
681
|
+
content_length: contentLength,
|
|
682
|
+
model_tier: modelTier,
|
|
683
|
+
}
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Get AI usage audit log for compliance.
|
|
688
|
+
*/
|
|
689
|
+
async getAuditLog(options = {}) {
|
|
690
|
+
const params = { limit: options.limit || 100 };
|
|
691
|
+
if (options.startDate)
|
|
692
|
+
params.start_date = options.startDate;
|
|
693
|
+
if (options.endDate)
|
|
694
|
+
params.end_date = options.endDate;
|
|
695
|
+
const data = await this.client.request('GET', '/v2/ai/audit/', { params });
|
|
696
|
+
return data.entries || [];
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
// =============================================================================
|
|
700
|
+
// SECURITY UTILITIES
|
|
701
|
+
// =============================================================================
|
|
702
|
+
/**
|
|
703
|
+
* HMAC-SHA256 request signing for API request integrity.
|
|
704
|
+
*/
|
|
705
|
+
class RequestSigner {
|
|
706
|
+
/**
|
|
707
|
+
* Generate HMAC-SHA256 signature for request.
|
|
708
|
+
*/
|
|
709
|
+
static sign(apiKey, method, path, timestamp, body) {
|
|
710
|
+
const parts = [method.toUpperCase(), path, timestamp];
|
|
711
|
+
if (body) {
|
|
712
|
+
const bodyHash = crypto.createHash('sha256').update(body).digest('hex');
|
|
713
|
+
parts.push(bodyHash);
|
|
714
|
+
}
|
|
715
|
+
const canonical = parts.join('\n');
|
|
716
|
+
const signature = crypto
|
|
717
|
+
.createHmac('sha256', apiKey)
|
|
718
|
+
.update(canonical)
|
|
719
|
+
.digest('base64');
|
|
720
|
+
return signature;
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Verify request signature and timestamp freshness.
|
|
724
|
+
*/
|
|
725
|
+
static verify(apiKey, signature, method, path, timestamp, body, maxAgeSeconds = 300) {
|
|
726
|
+
// Check timestamp freshness
|
|
727
|
+
try {
|
|
728
|
+
const ts = new Date(timestamp);
|
|
729
|
+
const age = Math.abs(Date.now() - ts.getTime()) / 1000;
|
|
730
|
+
if (age > maxAgeSeconds)
|
|
731
|
+
return false;
|
|
732
|
+
}
|
|
733
|
+
catch {
|
|
734
|
+
return false;
|
|
735
|
+
}
|
|
736
|
+
// Verify signature
|
|
737
|
+
const expected = RequestSigner.sign(apiKey, method, path, timestamp, body);
|
|
738
|
+
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
exports.RequestSigner = RequestSigner;
|
|
742
|
+
/**
|
|
743
|
+
* Secure credential storage utilities.
|
|
744
|
+
*/
|
|
745
|
+
class SecureCredentialManager {
|
|
746
|
+
static SERVICE_NAME = 'aribot-api';
|
|
747
|
+
/**
|
|
748
|
+
* Store API key securely using environment variable.
|
|
749
|
+
* For production, use OS keyring via native modules.
|
|
750
|
+
*/
|
|
751
|
+
static setApiKey(apiKey) {
|
|
752
|
+
process.env.ARIBOT_API_KEY = apiKey;
|
|
753
|
+
}
|
|
754
|
+
/**
|
|
755
|
+
* Retrieve API key from environment.
|
|
756
|
+
*/
|
|
757
|
+
static getApiKey() {
|
|
758
|
+
return process.env.ARIBOT_API_KEY;
|
|
759
|
+
}
|
|
760
|
+
/**
|
|
761
|
+
* Clear stored API key.
|
|
762
|
+
*/
|
|
763
|
+
static clearApiKey() {
|
|
764
|
+
delete process.env.ARIBOT_API_KEY;
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* Validate API key format.
|
|
768
|
+
*/
|
|
769
|
+
static isValidFormat(apiKey) {
|
|
770
|
+
return /^ak_[a-zA-Z0-9]{32,}$/.test(apiKey);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
exports.SecureCredentialManager = SecureCredentialManager;
|
|
774
|
+
// =============================================================================
|
|
775
|
+
// CONVENIENCE FUNCTIONS
|
|
776
|
+
// =============================================================================
|
|
777
|
+
/**
|
|
778
|
+
* Quick function to analyze a diagram and get threats.
|
|
779
|
+
*/
|
|
780
|
+
async function analyzeDiagram(filePath, options = {}) {
|
|
781
|
+
const client = new AribotClient({ apiKey: options.apiKey });
|
|
782
|
+
const diagram = await client.threatModeling.upload(filePath, {
|
|
783
|
+
name: options.name,
|
|
784
|
+
autoGenerateThreats: options.waitForThreats !== false
|
|
785
|
+
});
|
|
786
|
+
if (options.waitForThreats !== false) {
|
|
787
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
788
|
+
for (let i = 0; i < 30; i++) {
|
|
789
|
+
const updated = await client.threatModeling.get(diagram.id);
|
|
790
|
+
if (updated.stage === 'completed') {
|
|
791
|
+
break;
|
|
792
|
+
}
|
|
793
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
794
|
+
}
|
|
795
|
+
const threats = await client.threatModeling.getThreats(diagram.id);
|
|
796
|
+
return { diagram, threats };
|
|
797
|
+
}
|
|
798
|
+
return { diagram, threats: [] };
|
|
799
|
+
}
|
|
800
|
+
/**
|
|
801
|
+
* Quick compliance check against multiple standards.
|
|
802
|
+
*/
|
|
803
|
+
async function runComplianceCheck(diagramId, standards = ['SOC2', 'ISO27001'], apiKey) {
|
|
804
|
+
const client = new AribotClient({ apiKey });
|
|
805
|
+
return client.compliance.runScan(diagramId, standards);
|
|
806
|
+
}
|
|
807
|
+
// Export default client
|
|
808
|
+
exports.default = AribotClient;
|