agentmesh-platform 1.0.0a1__py3-none-any.whl

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.
@@ -0,0 +1,447 @@
1
+ """
2
+ Compliance Engine
3
+
4
+ Automated compliance mapping for:
5
+ - EU AI Act
6
+ - SOC 2
7
+ - HIPAA
8
+ - GDPR
9
+
10
+ Every action is mapped to relevant controls automatically.
11
+ """
12
+
13
+ from datetime import datetime
14
+ from typing import Optional, Literal
15
+ from pydantic import BaseModel, Field
16
+ from enum import Enum
17
+
18
+
19
+ class ComplianceFramework(str, Enum):
20
+ """Supported compliance frameworks."""
21
+ EU_AI_ACT = "eu_ai_act"
22
+ SOC2 = "soc2"
23
+ HIPAA = "hipaa"
24
+ GDPR = "gdpr"
25
+
26
+
27
+ class ComplianceControl(BaseModel):
28
+ """A specific compliance control."""
29
+
30
+ control_id: str
31
+ framework: ComplianceFramework
32
+ name: str
33
+ description: str
34
+
35
+ # Categorization
36
+ category: str
37
+ subcategory: Optional[str] = None
38
+
39
+ # Requirements
40
+ requirements: list[str] = Field(default_factory=list)
41
+
42
+ # Evidence required
43
+ evidence_types: list[str] = Field(default_factory=list)
44
+
45
+
46
+ class ComplianceMapping(BaseModel):
47
+ """Mapping of an action to compliance controls."""
48
+
49
+ action_type: str
50
+ controls: list[str] = Field(default_factory=list) # Control IDs
51
+
52
+ # Auto-generated evidence
53
+ evidence_generated: list[str] = Field(default_factory=list)
54
+
55
+ # Manual evidence required
56
+ evidence_required: list[str] = Field(default_factory=list)
57
+
58
+
59
+ class ComplianceViolation(BaseModel):
60
+ """A compliance violation."""
61
+
62
+ violation_id: str
63
+ timestamp: datetime = Field(default_factory=datetime.utcnow)
64
+
65
+ # What happened
66
+ agent_did: str
67
+ action_type: str
68
+
69
+ # Which control was violated
70
+ control_id: str
71
+ framework: ComplianceFramework
72
+
73
+ # Severity
74
+ severity: Literal["critical", "high", "medium", "low"] = "medium"
75
+
76
+ # Details
77
+ description: str
78
+ evidence: dict = Field(default_factory=dict)
79
+
80
+ # Remediation
81
+ remediated: bool = False
82
+ remediated_at: Optional[datetime] = None
83
+ remediation_notes: Optional[str] = None
84
+
85
+
86
+ class ComplianceReport(BaseModel):
87
+ """Compliance audit report."""
88
+
89
+ report_id: str
90
+ generated_at: datetime = Field(default_factory=datetime.utcnow)
91
+
92
+ # Scope
93
+ framework: ComplianceFramework
94
+ period_start: datetime
95
+ period_end: datetime
96
+
97
+ # Organization
98
+ organization_id: Optional[str] = None
99
+ agents_covered: list[str] = Field(default_factory=list)
100
+
101
+ # Summary
102
+ total_controls: int = 0
103
+ controls_met: int = 0
104
+ controls_partial: int = 0
105
+ controls_failed: int = 0
106
+ compliance_score: float = 0.0 # 0-100
107
+
108
+ # Violations
109
+ violations: list[ComplianceViolation] = Field(default_factory=list)
110
+
111
+ # Evidence
112
+ evidence_items: int = 0
113
+
114
+ # Recommendations
115
+ recommendations: list[str] = Field(default_factory=list)
116
+
117
+
118
+ class ComplianceEngine:
119
+ """
120
+ Automated compliance mapping and reporting.
121
+
122
+ Maps every agent action to relevant compliance controls
123
+ and generates audit-ready reports.
124
+ """
125
+
126
+ def __init__(self, frameworks: Optional[list[ComplianceFramework]] = None):
127
+ self.frameworks = frameworks or [ComplianceFramework.SOC2]
128
+ self._controls: dict[str, ComplianceControl] = {}
129
+ self._mappings: dict[str, ComplianceMapping] = {}
130
+ self._violations: list[ComplianceViolation] = []
131
+
132
+ # Load default controls
133
+ self._load_default_controls()
134
+
135
+ def _load_default_controls(self) -> None:
136
+ """Load default compliance controls for enabled frameworks."""
137
+
138
+ # SOC 2 Controls
139
+ if ComplianceFramework.SOC2 in self.frameworks:
140
+ self._add_control(ComplianceControl(
141
+ control_id="SOC2-CC6.1",
142
+ framework=ComplianceFramework.SOC2,
143
+ name="Logical Access Security",
144
+ description="Logical access security software, infrastructure, and architectures have been implemented",
145
+ category="Common Criteria",
146
+ requirements=[
147
+ "Identity verification",
148
+ "Access logging",
149
+ "Credential management",
150
+ ],
151
+ evidence_types=["access_logs", "identity_records"],
152
+ ))
153
+ self._add_control(ComplianceControl(
154
+ control_id="SOC2-CC7.2",
155
+ framework=ComplianceFramework.SOC2,
156
+ name="System Monitoring",
157
+ description="System components are monitored for anomalies",
158
+ category="Common Criteria",
159
+ requirements=[
160
+ "Activity monitoring",
161
+ "Anomaly detection",
162
+ "Alerting",
163
+ ],
164
+ evidence_types=["monitoring_logs", "alerts"],
165
+ ))
166
+
167
+ # HIPAA Controls
168
+ if ComplianceFramework.HIPAA in self.frameworks:
169
+ self._add_control(ComplianceControl(
170
+ control_id="HIPAA-164.312(a)(1)",
171
+ framework=ComplianceFramework.HIPAA,
172
+ name="Access Control",
173
+ description="Implement technical policies and procedures for electronic PHI access",
174
+ category="Technical Safeguards",
175
+ requirements=[
176
+ "Unique user identification",
177
+ "Automatic logoff",
178
+ "Encryption",
179
+ ],
180
+ evidence_types=["access_logs", "encryption_records"],
181
+ ))
182
+ self._add_control(ComplianceControl(
183
+ control_id="HIPAA-164.312(b)",
184
+ framework=ComplianceFramework.HIPAA,
185
+ name="Audit Controls",
186
+ description="Implement hardware, software, and procedural mechanisms for audit trails",
187
+ category="Technical Safeguards",
188
+ requirements=[
189
+ "Audit logging",
190
+ "Log retention",
191
+ "Log review",
192
+ ],
193
+ evidence_types=["audit_logs"],
194
+ ))
195
+
196
+ # EU AI Act Controls
197
+ if ComplianceFramework.EU_AI_ACT in self.frameworks:
198
+ self._add_control(ComplianceControl(
199
+ control_id="EUAI-ART9",
200
+ framework=ComplianceFramework.EU_AI_ACT,
201
+ name="Risk Management System",
202
+ description="High-risk AI systems shall have a risk management system",
203
+ category="High-Risk AI",
204
+ requirements=[
205
+ "Risk identification",
206
+ "Risk mitigation",
207
+ "Continuous monitoring",
208
+ ],
209
+ evidence_types=["risk_assessments", "mitigation_logs"],
210
+ ))
211
+ self._add_control(ComplianceControl(
212
+ control_id="EUAI-ART13",
213
+ framework=ComplianceFramework.EU_AI_ACT,
214
+ name="Transparency",
215
+ description="High-risk AI systems shall be designed to allow appropriate transparency",
216
+ category="High-Risk AI",
217
+ requirements=[
218
+ "Explainability",
219
+ "Documentation",
220
+ "User notification",
221
+ ],
222
+ evidence_types=["decision_logs", "explanations"],
223
+ ))
224
+
225
+ # GDPR Controls
226
+ if ComplianceFramework.GDPR in self.frameworks:
227
+ self._add_control(ComplianceControl(
228
+ control_id="GDPR-ART5",
229
+ framework=ComplianceFramework.GDPR,
230
+ name="Data Processing Principles",
231
+ description="Personal data shall be processed lawfully, fairly and transparently",
232
+ category="Principles",
233
+ requirements=[
234
+ "Lawful basis",
235
+ "Purpose limitation",
236
+ "Data minimization",
237
+ ],
238
+ evidence_types=["processing_records", "consent_logs"],
239
+ ))
240
+ self._add_control(ComplianceControl(
241
+ control_id="GDPR-ART22",
242
+ framework=ComplianceFramework.GDPR,
243
+ name="Automated Decision-Making",
244
+ description="Right not to be subject to solely automated decision-making",
245
+ category="Individual Rights",
246
+ requirements=[
247
+ "Human oversight",
248
+ "Explanation of logic",
249
+ "Right to contest",
250
+ ],
251
+ evidence_types=["decision_logs", "human_review_records"],
252
+ ))
253
+
254
+ # Set up default mappings
255
+ self._setup_default_mappings()
256
+
257
+ def _setup_default_mappings(self) -> None:
258
+ """Set up default action-to-control mappings."""
259
+
260
+ # Agent registration
261
+ self._mappings["agent_registration"] = ComplianceMapping(
262
+ action_type="agent_registration",
263
+ controls=["SOC2-CC6.1", "HIPAA-164.312(a)(1)"],
264
+ evidence_generated=["identity_record", "registration_log"],
265
+ )
266
+
267
+ # Data access
268
+ self._mappings["data_access"] = ComplianceMapping(
269
+ action_type="data_access",
270
+ controls=["SOC2-CC6.1", "HIPAA-164.312(b)", "GDPR-ART5"],
271
+ evidence_generated=["access_log", "data_classification"],
272
+ )
273
+
274
+ # Automated decision
275
+ self._mappings["automated_decision"] = ComplianceMapping(
276
+ action_type="automated_decision",
277
+ controls=["EUAI-ART13", "GDPR-ART22"],
278
+ evidence_generated=["decision_log", "explanation"],
279
+ evidence_required=["human_review"] if ComplianceFramework.GDPR in self.frameworks else [],
280
+ )
281
+
282
+ def _add_control(self, control: ComplianceControl) -> None:
283
+ """Add a control to the registry."""
284
+ self._controls[control.control_id] = control
285
+
286
+ def map_action(self, action_type: str) -> Optional[ComplianceMapping]:
287
+ """Get compliance mapping for an action type."""
288
+ return self._mappings.get(action_type)
289
+
290
+ def check_compliance(
291
+ self,
292
+ agent_did: str,
293
+ action_type: str,
294
+ context: dict,
295
+ ) -> list[ComplianceViolation]:
296
+ """
297
+ Check an action for compliance violations.
298
+
299
+ Returns list of any violations found.
300
+ """
301
+ violations = []
302
+ mapping = self.map_action(action_type)
303
+
304
+ if not mapping:
305
+ return violations
306
+
307
+ for control_id in mapping.controls:
308
+ control = self._controls.get(control_id)
309
+ if not control:
310
+ continue
311
+
312
+ # Check requirements
313
+ violation = self._check_control(agent_did, action_type, control, context)
314
+ if violation:
315
+ violations.append(violation)
316
+ self._violations.append(violation)
317
+
318
+ return violations
319
+
320
+ def _check_control(
321
+ self,
322
+ agent_did: str,
323
+ action_type: str,
324
+ control: ComplianceControl,
325
+ context: dict,
326
+ ) -> Optional[ComplianceViolation]:
327
+ """Check if an action violates a specific control."""
328
+ import uuid
329
+
330
+ # Framework-specific checks
331
+ if control.framework == ComplianceFramework.HIPAA:
332
+ # Check for PHI handling
333
+ if context.get("data_type") == "phi" and not context.get("encrypted"):
334
+ return ComplianceViolation(
335
+ violation_id=f"viol_{uuid.uuid4().hex[:12]}",
336
+ agent_did=agent_did,
337
+ action_type=action_type,
338
+ control_id=control.control_id,
339
+ framework=control.framework,
340
+ severity="high",
341
+ description="PHI data accessed without encryption",
342
+ evidence={"data_type": "phi", "encrypted": False},
343
+ )
344
+
345
+ if control.framework == ComplianceFramework.GDPR:
346
+ # Check for consent
347
+ if context.get("personal_data") and not context.get("consent_verified"):
348
+ return ComplianceViolation(
349
+ violation_id=f"viol_{uuid.uuid4().hex[:12]}",
350
+ agent_did=agent_did,
351
+ action_type=action_type,
352
+ control_id=control.control_id,
353
+ framework=control.framework,
354
+ severity="high",
355
+ description="Personal data processed without verified consent",
356
+ evidence={"personal_data": True, "consent": False},
357
+ )
358
+
359
+ return None
360
+
361
+ def generate_report(
362
+ self,
363
+ framework: ComplianceFramework,
364
+ period_start: datetime,
365
+ period_end: datetime,
366
+ agent_ids: Optional[list[str]] = None,
367
+ ) -> ComplianceReport:
368
+ """Generate a compliance report."""
369
+ import uuid
370
+
371
+ # Filter violations
372
+ violations = [
373
+ v for v in self._violations
374
+ if v.framework == framework
375
+ and period_start <= v.timestamp <= period_end
376
+ and (not agent_ids or v.agent_did in agent_ids)
377
+ ]
378
+
379
+ # Get controls for framework
380
+ framework_controls = [
381
+ c for c in self._controls.values()
382
+ if c.framework == framework
383
+ ]
384
+
385
+ # Calculate compliance score
386
+ violated_controls = set(v.control_id for v in violations)
387
+ total = len(framework_controls)
388
+ failed = len(violated_controls)
389
+ met = total - failed
390
+
391
+ score = (met / total * 100) if total > 0 else 100.0
392
+
393
+ # Generate recommendations
394
+ recommendations = []
395
+ for v in violations:
396
+ if not v.remediated:
397
+ recommendations.append(
398
+ f"Remediate {v.control_id}: {v.description}"
399
+ )
400
+
401
+ return ComplianceReport(
402
+ report_id=f"report_{uuid.uuid4().hex[:12]}",
403
+ framework=framework,
404
+ period_start=period_start,
405
+ period_end=period_end,
406
+ agents_covered=agent_ids or [],
407
+ total_controls=total,
408
+ controls_met=met,
409
+ controls_failed=failed,
410
+ compliance_score=score,
411
+ violations=violations,
412
+ recommendations=recommendations[:10], # Top 10
413
+ )
414
+
415
+ def remediate_violation(
416
+ self,
417
+ violation_id: str,
418
+ notes: str,
419
+ ) -> bool:
420
+ """Mark a violation as remediated."""
421
+ for v in self._violations:
422
+ if v.violation_id == violation_id:
423
+ v.remediated = True
424
+ v.remediated_at = datetime.utcnow()
425
+ v.remediation_notes = notes
426
+ return True
427
+ return False
428
+
429
+ def get_violations(
430
+ self,
431
+ framework: Optional[ComplianceFramework] = None,
432
+ agent_did: Optional[str] = None,
433
+ remediated: Optional[bool] = None,
434
+ ) -> list[ComplianceViolation]:
435
+ """Get violations with optional filters."""
436
+ violations = self._violations
437
+
438
+ if framework:
439
+ violations = [v for v in violations if v.framework == framework]
440
+
441
+ if agent_did:
442
+ violations = [v for v in violations if v.agent_did == agent_did]
443
+
444
+ if remediated is not None:
445
+ violations = [v for v in violations if v.remediated == remediated]
446
+
447
+ return violations