proxilion 0.0.1__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.
- proxilion/__init__.py +136 -0
- proxilion/audit/__init__.py +133 -0
- proxilion/audit/base_exporters.py +527 -0
- proxilion/audit/compliance/__init__.py +130 -0
- proxilion/audit/compliance/base.py +457 -0
- proxilion/audit/compliance/eu_ai_act.py +603 -0
- proxilion/audit/compliance/iso27001.py +544 -0
- proxilion/audit/compliance/soc2.py +491 -0
- proxilion/audit/events.py +493 -0
- proxilion/audit/explainability.py +1173 -0
- proxilion/audit/exporters/__init__.py +58 -0
- proxilion/audit/exporters/aws_s3.py +636 -0
- proxilion/audit/exporters/azure_storage.py +608 -0
- proxilion/audit/exporters/cloud_base.py +468 -0
- proxilion/audit/exporters/gcp_storage.py +570 -0
- proxilion/audit/exporters/multi_exporter.py +498 -0
- proxilion/audit/hash_chain.py +652 -0
- proxilion/audit/logger.py +543 -0
- proxilion/caching/__init__.py +49 -0
- proxilion/caching/tool_cache.py +633 -0
- proxilion/context/__init__.py +73 -0
- proxilion/context/context_window.py +556 -0
- proxilion/context/message_history.py +505 -0
- proxilion/context/session.py +735 -0
- proxilion/contrib/__init__.py +51 -0
- proxilion/contrib/anthropic.py +609 -0
- proxilion/contrib/google.py +1012 -0
- proxilion/contrib/langchain.py +641 -0
- proxilion/contrib/mcp.py +893 -0
- proxilion/contrib/openai.py +646 -0
- proxilion/core.py +3058 -0
- proxilion/decorators.py +966 -0
- proxilion/engines/__init__.py +287 -0
- proxilion/engines/base.py +266 -0
- proxilion/engines/casbin_engine.py +412 -0
- proxilion/engines/opa_engine.py +493 -0
- proxilion/engines/simple.py +437 -0
- proxilion/exceptions.py +887 -0
- proxilion/guards/__init__.py +54 -0
- proxilion/guards/input_guard.py +522 -0
- proxilion/guards/output_guard.py +634 -0
- proxilion/observability/__init__.py +198 -0
- proxilion/observability/cost_tracker.py +866 -0
- proxilion/observability/hooks.py +683 -0
- proxilion/observability/metrics.py +798 -0
- proxilion/observability/session_cost_tracker.py +1063 -0
- proxilion/policies/__init__.py +67 -0
- proxilion/policies/base.py +304 -0
- proxilion/policies/builtin.py +486 -0
- proxilion/policies/registry.py +376 -0
- proxilion/providers/__init__.py +201 -0
- proxilion/providers/adapter.py +468 -0
- proxilion/providers/anthropic_adapter.py +330 -0
- proxilion/providers/gemini_adapter.py +391 -0
- proxilion/providers/openai_adapter.py +294 -0
- proxilion/py.typed +0 -0
- proxilion/resilience/__init__.py +81 -0
- proxilion/resilience/degradation.py +615 -0
- proxilion/resilience/fallback.py +555 -0
- proxilion/resilience/retry.py +554 -0
- proxilion/scheduling/__init__.py +57 -0
- proxilion/scheduling/priority_queue.py +419 -0
- proxilion/scheduling/scheduler.py +459 -0
- proxilion/security/__init__.py +244 -0
- proxilion/security/agent_trust.py +968 -0
- proxilion/security/behavioral_drift.py +794 -0
- proxilion/security/cascade_protection.py +869 -0
- proxilion/security/circuit_breaker.py +428 -0
- proxilion/security/cost_limiter.py +690 -0
- proxilion/security/idor_protection.py +460 -0
- proxilion/security/intent_capsule.py +849 -0
- proxilion/security/intent_validator.py +495 -0
- proxilion/security/memory_integrity.py +767 -0
- proxilion/security/rate_limiter.py +509 -0
- proxilion/security/scope_enforcer.py +680 -0
- proxilion/security/sequence_validator.py +636 -0
- proxilion/security/trust_boundaries.py +784 -0
- proxilion/streaming/__init__.py +70 -0
- proxilion/streaming/detector.py +761 -0
- proxilion/streaming/transformer.py +674 -0
- proxilion/timeouts/__init__.py +55 -0
- proxilion/timeouts/decorators.py +477 -0
- proxilion/timeouts/manager.py +545 -0
- proxilion/tools/__init__.py +69 -0
- proxilion/tools/decorators.py +493 -0
- proxilion/tools/registry.py +732 -0
- proxilion/types.py +339 -0
- proxilion/validation/__init__.py +93 -0
- proxilion/validation/pydantic_schema.py +351 -0
- proxilion/validation/schema.py +651 -0
- proxilion-0.0.1.dist-info/METADATA +872 -0
- proxilion-0.0.1.dist-info/RECORD +94 -0
- proxilion-0.0.1.dist-info/WHEEL +4 -0
- proxilion-0.0.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SOC 2 Type II compliance exporter.
|
|
3
|
+
|
|
4
|
+
Provides audit log export formats for SOC 2 Type II compliance,
|
|
5
|
+
mapping to Trust Service Criteria (TSC) including:
|
|
6
|
+
- CC6: Logical and Physical Access Controls
|
|
7
|
+
- CC7: System Operations
|
|
8
|
+
- CC8: Change Management
|
|
9
|
+
|
|
10
|
+
Example:
|
|
11
|
+
>>> from proxilion.audit import InMemoryAuditLogger
|
|
12
|
+
>>> from proxilion.audit.compliance import SOC2Exporter
|
|
13
|
+
>>> from datetime import datetime, timedelta, timezone
|
|
14
|
+
>>>
|
|
15
|
+
>>> logger = InMemoryAuditLogger()
|
|
16
|
+
>>> # ... log events ...
|
|
17
|
+
>>>
|
|
18
|
+
>>> exporter = SOC2Exporter(
|
|
19
|
+
... logger,
|
|
20
|
+
... organization="Acme Corp",
|
|
21
|
+
... system_name="Customer API",
|
|
22
|
+
... responsible_party="Security Team",
|
|
23
|
+
... )
|
|
24
|
+
>>>
|
|
25
|
+
>>> end = datetime.now(timezone.utc)
|
|
26
|
+
>>> start = end - timedelta(days=90)
|
|
27
|
+
>>>
|
|
28
|
+
>>> # Export access control evidence
|
|
29
|
+
>>> access_evidence = exporter.export_access_control_evidence(start, end)
|
|
30
|
+
>>>
|
|
31
|
+
>>> # Generate full SOC 2 report
|
|
32
|
+
>>> report = exporter.generate_report(start, end)
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
from __future__ import annotations
|
|
36
|
+
|
|
37
|
+
from dataclasses import dataclass, field
|
|
38
|
+
from datetime import datetime, timezone # noqa: F401 (timezone used in docstring)
|
|
39
|
+
from typing import Any
|
|
40
|
+
|
|
41
|
+
from proxilion.audit.compliance.base import (
|
|
42
|
+
BaseComplianceExporter,
|
|
43
|
+
ComplianceEvidence,
|
|
44
|
+
ComplianceFramework,
|
|
45
|
+
ComplianceReport,
|
|
46
|
+
)
|
|
47
|
+
from proxilion.audit.events import EventType
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@dataclass
|
|
51
|
+
class AccessControlEvidence:
|
|
52
|
+
"""
|
|
53
|
+
Evidence for CC6.1 - Logical Access Security.
|
|
54
|
+
|
|
55
|
+
Attributes:
|
|
56
|
+
authorization_checks: All authorization checks performed.
|
|
57
|
+
access_denied: Denied access attempts.
|
|
58
|
+
privilege_escalation_blocked: Blocked privilege escalation attempts.
|
|
59
|
+
unique_users: Number of unique users.
|
|
60
|
+
unique_resources: Number of unique resources accessed.
|
|
61
|
+
"""
|
|
62
|
+
authorization_checks: list[dict[str, Any]] = field(default_factory=list)
|
|
63
|
+
access_denied: list[dict[str, Any]] = field(default_factory=list)
|
|
64
|
+
privilege_escalation_blocked: list[dict[str, Any]] = field(default_factory=list)
|
|
65
|
+
unique_users: int = 0
|
|
66
|
+
unique_resources: int = 0
|
|
67
|
+
|
|
68
|
+
def to_dict(self) -> dict[str, Any]:
|
|
69
|
+
"""Convert to dictionary."""
|
|
70
|
+
return {
|
|
71
|
+
"authorization_checks": self.authorization_checks,
|
|
72
|
+
"access_denied": self.access_denied,
|
|
73
|
+
"privilege_escalation_blocked": self.privilege_escalation_blocked,
|
|
74
|
+
"summary": {
|
|
75
|
+
"total_auth_checks": len(self.authorization_checks),
|
|
76
|
+
"total_denied": len(self.access_denied),
|
|
77
|
+
"total_escalation_blocked": len(self.privilege_escalation_blocked),
|
|
78
|
+
"unique_users": self.unique_users,
|
|
79
|
+
"unique_resources": self.unique_resources,
|
|
80
|
+
"denial_rate": (
|
|
81
|
+
len(self.access_denied) / len(self.authorization_checks)
|
|
82
|
+
if self.authorization_checks else 0.0
|
|
83
|
+
),
|
|
84
|
+
},
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@dataclass
|
|
89
|
+
class MonitoringEvidence:
|
|
90
|
+
"""
|
|
91
|
+
Evidence for CC7.2 - System Monitoring.
|
|
92
|
+
|
|
93
|
+
Attributes:
|
|
94
|
+
anomaly_detections: Anomalies detected by the system.
|
|
95
|
+
security_alerts: Security alerts raised.
|
|
96
|
+
incident_responses: Incident response actions taken.
|
|
97
|
+
monitoring_coverage: Percentage of operations monitored.
|
|
98
|
+
"""
|
|
99
|
+
anomaly_detections: list[dict[str, Any]] = field(default_factory=list)
|
|
100
|
+
security_alerts: list[dict[str, Any]] = field(default_factory=list)
|
|
101
|
+
incident_responses: list[dict[str, Any]] = field(default_factory=list)
|
|
102
|
+
monitoring_coverage: float = 100.0
|
|
103
|
+
|
|
104
|
+
def to_dict(self) -> dict[str, Any]:
|
|
105
|
+
"""Convert to dictionary."""
|
|
106
|
+
return {
|
|
107
|
+
"anomaly_detections": self.anomaly_detections,
|
|
108
|
+
"security_alerts": self.security_alerts,
|
|
109
|
+
"incident_responses": self.incident_responses,
|
|
110
|
+
"summary": {
|
|
111
|
+
"total_anomalies": len(self.anomaly_detections),
|
|
112
|
+
"total_alerts": len(self.security_alerts),
|
|
113
|
+
"total_incident_responses": len(self.incident_responses),
|
|
114
|
+
"monitoring_coverage": f"{self.monitoring_coverage:.1%}",
|
|
115
|
+
},
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
@dataclass
|
|
120
|
+
class ChangeManagementEvidence:
|
|
121
|
+
"""
|
|
122
|
+
Evidence for CC8.1 - Change Management.
|
|
123
|
+
|
|
124
|
+
Attributes:
|
|
125
|
+
configuration_changes: Logged configuration changes.
|
|
126
|
+
policy_updates: Policy update events.
|
|
127
|
+
approval_workflows: Approval workflow events.
|
|
128
|
+
"""
|
|
129
|
+
configuration_changes: list[dict[str, Any]] = field(default_factory=list)
|
|
130
|
+
policy_updates: list[dict[str, Any]] = field(default_factory=list)
|
|
131
|
+
approval_workflows: list[dict[str, Any]] = field(default_factory=list)
|
|
132
|
+
|
|
133
|
+
def to_dict(self) -> dict[str, Any]:
|
|
134
|
+
"""Convert to dictionary."""
|
|
135
|
+
return {
|
|
136
|
+
"configuration_changes": self.configuration_changes,
|
|
137
|
+
"policy_updates": self.policy_updates,
|
|
138
|
+
"approval_workflows": self.approval_workflows,
|
|
139
|
+
"summary": {
|
|
140
|
+
"total_config_changes": len(self.configuration_changes),
|
|
141
|
+
"total_policy_updates": len(self.policy_updates),
|
|
142
|
+
"total_approval_workflows": len(self.approval_workflows),
|
|
143
|
+
},
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class SOC2Exporter(BaseComplianceExporter):
|
|
148
|
+
"""
|
|
149
|
+
Export audit logs for SOC 2 Type II evidence.
|
|
150
|
+
|
|
151
|
+
Maps to Trust Service Criteria:
|
|
152
|
+
- CC6.1: Logical and physical access security
|
|
153
|
+
- CC7.2: System monitoring
|
|
154
|
+
- CC8.1: Change management
|
|
155
|
+
|
|
156
|
+
SOC 2 Type II reports cover a period of time (typically 6-12 months)
|
|
157
|
+
and provide evidence that controls were operating effectively
|
|
158
|
+
throughout the period.
|
|
159
|
+
|
|
160
|
+
Example:
|
|
161
|
+
>>> exporter = SOC2Exporter(
|
|
162
|
+
... logger,
|
|
163
|
+
... organization="Acme Corp",
|
|
164
|
+
... system_name="API Gateway",
|
|
165
|
+
... responsible_party="security@acme.com",
|
|
166
|
+
... )
|
|
167
|
+
>>>
|
|
168
|
+
>>> # Export access control evidence for CC6.1
|
|
169
|
+
>>> access = exporter.export_access_control_evidence(start, end)
|
|
170
|
+
>>>
|
|
171
|
+
>>> # Export monitoring evidence for CC7.2
|
|
172
|
+
>>> monitoring = exporter.export_monitoring_evidence(start, end)
|
|
173
|
+
>>>
|
|
174
|
+
>>> # Export change management evidence for CC8.1
|
|
175
|
+
>>> changes = exporter.export_change_management_evidence(start, end)
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
@property
|
|
179
|
+
def framework(self) -> ComplianceFramework:
|
|
180
|
+
"""Get the compliance framework."""
|
|
181
|
+
return ComplianceFramework.SOC2
|
|
182
|
+
|
|
183
|
+
@property
|
|
184
|
+
def framework_version(self) -> str:
|
|
185
|
+
"""Get the framework version."""
|
|
186
|
+
return "2017" # SOC 2 TSC version
|
|
187
|
+
|
|
188
|
+
def export_access_control_evidence(
|
|
189
|
+
self,
|
|
190
|
+
start: datetime,
|
|
191
|
+
end: datetime,
|
|
192
|
+
) -> AccessControlEvidence:
|
|
193
|
+
"""
|
|
194
|
+
Export CC6.1 - Logical Access Security evidence.
|
|
195
|
+
|
|
196
|
+
CC6.1 requires that logical access to systems is restricted
|
|
197
|
+
to authorized individuals only.
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
start: Start of the reporting period.
|
|
201
|
+
end: End of the reporting period.
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
AccessControlEvidence with categorized events.
|
|
205
|
+
"""
|
|
206
|
+
events = self.filter_by_date_range(start, end)
|
|
207
|
+
evidence = AccessControlEvidence()
|
|
208
|
+
|
|
209
|
+
users = set()
|
|
210
|
+
resources = set()
|
|
211
|
+
|
|
212
|
+
for event in events:
|
|
213
|
+
event_dict = self.event_to_evidence_dict(event)
|
|
214
|
+
users.add(event.data.user_id)
|
|
215
|
+
resources.add(event.data.tool_name)
|
|
216
|
+
|
|
217
|
+
# All authorization events are access control evidence
|
|
218
|
+
if event.data.event_type in [
|
|
219
|
+
EventType.AUTHORIZATION_GRANTED,
|
|
220
|
+
EventType.AUTHORIZATION_DENIED,
|
|
221
|
+
EventType.AUTHORIZATION_REQUEST,
|
|
222
|
+
]:
|
|
223
|
+
evidence.authorization_checks.append(event_dict)
|
|
224
|
+
|
|
225
|
+
# Denied events
|
|
226
|
+
if event.data.event_type == EventType.AUTHORIZATION_DENIED:
|
|
227
|
+
evidence.access_denied.append({
|
|
228
|
+
**event_dict,
|
|
229
|
+
"denial_reason": event.data.authorization_reason,
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
# IDOR violations indicate privilege escalation attempts
|
|
233
|
+
if event.data.event_type == EventType.IDOR_VIOLATION:
|
|
234
|
+
evidence.privilege_escalation_blocked.append({
|
|
235
|
+
**event_dict,
|
|
236
|
+
"violation_type": "unauthorized_resource_access",
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
evidence.unique_users = len(users)
|
|
240
|
+
evidence.unique_resources = len(resources)
|
|
241
|
+
|
|
242
|
+
return evidence
|
|
243
|
+
|
|
244
|
+
def export_monitoring_evidence(
|
|
245
|
+
self,
|
|
246
|
+
start: datetime,
|
|
247
|
+
end: datetime,
|
|
248
|
+
) -> MonitoringEvidence:
|
|
249
|
+
"""
|
|
250
|
+
Export CC7.2 - System Monitoring evidence.
|
|
251
|
+
|
|
252
|
+
CC7.2 requires that the entity monitors the system and
|
|
253
|
+
environment to identify security events.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
start: Start of the reporting period.
|
|
257
|
+
end: End of the reporting period.
|
|
258
|
+
|
|
259
|
+
Returns:
|
|
260
|
+
MonitoringEvidence with categorized events.
|
|
261
|
+
"""
|
|
262
|
+
events = self.filter_by_date_range(start, end)
|
|
263
|
+
evidence = MonitoringEvidence()
|
|
264
|
+
|
|
265
|
+
for event in events:
|
|
266
|
+
event_dict = self.event_to_evidence_dict(event)
|
|
267
|
+
|
|
268
|
+
# Anomaly detection events
|
|
269
|
+
if event.data.event_type in [
|
|
270
|
+
EventType.IDOR_VIOLATION,
|
|
271
|
+
EventType.SCHEMA_VALIDATION_FAILURE,
|
|
272
|
+
]:
|
|
273
|
+
evidence.anomaly_detections.append({
|
|
274
|
+
**event_dict,
|
|
275
|
+
"anomaly_type": event.data.event_type.value,
|
|
276
|
+
"detected_at": event.timestamp.isoformat(),
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
# Security alerts (rate limiting, circuit breakers)
|
|
280
|
+
if event.data.event_type in [
|
|
281
|
+
EventType.RATE_LIMIT_EXCEEDED,
|
|
282
|
+
EventType.CIRCUIT_BREAKER_OPEN,
|
|
283
|
+
]:
|
|
284
|
+
is_rate_limit = event.data.event_type == EventType.RATE_LIMIT_EXCEEDED
|
|
285
|
+
evidence.security_alerts.append({
|
|
286
|
+
**event_dict,
|
|
287
|
+
"alert_type": event.data.event_type.value,
|
|
288
|
+
"severity": "medium" if is_rate_limit else "high",
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
# Denied authorizations are incident responses
|
|
292
|
+
if event.data.event_type == EventType.AUTHORIZATION_DENIED:
|
|
293
|
+
evidence.incident_responses.append({
|
|
294
|
+
**event_dict,
|
|
295
|
+
"response_type": "access_blocked",
|
|
296
|
+
"response_reason": event.data.authorization_reason,
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
# All events are monitored, so coverage is 100%
|
|
300
|
+
evidence.monitoring_coverage = 1.0
|
|
301
|
+
|
|
302
|
+
return evidence
|
|
303
|
+
|
|
304
|
+
def export_change_management_evidence(
|
|
305
|
+
self,
|
|
306
|
+
start: datetime,
|
|
307
|
+
end: datetime,
|
|
308
|
+
) -> ChangeManagementEvidence:
|
|
309
|
+
"""
|
|
310
|
+
Export CC8.1 - Change Management evidence.
|
|
311
|
+
|
|
312
|
+
CC8.1 requires that changes to the system are authorized,
|
|
313
|
+
designed, developed, tested, and implemented appropriately.
|
|
314
|
+
|
|
315
|
+
Args:
|
|
316
|
+
start: Start of the reporting period.
|
|
317
|
+
end: End of the reporting period.
|
|
318
|
+
|
|
319
|
+
Returns:
|
|
320
|
+
ChangeManagementEvidence with categorized events.
|
|
321
|
+
"""
|
|
322
|
+
events = self.filter_by_date_range(start, end)
|
|
323
|
+
evidence = ChangeManagementEvidence()
|
|
324
|
+
|
|
325
|
+
for event in events:
|
|
326
|
+
event_dict = self.event_to_evidence_dict(event)
|
|
327
|
+
|
|
328
|
+
# Look for policy-related metadata
|
|
329
|
+
if event.data.authorization_metadata.get("policy_updated"):
|
|
330
|
+
evidence.policy_updates.append({
|
|
331
|
+
**event_dict,
|
|
332
|
+
"policy_name": event.data.authorization_metadata.get("policy_name"),
|
|
333
|
+
"change_type": "update",
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
# Look for configuration changes
|
|
337
|
+
if event.data.authorization_metadata.get("config_change"):
|
|
338
|
+
change_desc = event.data.authorization_metadata.get("change_description")
|
|
339
|
+
evidence.configuration_changes.append({
|
|
340
|
+
**event_dict,
|
|
341
|
+
"change_description": change_desc,
|
|
342
|
+
})
|
|
343
|
+
|
|
344
|
+
# Approval workflows (requires_approval events that were granted)
|
|
345
|
+
if (
|
|
346
|
+
event.data.authorization_metadata.get("requires_approval") and
|
|
347
|
+
event.data.authorization_allowed
|
|
348
|
+
):
|
|
349
|
+
evidence.approval_workflows.append({
|
|
350
|
+
**event_dict,
|
|
351
|
+
"approval_type": "tool_execution",
|
|
352
|
+
"approved_by": event.data.authorization_metadata.get("approved_by", "system"),
|
|
353
|
+
})
|
|
354
|
+
|
|
355
|
+
return evidence
|
|
356
|
+
|
|
357
|
+
def generate_report(
|
|
358
|
+
self,
|
|
359
|
+
start: datetime,
|
|
360
|
+
end: datetime,
|
|
361
|
+
) -> ComplianceReport:
|
|
362
|
+
"""
|
|
363
|
+
Generate a complete SOC 2 Type II compliance report.
|
|
364
|
+
|
|
365
|
+
Args:
|
|
366
|
+
start: Start of the reporting period.
|
|
367
|
+
end: End of the reporting period.
|
|
368
|
+
|
|
369
|
+
Returns:
|
|
370
|
+
Complete compliance report.
|
|
371
|
+
"""
|
|
372
|
+
metadata = self.create_metadata(start, end)
|
|
373
|
+
evidence_list = []
|
|
374
|
+
recommendations = []
|
|
375
|
+
|
|
376
|
+
# CC6.1: Logical Access Security
|
|
377
|
+
access = self.export_access_control_evidence(start, end)
|
|
378
|
+
access_data = access.to_dict()
|
|
379
|
+
|
|
380
|
+
cc6_1_evidence = ComplianceEvidence(
|
|
381
|
+
control_id="CC6.1",
|
|
382
|
+
control_name="Logical and Physical Access Controls",
|
|
383
|
+
evidence_type="access_logs",
|
|
384
|
+
description=(
|
|
385
|
+
"The entity implements logical access security software, "
|
|
386
|
+
"infrastructure, and architectures to support (1) identification "
|
|
387
|
+
"and authentication of authorized users, and (2) restriction of "
|
|
388
|
+
"authenticated user access to authorized data and functions."
|
|
389
|
+
),
|
|
390
|
+
events=access.authorization_checks[:50], # Limit for readability
|
|
391
|
+
summary=access_data["summary"],
|
|
392
|
+
compliant=len(access.authorization_checks) > 0,
|
|
393
|
+
notes=(
|
|
394
|
+
f"Showing 50 of {len(access.authorization_checks)} authorization events."
|
|
395
|
+
if len(access.authorization_checks) > 50 else None
|
|
396
|
+
),
|
|
397
|
+
)
|
|
398
|
+
evidence_list.append(cc6_1_evidence)
|
|
399
|
+
|
|
400
|
+
denial_rate = access_data["summary"]["denial_rate"]
|
|
401
|
+
if denial_rate > 0.2:
|
|
402
|
+
recommendations.append(
|
|
403
|
+
f"High denial rate ({denial_rate:.1%}) detected. "
|
|
404
|
+
"Review access policies for potential misconfigurations."
|
|
405
|
+
)
|
|
406
|
+
|
|
407
|
+
if len(access.privilege_escalation_blocked) > 0:
|
|
408
|
+
esc_count = len(access.privilege_escalation_blocked)
|
|
409
|
+
recommendations.append(
|
|
410
|
+
f"Detected {esc_count} privilege escalation attempts. "
|
|
411
|
+
"Consider reviewing user permissions and implementing additional controls."
|
|
412
|
+
)
|
|
413
|
+
|
|
414
|
+
# CC7.2: System Monitoring
|
|
415
|
+
monitoring = self.export_monitoring_evidence(start, end)
|
|
416
|
+
monitoring_data = monitoring.to_dict()
|
|
417
|
+
|
|
418
|
+
cc7_2_evidence = ComplianceEvidence(
|
|
419
|
+
control_id="CC7.2",
|
|
420
|
+
control_name="System Monitoring",
|
|
421
|
+
evidence_type="monitoring_logs",
|
|
422
|
+
description=(
|
|
423
|
+
"The entity monitors system components and the operation of "
|
|
424
|
+
"those components for anomalies that are indicative of "
|
|
425
|
+
"malicious acts, natural disasters, and errors affecting "
|
|
426
|
+
"the entity's ability to meet its objectives."
|
|
427
|
+
),
|
|
428
|
+
events=monitoring.security_alerts + monitoring.anomaly_detections,
|
|
429
|
+
summary=monitoring_data["summary"],
|
|
430
|
+
compliant=True, # Having monitoring in place is compliant
|
|
431
|
+
notes=(
|
|
432
|
+
"Continuous monitoring is in place. "
|
|
433
|
+
f"{len(monitoring.security_alerts)} alerts and "
|
|
434
|
+
f"{len(monitoring.anomaly_detections)} anomalies detected."
|
|
435
|
+
),
|
|
436
|
+
)
|
|
437
|
+
evidence_list.append(cc7_2_evidence)
|
|
438
|
+
|
|
439
|
+
if len(monitoring.security_alerts) > 50:
|
|
440
|
+
recommendations.append(
|
|
441
|
+
"High volume of security alerts. Consider implementing alert aggregation "
|
|
442
|
+
"and investigating root causes."
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
# CC8.1: Change Management
|
|
446
|
+
changes = self.export_change_management_evidence(start, end)
|
|
447
|
+
changes_data = changes.to_dict()
|
|
448
|
+
|
|
449
|
+
cc8_1_evidence = ComplianceEvidence(
|
|
450
|
+
control_id="CC8.1",
|
|
451
|
+
control_name="Change Management",
|
|
452
|
+
evidence_type="change_logs",
|
|
453
|
+
description=(
|
|
454
|
+
"The entity authorizes, designs, develops or acquires, "
|
|
455
|
+
"configures, documents, tests, approves, and implements "
|
|
456
|
+
"changes to infrastructure, data, software, and procedures "
|
|
457
|
+
"to meet its objectives."
|
|
458
|
+
),
|
|
459
|
+
events=changes.policy_updates + changes.configuration_changes,
|
|
460
|
+
summary=changes_data["summary"],
|
|
461
|
+
compliant=True, # Having change tracking is compliant
|
|
462
|
+
notes=(
|
|
463
|
+
f"Tracked {len(changes.policy_updates)} policy updates and "
|
|
464
|
+
f"{len(changes.configuration_changes)} configuration changes."
|
|
465
|
+
),
|
|
466
|
+
)
|
|
467
|
+
evidence_list.append(cc8_1_evidence)
|
|
468
|
+
|
|
469
|
+
# Overall summary
|
|
470
|
+
all_events = self.filter_by_date_range(start, end)
|
|
471
|
+
stats = self.compute_summary_stats(all_events)
|
|
472
|
+
|
|
473
|
+
summary = {
|
|
474
|
+
"reporting_period": f"{start.date()} to {end.date()}",
|
|
475
|
+
"total_operations": stats["total_events"],
|
|
476
|
+
"unique_users": stats["unique_users"],
|
|
477
|
+
"unique_resources": stats["unique_tools"],
|
|
478
|
+
"authorization_rate": f"{stats['grant_rate']:.1%}",
|
|
479
|
+
"security_alerts": len(monitoring.security_alerts),
|
|
480
|
+
"anomalies_detected": len(monitoring.anomaly_detections),
|
|
481
|
+
"changes_tracked": len(changes.policy_updates) + len(changes.configuration_changes),
|
|
482
|
+
"controls_tested": 3,
|
|
483
|
+
"controls_effective": sum(1 for e in evidence_list if e.compliant),
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
return ComplianceReport(
|
|
487
|
+
metadata=metadata,
|
|
488
|
+
evidence=evidence_list,
|
|
489
|
+
summary=summary,
|
|
490
|
+
recommendations=recommendations,
|
|
491
|
+
)
|