buildhive-agent 1.0.0-beta.1

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 (170) hide show
  1. package/README.md +166 -0
  2. package/dist/__tests__/fakes/FakeDockerManager.d.ts +115 -0
  3. package/dist/__tests__/fakes/FakeDockerManager.d.ts.map +1 -0
  4. package/dist/__tests__/fakes/FakeDockerManager.js +203 -0
  5. package/dist/__tests__/fakes/FakeDockerManager.js.map +1 -0
  6. package/dist/acceptanceChecker.d.ts +26 -0
  7. package/dist/acceptanceChecker.d.ts.map +1 -0
  8. package/dist/acceptanceChecker.js +64 -0
  9. package/dist/acceptanceChecker.js.map +1 -0
  10. package/dist/advancedAgent.d.ts +161 -0
  11. package/dist/advancedAgent.d.ts.map +1 -0
  12. package/dist/advancedAgent.js +604 -0
  13. package/dist/advancedAgent.js.map +1 -0
  14. package/dist/agent.d.ts +101 -0
  15. package/dist/agent.d.ts.map +1 -0
  16. package/dist/agent.js +490 -0
  17. package/dist/agent.js.map +1 -0
  18. package/dist/api/jobStatusApi.d.ts +88 -0
  19. package/dist/api/jobStatusApi.d.ts.map +1 -0
  20. package/dist/api/jobStatusApi.js +240 -0
  21. package/dist/api/jobStatusApi.js.map +1 -0
  22. package/dist/autoUpdater.d.ts +135 -0
  23. package/dist/autoUpdater.d.ts.map +1 -0
  24. package/dist/autoUpdater.js +494 -0
  25. package/dist/autoUpdater.js.map +1 -0
  26. package/dist/cacheManager.d.ts +108 -0
  27. package/dist/cacheManager.d.ts.map +1 -0
  28. package/dist/cacheManager.js +300 -0
  29. package/dist/cacheManager.js.map +1 -0
  30. package/dist/cli.d.ts +11 -0
  31. package/dist/cli.d.ts.map +1 -0
  32. package/dist/cli.js +749 -0
  33. package/dist/cli.js.map +1 -0
  34. package/dist/config/index.d.ts +30 -0
  35. package/dist/config/index.d.ts.map +1 -0
  36. package/dist/config/index.js +35 -0
  37. package/dist/config/index.js.map +1 -0
  38. package/dist/config/loader.d.ts +45 -0
  39. package/dist/config/loader.d.ts.map +1 -0
  40. package/dist/config/loader.js +269 -0
  41. package/dist/config/loader.js.map +1 -0
  42. package/dist/config/types.d.ts +193 -0
  43. package/dist/config/types.d.ts.map +1 -0
  44. package/dist/config/types.js +90 -0
  45. package/dist/config/types.js.map +1 -0
  46. package/dist/config/validation.d.ts +28 -0
  47. package/dist/config/validation.d.ts.map +1 -0
  48. package/dist/config/validation.js +397 -0
  49. package/dist/config/validation.js.map +1 -0
  50. package/dist/docker.d.ts +96 -0
  51. package/dist/docker.d.ts.map +1 -0
  52. package/dist/docker.js +411 -0
  53. package/dist/docker.js.map +1 -0
  54. package/dist/enhancedJobExecutor.d.ts +81 -0
  55. package/dist/enhancedJobExecutor.d.ts.map +1 -0
  56. package/dist/enhancedJobExecutor.js +223 -0
  57. package/dist/enhancedJobExecutor.js.map +1 -0
  58. package/dist/executors/executorFactory.d.ts +46 -0
  59. package/dist/executors/executorFactory.d.ts.map +1 -0
  60. package/dist/executors/executorFactory.js +80 -0
  61. package/dist/executors/executorFactory.js.map +1 -0
  62. package/dist/executors/index.d.ts +7 -0
  63. package/dist/executors/index.d.ts.map +1 -0
  64. package/dist/executors/index.js +6 -0
  65. package/dist/executors/index.js.map +1 -0
  66. package/dist/executors/nativeExecutor.d.ts +60 -0
  67. package/dist/executors/nativeExecutor.d.ts.map +1 -0
  68. package/dist/executors/nativeExecutor.js +311 -0
  69. package/dist/executors/nativeExecutor.js.map +1 -0
  70. package/dist/executors/types.d.ts +38 -0
  71. package/dist/executors/types.d.ts.map +1 -0
  72. package/dist/executors/types.js +9 -0
  73. package/dist/executors/types.js.map +1 -0
  74. package/dist/healthMonitor.d.ts +213 -0
  75. package/dist/healthMonitor.d.ts.map +1 -0
  76. package/dist/healthMonitor.js +547 -0
  77. package/dist/healthMonitor.js.map +1 -0
  78. package/dist/index.d.ts +16 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +16 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/jobExecutor.d.ts +117 -0
  83. package/dist/jobExecutor.d.ts.map +1 -0
  84. package/dist/jobExecutor.js +458 -0
  85. package/dist/jobExecutor.js.map +1 -0
  86. package/dist/lifecycleExecutor.d.ts +54 -0
  87. package/dist/lifecycleExecutor.d.ts.map +1 -0
  88. package/dist/lifecycleExecutor.js +230 -0
  89. package/dist/lifecycleExecutor.js.map +1 -0
  90. package/dist/main.d.ts +15 -0
  91. package/dist/main.d.ts.map +1 -0
  92. package/dist/main.js +77 -0
  93. package/dist/main.js.map +1 -0
  94. package/dist/metrics.d.ts +103 -0
  95. package/dist/metrics.d.ts.map +1 -0
  96. package/dist/metrics.js +360 -0
  97. package/dist/metrics.js.map +1 -0
  98. package/dist/recipes/builtinRecipes.d.ts +11 -0
  99. package/dist/recipes/builtinRecipes.d.ts.map +1 -0
  100. package/dist/recipes/builtinRecipes.js +688 -0
  101. package/dist/recipes/builtinRecipes.js.map +1 -0
  102. package/dist/recipes/index.d.ts +18 -0
  103. package/dist/recipes/index.d.ts.map +1 -0
  104. package/dist/recipes/index.js +17 -0
  105. package/dist/recipes/index.js.map +1 -0
  106. package/dist/recipes/recipeRegistry.d.ts +49 -0
  107. package/dist/recipes/recipeRegistry.d.ts.map +1 -0
  108. package/dist/recipes/recipeRegistry.js +264 -0
  109. package/dist/recipes/recipeRegistry.js.map +1 -0
  110. package/dist/recipes/types.d.ts +116 -0
  111. package/dist/recipes/types.d.ts.map +1 -0
  112. package/dist/recipes/types.js +10 -0
  113. package/dist/recipes/types.js.map +1 -0
  114. package/dist/recovery.d.ts +133 -0
  115. package/dist/recovery.d.ts.map +1 -0
  116. package/dist/recovery.js +299 -0
  117. package/dist/recovery.js.map +1 -0
  118. package/dist/registration/apiClient.d.ts +44 -0
  119. package/dist/registration/apiClient.d.ts.map +1 -0
  120. package/dist/registration/apiClient.js +149 -0
  121. package/dist/registration/apiClient.js.map +1 -0
  122. package/dist/registration/index.d.ts +41 -0
  123. package/dist/registration/index.d.ts.map +1 -0
  124. package/dist/registration/index.js +141 -0
  125. package/dist/registration/index.js.map +1 -0
  126. package/dist/registration/machineId.d.ts +30 -0
  127. package/dist/registration/machineId.d.ts.map +1 -0
  128. package/dist/registration/machineId.js +89 -0
  129. package/dist/registration/machineId.js.map +1 -0
  130. package/dist/registration/types.d.ts +32 -0
  131. package/dist/registration/types.d.ts.map +1 -0
  132. package/dist/registration/types.js +9 -0
  133. package/dist/registration/types.js.map +1 -0
  134. package/dist/resourceGovernor.d.ts +57 -0
  135. package/dist/resourceGovernor.d.ts.map +1 -0
  136. package/dist/resourceGovernor.js +125 -0
  137. package/dist/resourceGovernor.js.map +1 -0
  138. package/dist/security/secretManager.d.ts +107 -0
  139. package/dist/security/secretManager.d.ts.map +1 -0
  140. package/dist/security/secretManager.js +361 -0
  141. package/dist/security/secretManager.js.map +1 -0
  142. package/dist/security.d.ts +134 -0
  143. package/dist/security.d.ts.map +1 -0
  144. package/dist/security.js +470 -0
  145. package/dist/security.js.map +1 -0
  146. package/dist/storage/artifactUploader.d.ts +155 -0
  147. package/dist/storage/artifactUploader.d.ts.map +1 -0
  148. package/dist/storage/artifactUploader.js +554 -0
  149. package/dist/storage/artifactUploader.js.map +1 -0
  150. package/dist/types.d.ts +49 -0
  151. package/dist/types.d.ts.map +1 -0
  152. package/dist/types.js +7 -0
  153. package/dist/types.js.map +1 -0
  154. package/dist/utils/capabilities.d.ts +23 -0
  155. package/dist/utils/capabilities.d.ts.map +1 -0
  156. package/dist/utils/capabilities.js +200 -0
  157. package/dist/utils/capabilities.js.map +1 -0
  158. package/dist/utils/logger.d.ts +20 -0
  159. package/dist/utils/logger.d.ts.map +1 -0
  160. package/dist/utils/logger.js +188 -0
  161. package/dist/utils/logger.js.map +1 -0
  162. package/dist/utils/sdkScanner.d.ts +105 -0
  163. package/dist/utils/sdkScanner.d.ts.map +1 -0
  164. package/dist/utils/sdkScanner.js +459 -0
  165. package/dist/utils/sdkScanner.js.map +1 -0
  166. package/dist/websocketClient.d.ts +154 -0
  167. package/dist/websocketClient.d.ts.map +1 -0
  168. package/dist/websocketClient.js +422 -0
  169. package/dist/websocketClient.js.map +1 -0
  170. package/package.json +64 -0
@@ -0,0 +1,470 @@
1
+ /**
2
+ * Security Manager - Enhanced Docker security configuration and validation
3
+ *
4
+ * Provides comprehensive security measures for container execution including
5
+ * resource limits, network isolation, filesystem security, and monitoring.
6
+ *
7
+ * Requirements: 4.1, 4.2, 4.3, 4.4, 4.5
8
+ */
9
+ import { createLogger } from './utils/logger.js';
10
+ import { promises as fs } from 'fs';
11
+ import { join, resolve } from 'path';
12
+ import { spawn } from 'child_process';
13
+ const logger = createLogger('security');
14
+ export class SecurityManager {
15
+ config;
16
+ violations = [];
17
+ resourceMonitors = new Map();
18
+ constructor(config) {
19
+ this.config = config;
20
+ logger.info('Security manager initialized with enhanced configuration');
21
+ }
22
+ /**
23
+ * Generate secure Docker arguments for container creation
24
+ */
25
+ generateSecureDockerArgs(containerId) {
26
+ const args = [];
27
+ // Basic security settings
28
+ args.push('--security-opt', 'no-new-privileges:true');
29
+ // Drop all capabilities by default
30
+ if (this.config.dropAllCapabilities) {
31
+ args.push('--cap-drop', 'ALL');
32
+ // Add only explicitly allowed capabilities
33
+ for (const cap of this.config.allowedCapabilities) {
34
+ args.push('--cap-add', cap);
35
+ }
36
+ }
37
+ // Network isolation
38
+ args.push('--network', this.config.networkMode);
39
+ if (this.config.networkMode === 'none') {
40
+ logger.info(`Container ${containerId} will have no network access`);
41
+ }
42
+ // Resource limits
43
+ args.push('--memory', `${this.config.maxMemoryMB}m`);
44
+ args.push('--cpus', this.config.maxCpuCores.toString());
45
+ args.push('--pids-limit', this.config.maxProcesses.toString());
46
+ args.push('--ulimit', `nofile=${this.config.maxFileDescriptors}:${this.config.maxFileDescriptors}`);
47
+ // Filesystem security
48
+ if (this.config.readOnlyRoot) {
49
+ args.push('--read-only');
50
+ // Create secure temporary directories
51
+ args.push('--tmpfs', `/tmp:rw,noexec,nosuid,nodev,size=${this.config.tempDirSizeMB}m`);
52
+ args.push('--tmpfs', `/var/tmp:rw,noexec,nosuid,nodev,size=${this.config.tempDirSizeMB}m`);
53
+ // Add writable paths as tmpfs mounts
54
+ for (const writePath of this.config.allowedWritePaths) {
55
+ args.push('--tmpfs', `${writePath}:rw,noexec,nosuid,nodev,size=100m`);
56
+ }
57
+ }
58
+ // Security profiles
59
+ if (this.config.seccompProfile) {
60
+ args.push('--security-opt', `seccomp=${this.config.seccompProfile}`);
61
+ }
62
+ if (this.config.apparmorProfile) {
63
+ args.push('--security-opt', `apparmor=${this.config.apparmorProfile}`);
64
+ }
65
+ // Additional hardening
66
+ args.push('--security-opt', 'no-new-privileges:true');
67
+ args.push('--user', '1000:1000'); // Run as non-root user
68
+ args.push('--init'); // Use proper init system
69
+ logger.info(`Generated ${args.length / 2} security arguments for container ${containerId}`);
70
+ return args;
71
+ }
72
+ /**
73
+ * Validate container configuration against security policies
74
+ */
75
+ async validateContainerConfig(config) {
76
+ const violations = [];
77
+ // Check resource limits
78
+ if (config.memoryLimit && this.parseMemoryLimit(config.memoryLimit) > this.config.maxMemoryMB) {
79
+ violations.push({
80
+ type: 'resource',
81
+ severity: 'high',
82
+ message: `Memory limit ${config.memoryLimit} exceeds maximum allowed ${this.config.maxMemoryMB}MB`,
83
+ containerId: config.containerId || 'unknown',
84
+ timestamp: new Date()
85
+ });
86
+ }
87
+ // Check CPU limits
88
+ if (config.cpuLimit && parseFloat(config.cpuLimit) > this.config.maxCpuCores) {
89
+ violations.push({
90
+ type: 'resource',
91
+ severity: 'high',
92
+ message: `CPU limit ${config.cpuLimit} exceeds maximum allowed ${this.config.maxCpuCores}`,
93
+ containerId: config.containerId || 'unknown',
94
+ timestamp: new Date()
95
+ });
96
+ }
97
+ // Check network configuration
98
+ if (config.networkMode && config.networkMode !== this.config.networkMode) {
99
+ violations.push({
100
+ type: 'network',
101
+ severity: 'critical',
102
+ message: `Network mode ${config.networkMode} not allowed, must use ${this.config.networkMode}`,
103
+ containerId: config.containerId || 'unknown',
104
+ timestamp: new Date()
105
+ });
106
+ }
107
+ // Check for privileged mode
108
+ if (config.privileged) {
109
+ violations.push({
110
+ type: 'capability',
111
+ severity: 'critical',
112
+ message: 'Privileged mode is not allowed',
113
+ containerId: config.containerId || 'unknown',
114
+ timestamp: new Date()
115
+ });
116
+ }
117
+ // Check volume mounts for security risks
118
+ if (config.volumeMounts) {
119
+ for (const mount of config.volumeMounts) {
120
+ if (this.isUnsafeMount(mount.hostPath)) {
121
+ violations.push({
122
+ type: 'filesystem',
123
+ severity: 'critical',
124
+ message: `Unsafe volume mount detected: ${mount.hostPath}`,
125
+ containerId: config.containerId || 'unknown',
126
+ timestamp: new Date(),
127
+ details: { mount }
128
+ });
129
+ }
130
+ }
131
+ }
132
+ return violations;
133
+ }
134
+ /**
135
+ * Start resource monitoring for a container
136
+ */
137
+ async startResourceMonitoring(containerId) {
138
+ if (!this.config.enableResourceMonitoring) {
139
+ return;
140
+ }
141
+ logger.info(`Starting resource monitoring for container: ${containerId}`);
142
+ const monitor = setInterval(async () => {
143
+ try {
144
+ const usage = await this.getResourceUsage(containerId);
145
+ await this.checkResourceLimits(containerId, usage);
146
+ }
147
+ catch (error) {
148
+ logger.error(`Resource monitoring failed for container ${containerId}:`, error);
149
+ }
150
+ }, 5000); // Check every 5 seconds
151
+ this.resourceMonitors.set(containerId, monitor);
152
+ // Set up execution timeout
153
+ setTimeout(async () => {
154
+ await this.handleExecutionTimeout(containerId);
155
+ }, this.config.maxExecutionTimeSeconds * 1000);
156
+ }
157
+ /**
158
+ * Stop resource monitoring for a container
159
+ */
160
+ stopResourceMonitoring(containerId) {
161
+ const monitor = this.resourceMonitors.get(containerId);
162
+ if (monitor) {
163
+ clearInterval(monitor);
164
+ this.resourceMonitors.delete(containerId);
165
+ logger.info(`Stopped resource monitoring for container: ${containerId}`);
166
+ }
167
+ }
168
+ /**
169
+ * Get current resource usage for a container
170
+ */
171
+ async getResourceUsage(containerId) {
172
+ try {
173
+ const statsResult = await this.executeCommand('docker', [
174
+ 'stats', containerId, '--no-stream', '--format',
175
+ 'table {{.MemUsage}}\t{{.CPUPerc}}\t{{.PIDs}}\t{{.NetIO}}'
176
+ ]);
177
+ if (statsResult.exitCode !== 0) {
178
+ throw new Error(`Failed to get container stats: ${statsResult.error}`);
179
+ }
180
+ return this.parseResourceStats(statsResult.output);
181
+ }
182
+ catch (error) {
183
+ logger.error(`Failed to get resource usage for container ${containerId}:`, error);
184
+ throw error;
185
+ }
186
+ }
187
+ /**
188
+ * Check if resource usage exceeds limits
189
+ */
190
+ async checkResourceLimits(containerId, usage) {
191
+ const violations = [];
192
+ // Check memory usage
193
+ if (usage.memoryUsageMB > this.config.maxMemoryMB * 0.9) { // 90% threshold
194
+ violations.push({
195
+ type: 'resource',
196
+ severity: 'high',
197
+ message: `Memory usage ${usage.memoryUsageMB}MB approaching limit ${this.config.maxMemoryMB}MB`,
198
+ containerId,
199
+ timestamp: new Date(),
200
+ details: { usage }
201
+ });
202
+ }
203
+ // Check CPU usage
204
+ if (usage.cpuUsagePercent > this.config.maxCpuCores * 100 * 0.9) { // 90% threshold
205
+ violations.push({
206
+ type: 'resource',
207
+ severity: 'medium',
208
+ message: `CPU usage ${usage.cpuUsagePercent}% approaching limit`,
209
+ containerId,
210
+ timestamp: new Date(),
211
+ details: { usage }
212
+ });
213
+ }
214
+ // Check process count
215
+ if (usage.processCount > this.config.maxProcesses * 0.9) { // 90% threshold
216
+ violations.push({
217
+ type: 'resource',
218
+ severity: 'medium',
219
+ message: `Process count ${usage.processCount} approaching limit ${this.config.maxProcesses}`,
220
+ containerId,
221
+ timestamp: new Date(),
222
+ details: { usage }
223
+ });
224
+ }
225
+ // Log violations
226
+ for (const violation of violations) {
227
+ this.recordViolation(violation);
228
+ }
229
+ }
230
+ /**
231
+ * Handle execution timeout
232
+ */
233
+ async handleExecutionTimeout(containerId) {
234
+ logger.warn(`Container ${containerId} exceeded maximum execution time, terminating`);
235
+ const violation = {
236
+ type: 'execution',
237
+ severity: 'high',
238
+ message: `Container exceeded maximum execution time of ${this.config.maxExecutionTimeSeconds} seconds`,
239
+ containerId,
240
+ timestamp: new Date()
241
+ };
242
+ this.recordViolation(violation);
243
+ // Force kill the container
244
+ try {
245
+ await this.executeCommand('docker', ['kill', containerId]);
246
+ }
247
+ catch (error) {
248
+ logger.error(`Failed to kill timed-out container ${containerId}:`, error);
249
+ }
250
+ }
251
+ /**
252
+ * Create secure temporary directory for container
253
+ */
254
+ async createSecureTempDir(containerId) {
255
+ const tempDir = join('/tmp', `buildhive-${containerId}`);
256
+ try {
257
+ await fs.mkdir(tempDir, { recursive: true, mode: 0o700 });
258
+ // Set strict permissions
259
+ await fs.chmod(tempDir, 0o700);
260
+ logger.info(`Created secure temp directory: ${tempDir}`);
261
+ return tempDir;
262
+ }
263
+ catch (error) {
264
+ logger.error(`Failed to create secure temp directory:`, error);
265
+ throw error;
266
+ }
267
+ }
268
+ /**
269
+ * Clean up secure temporary directory
270
+ */
271
+ async cleanupSecureTempDir(tempDir) {
272
+ try {
273
+ await fs.rm(tempDir, { recursive: true, force: true });
274
+ logger.info(`Cleaned up temp directory: ${tempDir}`);
275
+ }
276
+ catch (error) {
277
+ logger.error(`Failed to cleanup temp directory ${tempDir}:`, error);
278
+ }
279
+ }
280
+ /**
281
+ * Validate Docker image security
282
+ */
283
+ async validateImageSecurity(image) {
284
+ const violations = [];
285
+ try {
286
+ // Check if image is from trusted registry
287
+ if (!this.isTrustedImage(image)) {
288
+ violations.push({
289
+ type: 'filesystem',
290
+ severity: 'medium',
291
+ message: `Image ${image} is not from a trusted registry`,
292
+ containerId: 'image-validation',
293
+ timestamp: new Date(),
294
+ details: { image }
295
+ });
296
+ }
297
+ // Inspect image for security issues
298
+ const inspectResult = await this.executeCommand('docker', ['inspect', image]);
299
+ if (inspectResult.exitCode === 0) {
300
+ const imageInfo = JSON.parse(inspectResult.output)[0];
301
+ // Check for root user
302
+ if (imageInfo.Config?.User === 'root' || !imageInfo.Config?.User) {
303
+ violations.push({
304
+ type: 'capability',
305
+ severity: 'medium',
306
+ message: `Image ${image} runs as root user`,
307
+ containerId: 'image-validation',
308
+ timestamp: new Date(),
309
+ details: { image }
310
+ });
311
+ }
312
+ }
313
+ }
314
+ catch (error) {
315
+ logger.error(`Failed to validate image security for ${image}:`, error);
316
+ }
317
+ return violations;
318
+ }
319
+ /**
320
+ * Get security violations
321
+ */
322
+ getViolations() {
323
+ return [...this.violations];
324
+ }
325
+ /**
326
+ * Clear security violations
327
+ */
328
+ clearViolations() {
329
+ this.violations = [];
330
+ }
331
+ /**
332
+ * Record a security violation
333
+ */
334
+ recordViolation(violation) {
335
+ this.violations.push(violation);
336
+ if (this.config.logSecurityEvents) {
337
+ logger.warn(`Security violation [${violation.severity}]: ${violation.message}`, {
338
+ containerId: violation.containerId,
339
+ type: violation.type,
340
+ details: violation.details
341
+ });
342
+ }
343
+ // Keep only last 1000 violations to prevent memory issues
344
+ if (this.violations.length > 1000) {
345
+ this.violations = this.violations.slice(-1000);
346
+ }
347
+ }
348
+ /**
349
+ * Check if a volume mount is unsafe
350
+ */
351
+ isUnsafeMount(hostPath) {
352
+ const unsafePaths = [
353
+ '/',
354
+ '/etc',
355
+ '/usr',
356
+ '/bin',
357
+ '/sbin',
358
+ '/boot',
359
+ '/sys',
360
+ '/proc',
361
+ '/dev',
362
+ '/var/run/docker.sock',
363
+ '/home',
364
+ '/root'
365
+ ];
366
+ const resolvedPath = resolve(hostPath);
367
+ return unsafePaths.some(unsafePath => resolvedPath === unsafePath || resolvedPath.startsWith(unsafePath + '/'));
368
+ }
369
+ /**
370
+ * Check if image is from trusted registry
371
+ */
372
+ isTrustedImage(image) {
373
+ const trustedRegistries = [
374
+ 'docker.io',
375
+ 'gcr.io',
376
+ 'quay.io',
377
+ 'registry.hub.docker.com'
378
+ ];
379
+ // If no registry specified, assume docker.io
380
+ if (!image.includes('/') || !image.includes('.')) {
381
+ return true;
382
+ }
383
+ const registry = image.split('/')[0];
384
+ return trustedRegistries.includes(registry);
385
+ }
386
+ /**
387
+ * Parse memory limit string to MB
388
+ */
389
+ parseMemoryLimit(limit) {
390
+ const match = limit.match(/^(\d+)([kmg]?)$/i);
391
+ if (!match)
392
+ return 0;
393
+ const value = parseInt(match[1]);
394
+ const unit = match[2]?.toLowerCase() || '';
395
+ switch (unit) {
396
+ case 'k': return value / 1024;
397
+ case 'm': return value;
398
+ case 'g': return value * 1024;
399
+ default: return value / (1024 * 1024); // bytes to MB
400
+ }
401
+ }
402
+ /**
403
+ * Parse resource stats output
404
+ */
405
+ parseResourceStats(output) {
406
+ // This is a simplified parser - in production, you'd want more robust parsing
407
+ const lines = output.trim().split('\n');
408
+ const dataLine = lines[1] || '';
409
+ const parts = dataLine.split('\t');
410
+ return {
411
+ memoryUsageMB: this.parseMemoryUsage(parts[0] || '0'),
412
+ cpuUsagePercent: parseFloat(parts[1]?.replace('%', '') || '0'),
413
+ processCount: parseInt(parts[2] || '0'),
414
+ networkBytesIn: 0, // Would need more complex parsing
415
+ networkBytesOut: 0,
416
+ diskUsageMB: 0 // Would need additional docker command
417
+ };
418
+ }
419
+ /**
420
+ * Parse memory usage string
421
+ */
422
+ parseMemoryUsage(usage) {
423
+ const match = usage.match(/^([\d.]+)([KMGT]?i?B)/);
424
+ if (!match)
425
+ return 0;
426
+ const value = parseFloat(match[1]);
427
+ const unit = match[2];
428
+ switch (unit) {
429
+ case 'KiB':
430
+ case 'KB': return value / 1024;
431
+ case 'MiB':
432
+ case 'MB': return value;
433
+ case 'GiB':
434
+ case 'GB': return value * 1024;
435
+ case 'TiB':
436
+ case 'TB': return value * 1024 * 1024;
437
+ default: return value / (1024 * 1024); // bytes to MB
438
+ }
439
+ }
440
+ /**
441
+ * Execute a system command
442
+ */
443
+ async executeCommand(command, args) {
444
+ return new Promise((resolve) => {
445
+ const process = spawn(command, args, { stdio: ['pipe', 'pipe', 'pipe'] });
446
+ let output = '';
447
+ let error = '';
448
+ process.stdout.on('data', (data) => output += data.toString());
449
+ process.stderr.on('data', (data) => error += data.toString());
450
+ process.on('close', (code) => {
451
+ resolve({
452
+ exitCode: code || 0,
453
+ output: output.trim(),
454
+ error: error.trim()
455
+ });
456
+ });
457
+ });
458
+ }
459
+ /**
460
+ * Cleanup all monitoring
461
+ */
462
+ cleanup() {
463
+ for (const [containerId, monitor] of this.resourceMonitors) {
464
+ clearInterval(monitor);
465
+ }
466
+ this.resourceMonitors.clear();
467
+ logger.info('Security manager cleanup completed');
468
+ }
469
+ }
470
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Artifact Uploader - MVP.4.2.4
3
+ *
4
+ * Handles artifact upload to storage backends (local or S3).
5
+ *
6
+ * Features:
7
+ * - Local file storage with configurable base path
8
+ * - S3 upload with multipart support for large files (>50MB)
9
+ * - S3-compatible storage support (MinIO, Cloudflare R2, etc.)
10
+ * - Presigned download URL generation
11
+ * - Retry logic with exponential backoff
12
+ * - Proper error handling and logging
13
+ * - Cleanup of temporary files after upload
14
+ * - Batch S3 object deletion for retention cleanup
15
+ *
16
+ * @module storage/artifactUploader
17
+ */
18
+ import type { StorageConfig } from '../config/types.js';
19
+ export interface UploadResult {
20
+ url: string;
21
+ size: number;
22
+ uploadedAt: Date;
23
+ }
24
+ export interface UploadOptions {
25
+ /**
26
+ * Maximum number of retry attempts on failure
27
+ */
28
+ maxRetries?: number;
29
+ /**
30
+ * Base delay in milliseconds for exponential backoff
31
+ */
32
+ retryDelayMs?: number;
33
+ /**
34
+ * Whether to delete the source file after successful upload
35
+ */
36
+ deleteAfterUpload?: boolean;
37
+ }
38
+ export declare class ArtifactUploader {
39
+ private config;
40
+ private s3Client;
41
+ constructor(config: StorageConfig);
42
+ /**
43
+ * Lazily create and cache an S3Client instance based on the current config.
44
+ */
45
+ private getS3Client;
46
+ /**
47
+ * Build the S3 object key from an artifact name, applying the configured path prefix.
48
+ */
49
+ private buildS3Key;
50
+ /**
51
+ * Build a public-style S3 URL for an object.
52
+ */
53
+ private buildS3Url;
54
+ /**
55
+ * Upload an artifact to the configured storage backend
56
+ *
57
+ * @param sourcePath - Absolute path to the artifact file
58
+ * @param artifactName - Name/path for the artifact in storage
59
+ * @param options - Upload options
60
+ * @returns Upload result with URL and metadata
61
+ */
62
+ uploadArtifact(sourcePath: string, artifactName: string, options?: UploadOptions): Promise<UploadResult>;
63
+ /**
64
+ * Upload artifact to local storage
65
+ *
66
+ * @param sourcePath - Source file path
67
+ * @param artifactName - Target artifact name
68
+ * @param maxRetries - Maximum retry attempts
69
+ * @param retryDelayMs - Retry delay in milliseconds
70
+ * @returns Upload result
71
+ */
72
+ private uploadToLocal;
73
+ /**
74
+ * Upload artifact to S3
75
+ *
76
+ * Uses PutObjectCommand for files <= 50 MB and multipart Upload for larger files.
77
+ * Supports S3-compatible storage (MinIO, Cloudflare R2) via custom endpoint.
78
+ *
79
+ * @param sourcePath - Source file path
80
+ * @param artifactName - Target artifact name
81
+ * @param maxRetries - Maximum retry attempts
82
+ * @param retryDelayMs - Retry delay in milliseconds
83
+ * @returns Upload result
84
+ */
85
+ private uploadToS3;
86
+ /**
87
+ * Generate a presigned download URL for an artifact in S3.
88
+ *
89
+ * @param artifactName - The artifact name/path in storage
90
+ * @param expiresInSeconds - URL expiration time (default: 3600 = 1 hour)
91
+ * @returns Presigned download URL
92
+ */
93
+ getSignedDownloadUrl(artifactName: string, expiresInSeconds?: number): Promise<string>;
94
+ /**
95
+ * Delete S3 objects in batch using DeleteObjectsCommand.
96
+ *
97
+ * @param keys - Array of S3 object keys to delete
98
+ * @returns Number of objects successfully deleted
99
+ */
100
+ deleteS3Objects(keys: string[]): Promise<number>;
101
+ /**
102
+ * Delete a file from the filesystem
103
+ *
104
+ * @param filePath - Path to the file to delete
105
+ */
106
+ private deleteFile;
107
+ /**
108
+ * Retry an operation with exponential backoff
109
+ *
110
+ * @param operation - Async operation to retry
111
+ * @param maxRetries - Maximum number of retry attempts
112
+ * @param baseDelayMs - Base delay for exponential backoff
113
+ * @param operationName - Name for logging
114
+ */
115
+ private retryOperation;
116
+ /**
117
+ * Clean up old artifacts based on retention policy
118
+ *
119
+ * @param basePath - Base path to scan for old artifacts
120
+ * @returns Number of files deleted
121
+ */
122
+ cleanupOldArtifacts(basePath?: string): Promise<number>;
123
+ /**
124
+ * Recursively find files older than the cutoff time
125
+ *
126
+ * @param dirPath - Directory to scan
127
+ * @param cutoffTime - Cutoff timestamp (files older than this will be included)
128
+ * @returns Array of file paths
129
+ */
130
+ private findOldFiles;
131
+ /**
132
+ * Get storage statistics
133
+ *
134
+ * @returns Storage usage statistics
135
+ */
136
+ getStorageStats(): Promise<{
137
+ type: 'local' | 's3';
138
+ totalFiles: number;
139
+ totalSizeBytes: number;
140
+ oldestFileDate?: Date;
141
+ newestFileDate?: Date;
142
+ }>;
143
+ /**
144
+ * Recursively find all files in a directory
145
+ *
146
+ * @param dirPath - Directory to scan
147
+ * @returns Array of file paths
148
+ */
149
+ private findAllFiles;
150
+ /**
151
+ * Retrieve storage statistics from S3 using ListObjectsV2 with pagination.
152
+ */
153
+ private getS3StorageStats;
154
+ }
155
+ //# sourceMappingURL=artifactUploader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifactUploader.d.ts","sourceRoot":"","sources":["../../src/storage/artifactUploader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAY,MAAM,oBAAoB,CAAC;AAclE,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAKD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,QAAQ,CAAyB;gBAE7B,MAAM,EAAE,aAAa;IASjC;;OAEG;IACH,OAAO,CAAC,WAAW;IAgCnB;;OAEG;IACH,OAAO,CAAC,UAAU;IAQlB;;OAEG;IACH,OAAO,CAAC,UAAU;IAUlB;;;;;;;OAOG;IACG,cAAc,CAClB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC;IA+CxB;;;;;;;;OAQG;YACW,aAAa;IAkC3B;;;;;;;;;;;OAWG;YACW,UAAU;IAwFxB;;;;;;OAMG;IACG,oBAAoB,CACxB,YAAY,EAAE,MAAM,EACpB,gBAAgB,GAAE,MAAa,GAC9B,OAAO,CAAC,MAAM,CAAC;IAgClB;;;;;OAKG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAwDtD;;;;OAIG;YACW,UAAU;IAaxB;;;;;;;OAOG;YACW,cAAc;IAiC5B;;;;;OAKG;IACG,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoC7D;;;;;;OAMG;YACW,YAAY;IA+B1B;;;;OAIG;IACG,eAAe,IAAI,OAAO,CAAC;QAC/B,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,CAAC,EAAE,IAAI,CAAC;QACtB,cAAc,CAAC,EAAE,IAAI,CAAC;KACvB,CAAC;IAkCF;;;;;OAKG;YACW,YAAY;IA4B1B;;OAEG;YACW,iBAAiB;CA+DhC"}