agentshield-sdk 7.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 (84) hide show
  1. package/CHANGELOG.md +191 -0
  2. package/LICENSE +21 -0
  3. package/README.md +975 -0
  4. package/bin/agent-shield.js +680 -0
  5. package/package.json +118 -0
  6. package/src/adaptive.js +330 -0
  7. package/src/agent-protocol.js +998 -0
  8. package/src/alert-tuning.js +480 -0
  9. package/src/allowlist.js +603 -0
  10. package/src/audit-immutable.js +914 -0
  11. package/src/audit-streaming.js +469 -0
  12. package/src/badges.js +196 -0
  13. package/src/behavior-profiling.js +289 -0
  14. package/src/benchmark-harness.js +804 -0
  15. package/src/canary.js +271 -0
  16. package/src/certification.js +563 -0
  17. package/src/circuit-breaker.js +321 -0
  18. package/src/compliance.js +617 -0
  19. package/src/confidence-tuning.js +324 -0
  20. package/src/confused-deputy.js +624 -0
  21. package/src/context-scoring.js +360 -0
  22. package/src/conversation.js +494 -0
  23. package/src/cost-optimizer.js +1024 -0
  24. package/src/ctf.js +462 -0
  25. package/src/detector-core.js +1999 -0
  26. package/src/distributed.js +359 -0
  27. package/src/document-scanner.js +795 -0
  28. package/src/embedding.js +307 -0
  29. package/src/encoding.js +429 -0
  30. package/src/enterprise.js +405 -0
  31. package/src/errors.js +100 -0
  32. package/src/eu-ai-act.js +523 -0
  33. package/src/fuzzer.js +764 -0
  34. package/src/honeypot.js +328 -0
  35. package/src/i18n-patterns.js +523 -0
  36. package/src/index.js +430 -0
  37. package/src/integrations.js +528 -0
  38. package/src/llm-redteam.js +670 -0
  39. package/src/main.js +741 -0
  40. package/src/main.mjs +38 -0
  41. package/src/mcp-bridge.js +542 -0
  42. package/src/mcp-certification.js +846 -0
  43. package/src/mcp-sdk-integration.js +355 -0
  44. package/src/mcp-security-runtime.js +741 -0
  45. package/src/mcp-server.js +740 -0
  46. package/src/middleware.js +208 -0
  47. package/src/model-finetuning.js +884 -0
  48. package/src/model-fingerprint.js +1042 -0
  49. package/src/multi-agent-trust.js +453 -0
  50. package/src/multi-agent.js +404 -0
  51. package/src/multimodal.js +296 -0
  52. package/src/nist-mapping.js +505 -0
  53. package/src/observability.js +330 -0
  54. package/src/openclaw.js +450 -0
  55. package/src/otel.js +544 -0
  56. package/src/owasp-2025.js +483 -0
  57. package/src/pii.js +390 -0
  58. package/src/plugin-marketplace.js +628 -0
  59. package/src/plugin-system.js +349 -0
  60. package/src/policy-dsl.js +775 -0
  61. package/src/policy-extended.js +635 -0
  62. package/src/policy.js +443 -0
  63. package/src/presets.js +409 -0
  64. package/src/production.js +557 -0
  65. package/src/prompt-leakage.js +321 -0
  66. package/src/rag-vulnerability.js +579 -0
  67. package/src/redteam.js +475 -0
  68. package/src/response-handler.js +429 -0
  69. package/src/scanners.js +357 -0
  70. package/src/self-healing.js +363 -0
  71. package/src/semantic.js +339 -0
  72. package/src/shield-score.js +250 -0
  73. package/src/sso-saml.js +897 -0
  74. package/src/stream-scanner.js +806 -0
  75. package/src/testing.js +505 -0
  76. package/src/threat-encyclopedia.js +629 -0
  77. package/src/threat-intel-network.js +1017 -0
  78. package/src/token-analysis.js +467 -0
  79. package/src/tool-guard.js +412 -0
  80. package/src/tool-output-validator.js +354 -0
  81. package/src/utils.js +83 -0
  82. package/src/watermark.js +235 -0
  83. package/src/worker-scanner.js +601 -0
  84. package/types/index.d.ts +2088 -0
@@ -0,0 +1,505 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Agent Shield — NIST AI RMF Mapping & AI-BOM Generator
5
+ *
6
+ * Maps Agent Shield capabilities to the NIST AI Risk Management Framework
7
+ * (2025 updates). Generates AI Bill of Materials (AI-BOM) for compliance.
8
+ *
9
+ * All processing runs locally — no data ever leaves your environment.
10
+ */
11
+
12
+ // =========================================================================
13
+ // NIST AI RMF 2025 Framework
14
+ // =========================================================================
15
+
16
+ /**
17
+ * NIST AI RMF functions, categories, and subcategories with Agent Shield mapping.
18
+ * @type {object}
19
+ */
20
+ const NIST_AI_RMF_2025 = {
21
+ version: '1.0-2025',
22
+ functions: {
23
+ GOVERN: {
24
+ name: 'Govern',
25
+ description: 'Establish and maintain AI risk management culture, accountability, and policies.',
26
+ categories: [
27
+ { id: 'GOVERN-1', name: 'AI Risk Culture', description: 'Foster organizational culture for AI risk management', agentShieldMapping: ['compliance.js:ComplianceReporter'], automatable: false },
28
+ { id: 'GOVERN-2', name: 'Accountability', description: 'Establish accountability structures for AI systems', agentShieldMapping: ['enterprise.js:RoleBasedPolicy', 'multi-agent-trust.js:CapabilityToken'], automatable: true },
29
+ { id: 'GOVERN-3', name: 'Workforce', description: 'AI risk management workforce competencies', agentShieldMapping: [], automatable: false },
30
+ { id: 'GOVERN-4', name: 'Stakeholder Engagement', description: 'Engage stakeholders in AI risk decisions', agentShieldMapping: [], automatable: false },
31
+ { id: 'GOVERN-5', name: 'Risk Assessment', description: 'Continuous AI risk assessment processes', agentShieldMapping: ['shield-score.js:ShieldScoreCalculator', 'owasp-2025.js:OWASPCoverageMatrix'], automatable: true },
32
+ { id: 'GOVERN-6', name: 'Policies & Procedures', description: 'AI governance policies and procedures', agentShieldMapping: ['policy.js:loadPolicy', 'policy-dsl.js:PolicyDSL'], automatable: true }
33
+ ]
34
+ },
35
+ MAP: {
36
+ name: 'Map',
37
+ description: 'Identify and document AI system context, requirements, and risks.',
38
+ categories: [
39
+ { id: 'MAP-1', name: 'Context', description: 'Map AI system intended purpose and context of use', agentShieldMapping: ['compliance.js:ComplianceReporter'], automatable: false },
40
+ { id: 'MAP-2', name: 'Requirements', description: 'Document AI system requirements and constraints', agentShieldMapping: ['owasp-2025.js:OWASPCoverageMatrix'], automatable: true },
41
+ { id: 'MAP-3', name: 'Risks', description: 'Identify and characterize AI-specific risks', agentShieldMapping: ['threat-encyclopedia.js:ThreatEncyclopedia', 'redteam.js:AttackSimulator'], automatable: true },
42
+ { id: 'MAP-4', name: 'Benefits', description: 'Document intended benefits relative to risks', agentShieldMapping: [], automatable: false },
43
+ { id: 'MAP-5', name: 'Documentation', description: 'Maintain AI system documentation', agentShieldMapping: ['compliance.js:AuditTrail', 'audit-immutable.js:ImmutableAuditLog'], automatable: true }
44
+ ]
45
+ },
46
+ MEASURE: {
47
+ name: 'Measure',
48
+ description: 'Assess, analyze, and monitor AI risks using quantitative and qualitative methods.',
49
+ categories: [
50
+ { id: 'MEASURE-1', name: 'Metrics', description: 'Define and track AI risk metrics', agentShieldMapping: ['shield-score.js:ShieldScoreCalculator', 'benchmark-harness.js:BenchmarkMetrics'], automatable: true },
51
+ { id: 'MEASURE-2', name: 'Testing', description: 'Test AI systems for safety, security, and fairness', agentShieldMapping: ['redteam.js:AttackSimulator', 'fuzzer.js:FuzzingHarness', 'testing.js:TestSuiteGenerator'], automatable: true },
52
+ { id: 'MEASURE-3', name: 'Monitoring', description: 'Continuously monitor AI system behavior', agentShieldMapping: ['behavior-profiling.js:BehaviorProfile', 'observability.js:MetricsCollector', 'circuit-breaker.js:CircuitBreaker'], automatable: true },
53
+ { id: 'MEASURE-4', name: 'Feedback', description: 'Collect and integrate feedback on AI risk', agentShieldMapping: ['allowlist.js:FeedbackLoop', 'self-healing.js:SelfHealingEngine'], automatable: true }
54
+ ]
55
+ },
56
+ MANAGE: {
57
+ name: 'Manage',
58
+ description: 'Allocate resources and implement plans to respond to AI risks.',
59
+ categories: [
60
+ { id: 'MANAGE-1', name: 'Risk Treatment', description: 'Treat identified AI risks with appropriate controls', agentShieldMapping: ['detector-core.js:scanText', 'middleware.js:wrapAgent', 'mcp-bridge.js:MCPBridge'], automatable: true },
61
+ { id: 'MANAGE-2', name: 'Incident Response', description: 'Respond to AI-related security incidents', agentShieldMapping: ['compliance.js:IncidentPlaybook', 'circuit-breaker.js:CircuitBreaker'], automatable: true },
62
+ { id: 'MANAGE-3', name: 'Communication', description: 'Communicate AI risks to stakeholders', agentShieldMapping: ['policy.js:WebhookAlert', 'audit-streaming.js:AuditStreamManager'], automatable: true },
63
+ { id: 'MANAGE-4', name: 'Improvement', description: 'Continuously improve AI risk management', agentShieldMapping: ['self-healing.js:SelfHealingEngine', 'confidence-tuning.js:ConfidenceTuner'], automatable: true }
64
+ ]
65
+ }
66
+ }
67
+ };
68
+
69
+ /**
70
+ * NIST SP 800-53 controls relevant to AI systems.
71
+ * @type {Array<object>}
72
+ */
73
+ const SP800_53_AI_CONTROLS = [
74
+ { id: 'AC-3', family: 'Access Control', name: 'Access Enforcement', description: 'Enforce approved authorizations for AI system access', agentShieldCoverage: 'enterprise.js:RoleBasedPolicy' },
75
+ { id: 'AU-2', family: 'Audit', name: 'Event Logging', description: 'Log AI system security-relevant events', agentShieldCoverage: 'audit-immutable.js:ImmutableAuditLog' },
76
+ { id: 'AU-6', family: 'Audit', name: 'Audit Review', description: 'Review and analyze AI system audit records', agentShieldCoverage: 'audit-streaming.js:AuditStreamManager' },
77
+ { id: 'CA-7', family: 'Assessment', name: 'Continuous Monitoring', description: 'Continuously monitor AI system security', agentShieldCoverage: 'observability.js:MetricsCollector' },
78
+ { id: 'CM-3', family: 'Configuration', name: 'Configuration Change Control', description: 'Control changes to AI system configuration', agentShieldCoverage: 'policy-dsl.js:PolicyDSL' },
79
+ { id: 'IA-9', family: 'Identification', name: 'Service Identification', description: 'Identify and authenticate AI services', agentShieldCoverage: 'agent-protocol.js:AgentIdentity' },
80
+ { id: 'IR-4', family: 'Incident Response', name: 'Incident Handling', description: 'Handle AI-related security incidents', agentShieldCoverage: 'compliance.js:IncidentPlaybook' },
81
+ { id: 'RA-5', family: 'Risk Assessment', name: 'Vulnerability Monitoring', description: 'Monitor AI system vulnerabilities', agentShieldCoverage: 'shield-score.js:ShieldScoreCalculator' },
82
+ { id: 'SA-11', family: 'Acquisition', name: 'Developer Testing', description: 'Test AI system security controls', agentShieldCoverage: 'testing.js:TestSuiteGenerator' },
83
+ { id: 'SC-7', family: 'System Protection', name: 'Boundary Protection', description: 'Protect AI system communication boundaries', agentShieldCoverage: 'agent-protocol.js:SecureChannel' },
84
+ { id: 'SI-3', family: 'System Integrity', name: 'Malicious Code Protection', description: 'Protect AI systems from malicious inputs', agentShieldCoverage: 'detector-core.js:scanText' },
85
+ { id: 'SI-4', family: 'System Integrity', name: 'System Monitoring', description: 'Monitor AI system for anomalous behavior', agentShieldCoverage: 'behavior-profiling.js:BehaviorProfile' }
86
+ ];
87
+
88
+ // =========================================================================
89
+ // NISTMapper
90
+ // =========================================================================
91
+
92
+ class NISTMapper {
93
+ /**
94
+ * @param {object} [options]
95
+ * @param {string} [options.organizationName='Organization'] - Org name for reports
96
+ * @param {string} [options.systemName='AI System'] - AI system name
97
+ * @param {'low'|'medium'|'high'|'critical'} [options.riskLevel='medium'] - Risk level
98
+ */
99
+ constructor(options = {}) {
100
+ this.organizationName = options.organizationName || 'Organization';
101
+ this.systemName = options.systemName || 'AI System';
102
+ this.riskLevel = options.riskLevel || 'medium';
103
+ }
104
+
105
+ /**
106
+ * Returns which NIST categories Agent Shield covers and how.
107
+ * @returns {object}
108
+ */
109
+ getCoverageMap() {
110
+ const map = {};
111
+ for (const [funcName, func] of Object.entries(NIST_AI_RMF_2025.functions)) {
112
+ map[funcName] = func.categories.map(cat => ({
113
+ id: cat.id,
114
+ name: cat.name,
115
+ covered: cat.agentShieldMapping.length > 0,
116
+ automatable: cat.automatable,
117
+ modules: cat.agentShieldMapping,
118
+ coverageLevel: cat.agentShieldMapping.length > 1 ? 'strong' : cat.agentShieldMapping.length === 1 ? 'basic' : 'none'
119
+ }));
120
+ }
121
+ return map;
122
+ }
123
+
124
+ /**
125
+ * Returns percentage of NIST controls addressed.
126
+ * @returns {{ percentage: number, covered: number, total: number, byFunction: object }}
127
+ */
128
+ getCoverageScore() {
129
+ const byFunction = {};
130
+ let covered = 0;
131
+ let total = 0;
132
+
133
+ for (const [funcName, func] of Object.entries(NIST_AI_RMF_2025.functions)) {
134
+ const funcCovered = func.categories.filter(c => c.agentShieldMapping.length > 0).length;
135
+ const funcTotal = func.categories.length;
136
+ byFunction[funcName] = { covered: funcCovered, total: funcTotal, percentage: Math.round((funcCovered / funcTotal) * 100) };
137
+ covered += funcCovered;
138
+ total += funcTotal;
139
+ }
140
+
141
+ return { percentage: Math.round((covered / total) * 100), covered, total, byFunction };
142
+ }
143
+
144
+ /**
145
+ * Returns uncovered or partially covered areas.
146
+ * @returns {Array<object>}
147
+ */
148
+ getGaps() {
149
+ const gaps = [];
150
+ for (const [funcName, func] of Object.entries(NIST_AI_RMF_2025.functions)) {
151
+ for (const cat of func.categories) {
152
+ if (cat.agentShieldMapping.length === 0) {
153
+ gaps.push({ function: funcName, id: cat.id, name: cat.name, description: cat.description, automatable: cat.automatable });
154
+ }
155
+ }
156
+ }
157
+ return gaps;
158
+ }
159
+
160
+ /**
161
+ * Generates a NIST AI RMF profile document.
162
+ * @param {string} [systemDescription=''] - Description of the AI system
163
+ * @returns {object}
164
+ */
165
+ generateProfile(systemDescription = '') {
166
+ return {
167
+ framework: 'NIST AI RMF',
168
+ version: NIST_AI_RMF_2025.version,
169
+ generatedAt: new Date().toISOString(),
170
+ organization: this.organizationName,
171
+ system: { name: this.systemName, description: systemDescription, riskLevel: this.riskLevel },
172
+ coverage: this.getCoverageScore(),
173
+ coverageMap: this.getCoverageMap(),
174
+ gaps: this.getGaps(),
175
+ sp800_53_mapping: SP800_53_AI_CONTROLS.map(c => ({ ...c, covered: !!c.agentShieldCoverage }))
176
+ };
177
+ }
178
+
179
+ /**
180
+ * Generates a formatted report.
181
+ * @param {'text'|'json'|'markdown'} [format='text']
182
+ * @returns {string}
183
+ */
184
+ generateReport(format = 'text') {
185
+ const profile = this.generateProfile();
186
+
187
+ if (format === 'json') return JSON.stringify(profile, null, 2);
188
+
189
+ if (format === 'markdown') {
190
+ const lines = [
191
+ '# NIST AI RMF Coverage Report',
192
+ '',
193
+ `**Organization:** ${this.organizationName}`,
194
+ `**System:** ${this.systemName}`,
195
+ `**Risk Level:** ${this.riskLevel}`,
196
+ `**Coverage:** ${profile.coverage.percentage}%`,
197
+ ''
198
+ ];
199
+
200
+ for (const [funcName, func] of Object.entries(NIST_AI_RMF_2025.functions)) {
201
+ const funcScore = profile.coverage.byFunction[funcName];
202
+ lines.push(`## ${func.name} (${funcScore.covered}/${funcScore.total})`);
203
+ lines.push('');
204
+ for (const cat of func.categories) {
205
+ const icon = cat.agentShieldMapping.length > 0 ? 'x' : ' ';
206
+ lines.push(`- [${icon}] **${cat.id}** ${cat.name}: ${cat.description}`);
207
+ }
208
+ lines.push('');
209
+ }
210
+ return lines.join('\n');
211
+ }
212
+
213
+ // text format
214
+ const score = profile.coverage;
215
+ const lines = [
216
+ `=== NIST AI RMF Coverage Report ===`,
217
+ `Organization: ${this.organizationName}`,
218
+ `System: ${this.systemName} | Risk: ${this.riskLevel}`,
219
+ `Coverage: ${score.percentage}% (${score.covered}/${score.total})`,
220
+ ''
221
+ ];
222
+ for (const [funcName, func] of Object.entries(NIST_AI_RMF_2025.functions)) {
223
+ const fs = score.byFunction[funcName];
224
+ lines.push(`${func.name}: ${fs.percentage}% (${fs.covered}/${fs.total})`);
225
+ for (const cat of func.categories) {
226
+ const icon = cat.agentShieldMapping.length > 0 ? '●' : '○';
227
+ lines.push(` ${icon} ${cat.id} ${cat.name}`);
228
+ }
229
+ }
230
+ return lines.join('\n');
231
+ }
232
+ }
233
+
234
+ // =========================================================================
235
+ // AIBOMGenerator — AI Bill of Materials
236
+ // =========================================================================
237
+
238
+ class AIBOMGenerator {
239
+ /**
240
+ * @param {object} [options]
241
+ * @param {'spdx'|'cyclonedx'|'custom'} [options.format='custom'] - Output format
242
+ * @param {string} [options.organizationName] - Organization name
243
+ * @param {string} [options.systemName] - System name
244
+ */
245
+ constructor(options = {}) {
246
+ this.format = options.format || 'custom';
247
+ this.organizationName = options.organizationName || 'Organization';
248
+ this.systemName = options.systemName || 'AI System';
249
+ this.components = [];
250
+ this.models = [];
251
+ this.datasets = [];
252
+ this.services = [];
253
+ }
254
+
255
+ /**
256
+ * Adds a generic component.
257
+ * @param {object} component - { name, version, type, supplier, license, hash }
258
+ */
259
+ addComponent(component) {
260
+ this.components.push({ ...component, addedAt: new Date().toISOString() });
261
+ }
262
+
263
+ /**
264
+ * Adds an AI model.
265
+ * @param {object} model - { name, provider, version, type, parameters, trainingData, license }
266
+ */
267
+ addModel(model) {
268
+ this.models.push({ ...model, addedAt: new Date().toISOString() });
269
+ }
270
+
271
+ /**
272
+ * Adds a dataset.
273
+ * @param {object} dataset - { name, source, version, format, size, privacyLevel }
274
+ */
275
+ addDataset(dataset) {
276
+ this.datasets.push({ ...dataset, addedAt: new Date().toISOString() });
277
+ }
278
+
279
+ /**
280
+ * Adds an external service.
281
+ * @param {object} service - { name, endpoint, provider, version, sla }
282
+ */
283
+ addService(service) {
284
+ this.services.push({ ...service, addedAt: new Date().toISOString() });
285
+ }
286
+
287
+ /**
288
+ * Generates the AI-BOM.
289
+ * @returns {object}
290
+ */
291
+ generate() {
292
+ if (this.format === 'spdx') return this.toSPDX();
293
+ if (this.format === 'cyclonedx') return this.toCycloneDX();
294
+ return this.toJSON();
295
+ }
296
+
297
+ /**
298
+ * Validates completeness of the BOM.
299
+ * @returns {{ valid: boolean, warnings: Array }}
300
+ */
301
+ validate() {
302
+ const warnings = [];
303
+ if (this.models.length === 0) warnings.push('No AI models documented');
304
+ if (this.components.length === 0 && this.services.length === 0) warnings.push('No components or services documented');
305
+ for (const m of this.models) {
306
+ if (!m.version) warnings.push(`Model "${m.name}" missing version`);
307
+ if (!m.license) warnings.push(`Model "${m.name}" missing license`);
308
+ }
309
+ for (const d of this.datasets) {
310
+ if (!d.privacyLevel) warnings.push(`Dataset "${d.name}" missing privacy level`);
311
+ }
312
+ return { valid: warnings.length === 0, warnings };
313
+ }
314
+
315
+ /**
316
+ * Custom JSON format.
317
+ * @returns {object}
318
+ */
319
+ toJSON() {
320
+ return {
321
+ bomFormat: 'AgentShield-AI-BOM',
322
+ specVersion: '1.0',
323
+ generatedAt: new Date().toISOString(),
324
+ system: { name: this.systemName, organization: this.organizationName },
325
+ models: this.models,
326
+ datasets: this.datasets,
327
+ components: this.components,
328
+ services: this.services,
329
+ summary: { totalModels: this.models.length, totalDatasets: this.datasets.length, totalComponents: this.components.length, totalServices: this.services.length }
330
+ };
331
+ }
332
+
333
+ /**
334
+ * SPDX-compatible format.
335
+ * @returns {object}
336
+ */
337
+ toSPDX() {
338
+ return {
339
+ spdxVersion: 'SPDX-2.3',
340
+ dataLicense: 'CC0-1.0',
341
+ SPDXID: 'SPDXRef-DOCUMENT',
342
+ name: `AI-BOM-${this.systemName}`,
343
+ documentNamespace: `https://spdx.org/spdxdocs/ai-bom-${Date.now()}`,
344
+ creationInfo: { created: new Date().toISOString(), creators: [`Organization: ${this.organizationName}`, 'Tool: AgentShield'] },
345
+ packages: [
346
+ ...this.models.map((m, i) => ({
347
+ SPDXID: `SPDXRef-Model-${i}`,
348
+ name: m.name,
349
+ versionInfo: m.version || 'unknown',
350
+ supplier: m.provider || 'unknown',
351
+ downloadLocation: 'NOASSERTION',
352
+ licenseConcluded: m.license || 'NOASSERTION',
353
+ primaryPackagePurpose: 'AI_MODEL'
354
+ })),
355
+ ...this.components.map((c, i) => ({
356
+ SPDXID: `SPDXRef-Component-${i}`,
357
+ name: c.name,
358
+ versionInfo: c.version || 'unknown',
359
+ supplier: c.supplier || 'unknown',
360
+ downloadLocation: 'NOASSERTION',
361
+ licenseConcluded: c.license || 'NOASSERTION',
362
+ primaryPackagePurpose: 'LIBRARY'
363
+ }))
364
+ ]
365
+ };
366
+ }
367
+
368
+ /**
369
+ * CycloneDX-compatible format.
370
+ * @returns {object}
371
+ */
372
+ toCycloneDX() {
373
+ return {
374
+ bomFormat: 'CycloneDX',
375
+ specVersion: '1.5',
376
+ version: 1,
377
+ metadata: {
378
+ timestamp: new Date().toISOString(),
379
+ tools: [{ vendor: 'AgentShield', name: 'AI-BOM Generator', version: '1.0' }],
380
+ component: { type: 'application', name: this.systemName, version: '1.0' }
381
+ },
382
+ components: [
383
+ ...this.models.map(m => ({
384
+ type: 'machine-learning-model',
385
+ name: m.name,
386
+ version: m.version || 'unknown',
387
+ supplier: { name: m.provider || 'unknown' },
388
+ licenses: m.license ? [{ license: { id: m.license } }] : [],
389
+ properties: [
390
+ { name: 'ai:type', value: m.type || 'unknown' },
391
+ { name: 'ai:parameters', value: String(m.parameters || 'unknown') }
392
+ ]
393
+ })),
394
+ ...this.components.map(c => ({
395
+ type: 'library',
396
+ name: c.name,
397
+ version: c.version || 'unknown',
398
+ supplier: { name: c.supplier || 'unknown' },
399
+ hashes: c.hash ? [{ alg: 'SHA-256', content: c.hash }] : []
400
+ }))
401
+ ]
402
+ };
403
+ }
404
+ }
405
+
406
+ // =========================================================================
407
+ // ComplianceChecker
408
+ // =========================================================================
409
+
410
+ class ComplianceChecker {
411
+ /**
412
+ * @param {NISTMapper} nistMapper
413
+ */
414
+ constructor(nistMapper) {
415
+ this.mapper = nistMapper;
416
+ }
417
+
418
+ /**
419
+ * Checks current state against a NIST profile.
420
+ * @param {object} profile - Generated profile
421
+ * @param {object} currentState - Current system state
422
+ * @returns {{ compliant: boolean, gaps: Array, score: number }}
423
+ */
424
+ checkAgainstProfile(profile, currentState = {}) {
425
+ const gaps = [];
426
+ const activeModules = currentState.activeModules || [];
427
+
428
+ for (const [funcName, categories] of Object.entries(profile.coverageMap)) {
429
+ for (const cat of categories) {
430
+ if (cat.covered && cat.modules.length > 0) {
431
+ const moduleName = cat.modules[0].split(':')[0].replace('.js', '');
432
+ if (!activeModules.includes(moduleName)) {
433
+ gaps.push({ function: funcName, category: cat.id, name: cat.name, reason: 'Module available but not active' });
434
+ }
435
+ }
436
+ }
437
+ }
438
+
439
+ const score = profile.coverage.percentage;
440
+ return { compliant: gaps.length === 0 && score >= 80, gaps, score };
441
+ }
442
+
443
+ /**
444
+ * Generates a prioritized action plan.
445
+ * @returns {Array<object>}
446
+ */
447
+ generateActionPlan() {
448
+ const gaps = this.mapper.getGaps();
449
+ return gaps.map((gap, i) => ({
450
+ priority: i + 1,
451
+ action: `Address ${gap.id} — ${gap.name}`,
452
+ description: gap.description,
453
+ automatable: gap.automatable,
454
+ effort: gap.automatable ? 'low' : 'high'
455
+ }));
456
+ }
457
+
458
+ /**
459
+ * Generates an audit artifact.
460
+ * @param {'text'|'json'|'markdown'} [format='json']
461
+ * @returns {string}
462
+ */
463
+ generateAuditArtifact(format = 'json') {
464
+ const profile = this.mapper.generateProfile();
465
+ const actionPlan = this.generateActionPlan();
466
+
467
+ const artifact = {
468
+ type: 'NIST AI RMF Audit Artifact',
469
+ generatedAt: new Date().toISOString(),
470
+ organization: this.mapper.organizationName,
471
+ system: this.mapper.systemName,
472
+ framework: 'NIST AI RMF 1.0 (2025)',
473
+ riskLevel: this.mapper.riskLevel,
474
+ coverageScore: profile.coverage,
475
+ gaps: profile.gaps,
476
+ actionPlan,
477
+ sp800_53: profile.sp800_53_mapping
478
+ };
479
+
480
+ if (format === 'json') return JSON.stringify(artifact, null, 2);
481
+ if (format === 'markdown') {
482
+ return [
483
+ '# NIST AI RMF Audit Artifact',
484
+ `**Date:** ${artifact.generatedAt}`,
485
+ `**Coverage:** ${artifact.coverageScore.percentage}%`,
486
+ '',
487
+ '## Action Plan',
488
+ ...actionPlan.map(a => `${a.priority}. **${a.action}** — ${a.description} (effort: ${a.effort})`)
489
+ ].join('\n');
490
+ }
491
+ return JSON.stringify(artifact, null, 2);
492
+ }
493
+ }
494
+
495
+ // =========================================================================
496
+ // Exports
497
+ // =========================================================================
498
+
499
+ module.exports = {
500
+ NIST_AI_RMF_2025,
501
+ SP800_53_AI_CONTROLS,
502
+ NISTMapper,
503
+ AIBOMGenerator,
504
+ ComplianceChecker
505
+ };