mcp-security-framework 1.1.0__py3-none-any.whl → 1.1.2__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.
Files changed (58) hide show
  1. mcp_security_framework/__init__.py +26 -15
  2. mcp_security_framework/cli/__init__.py +1 -1
  3. mcp_security_framework/cli/cert_cli.py +233 -197
  4. mcp_security_framework/cli/security_cli.py +324 -234
  5. mcp_security_framework/constants.py +21 -27
  6. mcp_security_framework/core/auth_manager.py +41 -22
  7. mcp_security_framework/core/cert_manager.py +210 -147
  8. mcp_security_framework/core/permission_manager.py +9 -9
  9. mcp_security_framework/core/rate_limiter.py +2 -2
  10. mcp_security_framework/core/security_manager.py +284 -229
  11. mcp_security_framework/examples/__init__.py +6 -0
  12. mcp_security_framework/examples/comprehensive_example.py +349 -279
  13. mcp_security_framework/examples/django_example.py +247 -206
  14. mcp_security_framework/examples/fastapi_example.py +315 -283
  15. mcp_security_framework/examples/flask_example.py +274 -203
  16. mcp_security_framework/examples/gateway_example.py +304 -237
  17. mcp_security_framework/examples/microservice_example.py +258 -189
  18. mcp_security_framework/examples/standalone_example.py +255 -230
  19. mcp_security_framework/examples/test_all_examples.py +151 -135
  20. mcp_security_framework/middleware/__init__.py +46 -55
  21. mcp_security_framework/middleware/auth_middleware.py +62 -63
  22. mcp_security_framework/middleware/fastapi_auth_middleware.py +119 -118
  23. mcp_security_framework/middleware/fastapi_middleware.py +156 -148
  24. mcp_security_framework/middleware/flask_auth_middleware.py +160 -147
  25. mcp_security_framework/middleware/flask_middleware.py +183 -157
  26. mcp_security_framework/middleware/mtls_middleware.py +106 -117
  27. mcp_security_framework/middleware/rate_limit_middleware.py +105 -101
  28. mcp_security_framework/middleware/security_middleware.py +109 -124
  29. mcp_security_framework/schemas/config.py +2 -1
  30. mcp_security_framework/schemas/models.py +18 -6
  31. mcp_security_framework/utils/cert_utils.py +14 -8
  32. mcp_security_framework/utils/datetime_compat.py +116 -0
  33. {mcp_security_framework-1.1.0.dist-info → mcp_security_framework-1.1.2.dist-info}/METADATA +4 -3
  34. mcp_security_framework-1.1.2.dist-info/RECORD +84 -0
  35. tests/conftest.py +63 -66
  36. tests/test_cli/test_cert_cli.py +184 -146
  37. tests/test_cli/test_security_cli.py +274 -247
  38. tests/test_core/test_cert_manager.py +24 -10
  39. tests/test_core/test_security_manager.py +2 -2
  40. tests/test_examples/test_comprehensive_example.py +190 -137
  41. tests/test_examples/test_fastapi_example.py +124 -101
  42. tests/test_examples/test_flask_example.py +124 -101
  43. tests/test_examples/test_standalone_example.py +73 -80
  44. tests/test_integration/test_auth_flow.py +213 -197
  45. tests/test_integration/test_certificate_flow.py +180 -149
  46. tests/test_integration/test_fastapi_integration.py +108 -111
  47. tests/test_integration/test_flask_integration.py +141 -140
  48. tests/test_integration/test_standalone_integration.py +290 -259
  49. tests/test_middleware/test_fastapi_auth_middleware.py +195 -174
  50. tests/test_middleware/test_fastapi_middleware.py +147 -132
  51. tests/test_middleware/test_flask_auth_middleware.py +260 -202
  52. tests/test_middleware/test_flask_middleware.py +201 -179
  53. tests/test_middleware/test_security_middleware.py +145 -130
  54. tests/test_utils/test_datetime_compat.py +147 -0
  55. mcp_security_framework-1.1.0.dist-info/RECORD +0 -82
  56. {mcp_security_framework-1.1.0.dist-info → mcp_security_framework-1.1.2.dist-info}/WHEEL +0 -0
  57. {mcp_security_framework-1.1.0.dist-info → mcp_security_framework-1.1.2.dist-info}/entry_points.txt +0 -0
  58. {mcp_security_framework-1.1.0.dist-info → mcp_security_framework-1.1.2.dist-info}/top_level.txt +0 -0
@@ -26,75 +26,92 @@ Version: 1.0.0
26
26
  License: MIT
27
27
  """
28
28
 
29
- import os
30
29
  import json
31
30
  import logging
32
- import tempfile
31
+ import os
33
32
  import shutil
34
- import ssl
35
33
  import socket
36
- from typing import Dict, List, Any, Optional, Tuple
34
+ import ssl
35
+ import tempfile
37
36
  from datetime import datetime, timedelta, timezone
38
37
  from pathlib import Path
38
+ from typing import Any, Dict, List, Optional, Tuple
39
39
 
40
- from mcp_security_framework.core.security_manager import SecurityManager
40
+ from mcp_security_framework.constants import (
41
+ AUTH_METHODS,
42
+ DEFAULT_SECURITY_HEADERS,
43
+ ErrorCodes,
44
+ )
41
45
  from mcp_security_framework.core.cert_manager import CertificateManager
46
+ from mcp_security_framework.core.security_manager import SecurityManager
42
47
  from mcp_security_framework.core.ssl_manager import SSLManager
43
48
  from mcp_security_framework.schemas.config import (
44
- SecurityConfig, AuthConfig, PermissionConfig, SSLConfig,
45
- CertificateConfig, RateLimitConfig, LoggingConfig,
46
- CAConfig, ClientCertConfig, ServerCertConfig, IntermediateCAConfig
49
+ AuthConfig,
50
+ CAConfig,
51
+ CertificateConfig,
52
+ ClientCertConfig,
53
+ IntermediateCAConfig,
54
+ LoggingConfig,
55
+ PermissionConfig,
56
+ RateLimitConfig,
57
+ SecurityConfig,
58
+ ServerCertConfig,
59
+ SSLConfig,
47
60
  )
48
61
  from mcp_security_framework.schemas.models import (
49
- AuthResult, ValidationResult, CertificatePair, CertificateInfo,
50
- AuthStatus, ValidationStatus, AuthMethod
51
- )
52
- from mcp_security_framework.constants import (
53
- DEFAULT_SECURITY_HEADERS, AUTH_METHODS, ErrorCodes
62
+ AuthMethod,
63
+ AuthResult,
64
+ AuthStatus,
65
+ CertificateInfo,
66
+ CertificatePair,
67
+ ValidationResult,
68
+ ValidationStatus,
54
69
  )
55
70
 
56
71
 
57
72
  class ComprehensiveSecurityExample:
58
73
  """
59
74
  Comprehensive Security Example
60
-
75
+
61
76
  This class demonstrates ALL capabilities of the MCP Security Framework
62
77
  including advanced certificate management features.
63
78
  """
64
-
79
+
65
80
  def __init__(self, work_dir: Optional[str] = None):
66
81
  """
67
82
  Initialize the comprehensive security example.
68
-
83
+
69
84
  Args:
70
85
  work_dir: Working directory for certificates and keys
71
86
  """
72
- self.work_dir = work_dir or tempfile.mkdtemp(prefix="mcp_security_comprehensive_")
87
+ self.work_dir = work_dir or tempfile.mkdtemp(
88
+ prefix="mcp_security_comprehensive_"
89
+ )
73
90
  self.certs_dir = os.path.join(self.work_dir, "certs")
74
91
  self.keys_dir = os.path.join(self.work_dir, "keys")
75
92
  self.config_dir = os.path.join(self.work_dir, "config")
76
-
93
+
77
94
  # Create directories
78
95
  os.makedirs(self.certs_dir, exist_ok=True)
79
96
  os.makedirs(self.keys_dir, exist_ok=True)
80
97
  os.makedirs(self.config_dir, exist_ok=True)
81
-
98
+
82
99
  # Initialize logger first
83
100
  self.logger = logging.getLogger(__name__)
84
-
101
+
85
102
  # Create roles configuration first
86
103
  self._create_roles_config()
87
-
104
+
88
105
  # Initialize configuration
89
106
  self.config = self._create_comprehensive_config()
90
107
  self.security_manager = SecurityManager(self.config)
91
108
  self.cert_manager = CertificateManager(self.config.certificates)
92
109
  self.ssl_manager = SSLManager(self.config.ssl)
93
-
110
+
94
111
  # Test data
95
112
  self.test_api_key = "admin_key_123"
96
113
  self.test_jwt_token = self._create_test_jwt_token()
97
-
114
+
98
115
  # Certificate paths
99
116
  self.ca_cert_path = None
100
117
  self.ca_key_path = None
@@ -104,31 +121,35 @@ class ComprehensiveSecurityExample:
104
121
  self.server_key_path = None
105
122
  self.client_cert_path = None
106
123
  self.client_key_path = None
107
-
124
+
108
125
  self.logger.info("Comprehensive Security Example initialized successfully")
109
-
126
+
110
127
  def _create_comprehensive_config(self) -> SecurityConfig:
111
128
  """Create comprehensive security configuration."""
112
129
  return SecurityConfig(
113
130
  auth=AuthConfig(
114
131
  enabled=True,
115
- methods=[AUTH_METHODS["API_KEY"], AUTH_METHODS["JWT"], AUTH_METHODS["CERTIFICATE"]],
132
+ methods=[
133
+ AUTH_METHODS["API_KEY"],
134
+ AUTH_METHODS["JWT"],
135
+ AUTH_METHODS["CERTIFICATE"],
136
+ ],
116
137
  api_keys={
117
138
  "admin_key_123": {"username": "admin", "roles": ["admin", "user"]},
118
139
  "user_key_456": {"username": "user", "roles": ["user"]},
119
- "readonly_key_789": {"username": "readonly", "roles": ["readonly"]}
140
+ "readonly_key_789": {"username": "readonly", "roles": ["readonly"]},
120
141
  },
121
142
  jwt_secret="your-super-secret-jwt-key-change-in-production-12345",
122
143
  jwt_algorithm="HS256",
123
144
  jwt_expiry_hours=24,
124
145
  public_paths=["/health/", "/metrics/"],
125
- security_headers=DEFAULT_SECURITY_HEADERS
146
+ security_headers=DEFAULT_SECURITY_HEADERS,
126
147
  ),
127
148
  permissions=PermissionConfig(
128
149
  enabled=True,
129
150
  roles_file=os.path.join(self.config_dir, "roles.json"),
130
151
  default_role="user",
131
- hierarchy_enabled=True
152
+ hierarchy_enabled=True,
132
153
  ),
133
154
  ssl=SSLConfig(
134
155
  enabled=False, # Disable initially, will be enabled after certificates are created
@@ -137,46 +158,55 @@ class ComprehensiveSecurityExample:
137
158
  ca_cert_file=None,
138
159
  verify_mode="CERT_REQUIRED",
139
160
  min_version="TLSv1.2",
140
- cipher_suite="ECDHE-RSA-AES256-GCM-SHA384"
161
+ cipher_suite="ECDHE-RSA-AES256-GCM-SHA384",
141
162
  ),
142
163
  certificates=CertificateConfig(
143
164
  enabled=False, # Disable initially, will be enabled after CA creation
144
165
  ca_cert_path=None, # Will be set after CA creation
145
- ca_key_path=None, # Will be set after CA creation
166
+ ca_key_path=None, # Will be set after CA creation
146
167
  cert_storage_path=self.certs_dir,
147
168
  key_storage_path=self.keys_dir,
148
169
  default_validity_days=365,
149
- default_key_size=2048
170
+ default_key_size=2048,
150
171
  ),
151
172
  rate_limiting=RateLimitConfig(
152
173
  enabled=True,
153
174
  default_limit=100,
154
175
  default_window=60,
155
- storage_type="memory"
176
+ storage_type="memory",
156
177
  ),
157
178
  logging=LoggingConfig(
158
179
  enabled=True,
159
180
  level="INFO",
160
181
  format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
161
- file_path=os.path.join(self.work_dir, "security.log")
162
- )
182
+ file_path=os.path.join(self.work_dir, "security.log"),
183
+ ),
163
184
  )
164
-
185
+
165
186
  def _create_test_jwt_token(self) -> str:
166
187
  """Create a test JWT token."""
167
188
  import jwt
189
+
168
190
  payload = {
169
191
  "username": "test_user",
170
192
  "roles": ["user"],
171
- "exp": datetime.now(timezone.utc) + timedelta(hours=1)
193
+ "exp": datetime.now(timezone.utc) + timedelta(hours=1),
172
194
  }
173
-
195
+
174
196
  # Ensure JWT secret is a string
175
- jwt_secret = str(self.config.auth.jwt_secret) if self.config.auth.jwt_secret else "default-secret"
176
- jwt_algorithm = str(self.config.auth.jwt_algorithm) if self.config.auth.jwt_algorithm else "HS256"
177
-
197
+ jwt_secret = (
198
+ str(self.config.auth.jwt_secret)
199
+ if self.config.auth.jwt_secret
200
+ else "default-secret"
201
+ )
202
+ jwt_algorithm = (
203
+ str(self.config.auth.jwt_algorithm)
204
+ if self.config.auth.jwt_algorithm
205
+ else "HS256"
206
+ )
207
+
178
208
  return jwt.encode(payload, jwt_secret, algorithm=jwt_algorithm)
179
-
209
+
180
210
  def _create_roles_config(self):
181
211
  """Create roles configuration file."""
182
212
  roles_config = {
@@ -184,36 +214,36 @@ class ComprehensiveSecurityExample:
184
214
  "admin": {
185
215
  "description": "Administrator role",
186
216
  "permissions": ["*"],
187
- "parent_roles": []
217
+ "parent_roles": [],
188
218
  },
189
219
  "user": {
190
- "description": "User role",
220
+ "description": "User role",
191
221
  "permissions": ["read:own", "write:own"],
192
- "parent_roles": []
222
+ "parent_roles": [],
193
223
  },
194
224
  "readonly": {
195
225
  "description": "Read Only role",
196
226
  "permissions": ["read:own"],
197
- "parent_roles": []
198
- }
227
+ "parent_roles": [],
228
+ },
199
229
  }
200
230
  }
201
-
231
+
202
232
  roles_file = os.path.join(self.config_dir, "roles.json")
203
- with open(roles_file, 'w') as f:
233
+ with open(roles_file, "w") as f:
204
234
  json.dump(roles_config, f, indent=2)
205
-
235
+
206
236
  self.logger.info(f"Created roles configuration: {roles_file}")
207
-
237
+
208
238
  def demonstrate_certificate_management(self) -> Dict[str, Any]:
209
239
  """
210
240
  Demonstrate comprehensive certificate management capabilities.
211
-
241
+
212
242
  Returns:
213
243
  Dict with certificate management test results
214
244
  """
215
245
  self.logger.info("Demonstrating comprehensive certificate management...")
216
-
246
+
217
247
  results = {
218
248
  "root_ca_creation": {},
219
249
  "intermediate_ca_creation": {},
@@ -221,9 +251,9 @@ class ComprehensiveSecurityExample:
221
251
  "client_cert_creation": {},
222
252
  "csr_creation": {},
223
253
  "crl_creation": {},
224
- "certificate_validation": {}
254
+ "certificate_validation": {},
225
255
  }
226
-
256
+
227
257
  try:
228
258
  # 1. Create Root CA
229
259
  self.logger.info("Creating Root CA certificate...")
@@ -234,21 +264,21 @@ class ComprehensiveSecurityExample:
234
264
  state="California",
235
265
  locality="San Francisco",
236
266
  validity_days=3650,
237
- key_size=4096
267
+ key_size=4096,
238
268
  )
239
-
269
+
240
270
  ca_pair = self.cert_manager.create_root_ca(ca_config)
241
271
  self.ca_cert_path = ca_pair.certificate_path
242
272
  self.ca_key_path = ca_pair.private_key_path
243
-
273
+
244
274
  results["root_ca_creation"] = {
245
275
  "success": True,
246
276
  "cert_path": self.ca_cert_path,
247
277
  "key_path": self.ca_key_path,
248
- "serial_number": ca_pair.serial_number
278
+ "serial_number": ca_pair.serial_number,
249
279
  }
250
280
  self.logger.info(f"Root CA created: {self.ca_cert_path}")
251
-
281
+
252
282
  # 2. Create Intermediate CA
253
283
  self.logger.info("Creating Intermediate CA certificate...")
254
284
  intermediate_config = IntermediateCAConfig(
@@ -260,21 +290,25 @@ class ComprehensiveSecurityExample:
260
290
  validity_days=1825,
261
291
  key_size=2048,
262
292
  parent_ca_cert=self.ca_cert_path,
263
- parent_ca_key=self.ca_key_path
293
+ parent_ca_key=self.ca_key_path,
294
+ )
295
+
296
+ intermediate_pair = self.cert_manager.create_intermediate_ca(
297
+ intermediate_config
264
298
  )
265
-
266
- intermediate_pair = self.cert_manager.create_intermediate_ca(intermediate_config)
267
299
  self.intermediate_ca_cert_path = intermediate_pair.certificate_path
268
300
  self.intermediate_ca_key_path = intermediate_pair.private_key_path
269
-
301
+
270
302
  results["intermediate_ca_creation"] = {
271
303
  "success": True,
272
304
  "cert_path": self.intermediate_ca_cert_path,
273
305
  "key_path": self.intermediate_ca_key_path,
274
- "serial_number": intermediate_pair.serial_number
306
+ "serial_number": intermediate_pair.serial_number,
275
307
  }
276
- self.logger.info(f"Intermediate CA created: {self.intermediate_ca_cert_path}")
277
-
308
+ self.logger.info(
309
+ f"Intermediate CA created: {self.intermediate_ca_cert_path}"
310
+ )
311
+
278
312
  # 3. Create Server Certificate
279
313
  self.logger.info("Creating server certificate...")
280
314
  server_config = ServerCertConfig(
@@ -286,21 +320,21 @@ class ComprehensiveSecurityExample:
286
320
  validity_days=365,
287
321
  key_size=2048,
288
322
  ca_cert_path=self.intermediate_ca_cert_path,
289
- ca_key_path=self.intermediate_ca_key_path
323
+ ca_key_path=self.intermediate_ca_key_path,
290
324
  )
291
-
325
+
292
326
  server_pair = self.cert_manager.create_server_certificate(server_config)
293
327
  self.server_cert_path = server_pair.certificate_path
294
328
  self.server_key_path = server_pair.private_key_path
295
-
329
+
296
330
  results["server_cert_creation"] = {
297
331
  "success": True,
298
332
  "cert_path": self.server_cert_path,
299
333
  "key_path": self.server_key_path,
300
- "serial_number": server_pair.serial_number
334
+ "serial_number": server_pair.serial_number,
301
335
  }
302
336
  self.logger.info(f"Server certificate created: {self.server_cert_path}")
303
-
337
+
304
338
  # 4. Create Client Certificate
305
339
  self.logger.info("Creating client certificate...")
306
340
  client_config = ClientCertConfig(
@@ -312,75 +346,77 @@ class ComprehensiveSecurityExample:
312
346
  validity_days=365,
313
347
  key_size=2048,
314
348
  ca_cert_path=self.intermediate_ca_cert_path,
315
- ca_key_path=self.intermediate_ca_key_path
349
+ ca_key_path=self.intermediate_ca_key_path,
316
350
  )
317
-
351
+
318
352
  client_pair = self.cert_manager.create_client_certificate(client_config)
319
353
  self.client_cert_path = client_pair.certificate_path
320
354
  self.client_key_path = client_pair.private_key_path
321
-
355
+
322
356
  results["client_cert_creation"] = {
323
357
  "success": True,
324
358
  "cert_path": self.client_cert_path,
325
359
  "key_path": self.client_key_path,
326
- "serial_number": client_pair.serial_number
360
+ "serial_number": client_pair.serial_number,
327
361
  }
328
362
  self.logger.info(f"Client certificate created: {self.client_cert_path}")
329
-
363
+
330
364
  # 5. Create Certificate Signing Request (CSR)
331
365
  self.logger.info("Creating Certificate Signing Request...")
332
- csr_path, csr_key_path = self.cert_manager.create_certificate_signing_request(
333
- common_name="new-service.example.com",
334
- organization="New Service Corp",
335
- country="US",
336
- state="California",
337
- locality="San Francisco",
338
- organizational_unit="IT Department",
339
- email="admin@new-service.example.com",
340
- key_size=2048,
341
- key_type="rsa"
366
+ csr_path, csr_key_path = (
367
+ self.cert_manager.create_certificate_signing_request(
368
+ common_name="new-service.example.com",
369
+ organization="New Service Corp",
370
+ country="US",
371
+ state="California",
372
+ locality="San Francisco",
373
+ organizational_unit="IT Department",
374
+ email="admin@new-service.example.com",
375
+ key_size=2048,
376
+ key_type="rsa",
377
+ )
342
378
  )
343
-
379
+
344
380
  results["csr_creation"] = {
345
381
  "success": True,
346
382
  "csr_path": csr_path,
347
- "key_path": csr_key_path
383
+ "key_path": csr_key_path,
348
384
  }
349
385
  self.logger.info(f"CSR created: {csr_path}")
350
-
386
+
351
387
  # 6. Create Certificate Revocation List (CRL)
352
388
  self.logger.info("Creating Certificate Revocation List...")
353
389
  revoked_serials = [
354
390
  {
355
391
  "serial": "123456789",
356
392
  "reason": "key_compromise",
357
- "revocation_date": datetime.now(timezone.utc)
393
+ "revocation_date": datetime.now(timezone.utc),
358
394
  },
359
395
  {
360
- "serial": "987654321",
396
+ "serial": "987654321",
361
397
  "reason": "certificate_hold",
362
- "revocation_date": datetime.now(timezone.utc)
363
- }
398
+ "revocation_date": datetime.now(timezone.utc),
399
+ },
364
400
  ]
365
-
401
+
366
402
  crl_path = self.cert_manager.create_crl(
367
403
  ca_cert_path=self.intermediate_ca_cert_path,
368
404
  ca_key_path=self.intermediate_ca_key_path,
369
405
  revoked_serials=revoked_serials,
370
- validity_days=30
406
+ validity_days=30,
371
407
  )
372
-
408
+
373
409
  results["crl_creation"] = {
374
410
  "success": True,
375
411
  "crl_path": crl_path,
376
- "revoked_count": len(revoked_serials)
412
+ "revoked_count": len(revoked_serials),
377
413
  }
378
414
  self.logger.info(f"CRL created: {crl_path}")
379
-
415
+
380
416
  # 7. Certificate Validation
381
417
  self.logger.info("Validating certificates...")
382
418
  cert_info = self.cert_manager.get_certificate_info(self.server_cert_path)
383
-
419
+
384
420
  results["certificate_validation"] = {
385
421
  "success": True,
386
422
  "subject": cert_info.subject,
@@ -388,54 +424,54 @@ class ComprehensiveSecurityExample:
388
424
  "serial_number": cert_info.serial_number,
389
425
  "valid_from": cert_info.not_before.isoformat(),
390
426
  "valid_until": cert_info.not_after.isoformat(),
391
- "is_valid": not cert_info.is_expired
427
+ "is_valid": not cert_info.is_expired,
392
428
  }
393
429
  self.logger.info("Certificate validation completed")
394
-
430
+
395
431
  # Update configuration with certificate paths
396
432
  self._update_config_after_certificates()
397
-
433
+
398
434
  except Exception as e:
399
435
  self.logger.error(f"Certificate management demonstration failed: {str(e)}")
400
436
  results["error"] = str(e)
401
-
437
+
402
438
  return results
403
-
439
+
404
440
  def _update_config_after_certificates(self):
405
441
  """Update configuration with certificate paths after creation."""
406
442
  if self.ca_cert_path and self.ca_key_path:
407
443
  self.config.certificates.enabled = True
408
444
  self.config.certificates.ca_cert_path = self.ca_cert_path
409
445
  self.config.certificates.ca_key_path = self.ca_key_path
410
-
446
+
411
447
  # Reinitialize certificate manager with updated config
412
448
  self.cert_manager = CertificateManager(self.config.certificates)
413
-
449
+
414
450
  if self.server_cert_path and self.server_key_path and self.ca_cert_path:
415
451
  self.config.ssl.enabled = True
416
452
  self.config.ssl.cert_file = self.server_cert_path
417
453
  self.config.ssl.key_file = self.server_key_path
418
454
  self.config.ssl.ca_cert_file = self.ca_cert_path
419
-
455
+
420
456
  # Reinitialize SSL manager with updated config
421
457
  self.ssl_manager = SSLManager(self.config.ssl)
422
-
458
+
423
459
  def demonstrate_ssl_tls_management(self) -> Dict[str, Any]:
424
460
  """
425
461
  Demonstrate SSL/TLS management capabilities.
426
-
462
+
427
463
  Returns:
428
464
  Dict with SSL/TLS test results
429
465
  """
430
466
  self.logger.info("Demonstrating SSL/TLS management...")
431
-
467
+
432
468
  results = {
433
469
  "server_context_creation": {},
434
470
  "client_context_creation": {},
435
471
  "mtls_context_creation": {},
436
- "ssl_validation": {}
472
+ "ssl_validation": {},
437
473
  }
438
-
474
+
439
475
  try:
440
476
  # 1. Create Server SSL Context
441
477
  self.logger.info("Creating server SSL context...")
@@ -444,17 +480,17 @@ class ComprehensiveSecurityExample:
444
480
  key_file=self.server_key_path,
445
481
  ca_cert_file=self.ca_cert_path,
446
482
  verify_mode="CERT_REQUIRED",
447
- min_version="TLSv1.2"
483
+ min_version="TLSv1.2",
448
484
  )
449
-
485
+
450
486
  results["server_context_creation"] = {
451
487
  "success": True,
452
488
  "verify_mode": str(server_context.verify_mode),
453
489
  "min_version": str(server_context.minimum_version),
454
- "max_version": str(server_context.maximum_version)
490
+ "max_version": str(server_context.maximum_version),
455
491
  }
456
492
  self.logger.info("Server SSL context created successfully")
457
-
493
+
458
494
  # 2. Create Client SSL Context
459
495
  self.logger.info("Creating client SSL context...")
460
496
  client_context = self.ssl_manager.create_client_context(
@@ -462,17 +498,17 @@ class ComprehensiveSecurityExample:
462
498
  client_cert_file=self.client_cert_path,
463
499
  client_key_file=self.client_key_path,
464
500
  verify_mode="CERT_REQUIRED",
465
- min_version="TLSv1.2"
501
+ min_version="TLSv1.2",
466
502
  )
467
-
503
+
468
504
  results["client_context_creation"] = {
469
505
  "success": True,
470
506
  "verify_mode": str(client_context.verify_mode),
471
507
  "min_version": str(client_context.minimum_version),
472
- "max_version": str(client_context.maximum_version)
508
+ "max_version": str(client_context.maximum_version),
473
509
  }
474
510
  self.logger.info("Client SSL context created successfully")
475
-
511
+
476
512
  # 3. Create mTLS Context (mutual TLS)
477
513
  self.logger.info("Creating mTLS context...")
478
514
  mtls_context = self.ssl_manager.create_server_context(
@@ -480,308 +516,295 @@ class ComprehensiveSecurityExample:
480
516
  key_file=self.server_key_path,
481
517
  ca_cert_file=self.ca_cert_path,
482
518
  verify_mode="CERT_REQUIRED",
483
- min_version="TLSv1.2"
519
+ min_version="TLSv1.2",
484
520
  )
485
-
521
+
486
522
  results["mtls_context_creation"] = {
487
523
  "success": True,
488
524
  "verify_mode": str(mtls_context.verify_mode),
489
- "client_cert_required": True
525
+ "client_cert_required": True,
490
526
  }
491
527
  self.logger.info("mTLS context created successfully")
492
-
528
+
493
529
  # 4. SSL Configuration Validation
494
530
  self.logger.info("Validating SSL configuration...")
495
-
531
+
496
532
  # Check if SSL files exist
497
533
  ssl_enabled = self.config.ssl.enabled
498
- cert_valid = os.path.exists(self.server_cert_path) if self.server_cert_path else False
499
- key_valid = os.path.exists(self.server_key_path) if self.server_key_path else False
534
+ cert_valid = (
535
+ os.path.exists(self.server_cert_path)
536
+ if self.server_cert_path
537
+ else False
538
+ )
539
+ key_valid = (
540
+ os.path.exists(self.server_key_path) if self.server_key_path else False
541
+ )
500
542
  ca_valid = os.path.exists(self.ca_cert_path) if self.ca_cert_path else False
501
-
543
+
502
544
  results["ssl_validation"] = {
503
545
  "success": True,
504
546
  "ssl_enabled": ssl_enabled,
505
547
  "certificate_valid": cert_valid,
506
548
  "key_valid": key_valid,
507
- "ca_valid": ca_valid
549
+ "ca_valid": ca_valid,
508
550
  }
509
551
  self.logger.info("SSL validation completed")
510
-
552
+
511
553
  except Exception as e:
512
554
  self.logger.error(f"SSL/TLS management demonstration failed: {str(e)}")
513
555
  results["error"] = str(e)
514
-
556
+
515
557
  return results
516
-
558
+
517
559
  def demonstrate_authentication(self) -> Dict[str, Any]:
518
560
  """
519
561
  Demonstrate authentication capabilities.
520
-
562
+
521
563
  Returns:
522
564
  Dict with authentication test results
523
565
  """
524
566
  self.logger.info("Demonstrating authentication capabilities...")
525
-
567
+
526
568
  results = {
527
569
  "api_key_auth": {},
528
570
  "jwt_auth": {},
529
571
  "certificate_auth": {},
530
- "failed_auth": {}
572
+ "failed_auth": {},
531
573
  }
532
-
574
+
533
575
  try:
534
576
  # 1. API Key Authentication
535
577
  self.logger.info("Testing API key authentication...")
536
- auth_result = self.security_manager.authenticate_user({
537
- "method": "api_key",
538
- "api_key": self.test_api_key
539
- })
578
+ auth_result = self.security_manager.authenticate_user(
579
+ {"method": "api_key", "api_key": self.test_api_key}
580
+ )
540
581
  results["api_key_auth"] = {
541
582
  "success": auth_result.is_valid,
542
583
  "username": auth_result.username,
543
584
  "roles": auth_result.roles,
544
- "auth_method": auth_result.auth_method.value
585
+ "auth_method": auth_result.auth_method.value,
545
586
  }
546
-
587
+
547
588
  # 2. JWT Authentication
548
589
  self.logger.info("Testing JWT authentication...")
549
- auth_result = self.security_manager.authenticate_user({
550
- "method": "jwt",
551
- "token": self.test_jwt_token
552
- })
590
+ auth_result = self.security_manager.authenticate_user(
591
+ {"method": "jwt", "token": self.test_jwt_token}
592
+ )
553
593
  results["jwt_auth"] = {
554
594
  "success": auth_result.is_valid,
555
595
  "username": auth_result.username,
556
596
  "roles": auth_result.roles,
557
- "auth_method": auth_result.auth_method.value
597
+ "auth_method": auth_result.auth_method.value,
558
598
  }
559
-
599
+
560
600
  # 3. Certificate Authentication (if certificate available)
561
601
  if self.client_cert_path:
562
602
  self.logger.info("Testing certificate authentication...")
563
- with open(self.client_cert_path, 'r') as f:
603
+ with open(self.client_cert_path, "r") as f:
564
604
  cert_pem = f.read()
565
-
566
- auth_result = self.security_manager.authenticate_user({
567
- "method": "certificate",
568
- "certificate": cert_pem
569
- })
605
+
606
+ auth_result = self.security_manager.authenticate_user(
607
+ {"method": "certificate", "certificate": cert_pem}
608
+ )
570
609
  results["certificate_auth"] = {
571
610
  "success": auth_result.is_valid,
572
611
  "username": auth_result.username,
573
612
  "roles": auth_result.roles,
574
- "auth_method": auth_result.auth_method.value
613
+ "auth_method": auth_result.auth_method.value,
575
614
  }
576
-
615
+
577
616
  # 4. Failed Authentication
578
617
  self.logger.info("Testing failed authentication...")
579
- auth_result = self.security_manager.authenticate_user({
580
- "method": "api_key",
581
- "api_key": "invalid_key"
582
- })
618
+ auth_result = self.security_manager.authenticate_user(
619
+ {"method": "api_key", "api_key": "invalid_key"}
620
+ )
583
621
  results["failed_auth"] = {
584
622
  "success": auth_result.is_valid,
585
623
  "error_code": auth_result.error_code,
586
- "error_message": auth_result.error_message
624
+ "error_message": auth_result.error_message,
587
625
  }
588
-
626
+
589
627
  except Exception as e:
590
628
  self.logger.error(f"Authentication demonstration failed: {str(e)}")
591
629
  results["error"] = str(e)
592
-
630
+
593
631
  return results
594
-
632
+
595
633
  def demonstrate_authorization(self) -> Dict[str, Any]:
596
634
  """
597
635
  Demonstrate authorization capabilities.
598
-
636
+
599
637
  Returns:
600
638
  Dict with authorization test results
601
639
  """
602
640
  self.logger.info("Demonstrating authorization capabilities...")
603
-
641
+
604
642
  results = {
605
643
  "admin_permissions": {},
606
644
  "user_permissions": {},
607
645
  "readonly_permissions": {},
608
- "denied_permissions": {}
646
+ "denied_permissions": {},
609
647
  }
610
-
648
+
611
649
  try:
612
650
  # 1. Admin Permissions
613
651
  self.logger.info("Testing admin permissions...")
614
652
  result = self.security_manager.check_permissions(
615
- user_roles=["admin"],
616
- required_permissions=["read", "write", "delete"]
653
+ user_roles=["admin"], required_permissions=["read", "write", "delete"]
617
654
  )
618
655
  results["admin_permissions"] = {
619
656
  "success": result.is_valid,
620
- "status": result.status.value
657
+ "status": result.status.value,
621
658
  }
622
-
659
+
623
660
  # 2. User Permissions
624
661
  self.logger.info("Testing user permissions...")
625
662
  result = self.security_manager.check_permissions(
626
- user_roles=["user"],
627
- required_permissions=["read:own", "write:own"]
663
+ user_roles=["user"], required_permissions=["read:own", "write:own"]
628
664
  )
629
665
  results["user_permissions"] = {
630
666
  "success": result.is_valid,
631
- "status": result.status.value
667
+ "status": result.status.value,
632
668
  }
633
-
669
+
634
670
  # 3. Readonly Permissions
635
671
  self.logger.info("Testing readonly permissions...")
636
672
  result = self.security_manager.check_permissions(
637
- user_roles=["readonly"],
638
- required_permissions=["read:own"]
673
+ user_roles=["readonly"], required_permissions=["read:own"]
639
674
  )
640
675
  results["readonly_permissions"] = {
641
676
  "success": result.is_valid,
642
- "status": result.status.value
677
+ "status": result.status.value,
643
678
  }
644
-
679
+
645
680
  # 4. Denied Permissions
646
681
  self.logger.info("Testing denied permissions...")
647
682
  result = self.security_manager.check_permissions(
648
- user_roles=["readonly"],
649
- required_permissions=["write", "delete"]
683
+ user_roles=["readonly"], required_permissions=["write", "delete"]
650
684
  )
651
685
  results["denied_permissions"] = {
652
686
  "success": result.is_valid,
653
- "status": result.status.value
687
+ "status": result.status.value,
654
688
  }
655
-
689
+
656
690
  except Exception as e:
657
691
  self.logger.error(f"Authorization demonstration failed: {str(e)}")
658
692
  results["error"] = str(e)
659
-
693
+
660
694
  return results
661
-
695
+
662
696
  def demonstrate_rate_limiting(self) -> Dict[str, Any]:
663
697
  """
664
698
  Demonstrate rate limiting capabilities.
665
-
699
+
666
700
  Returns:
667
701
  Dict with rate limiting test results
668
702
  """
669
703
  self.logger.info("Demonstrating rate limiting capabilities...")
670
-
671
- results = {
672
- "rate_limit_checks": [],
673
- "rate_limit_exceeded": False
674
- }
675
-
704
+
705
+ results = {"rate_limit_checks": [], "rate_limit_exceeded": False}
706
+
676
707
  try:
677
708
  # Test rate limiting
678
709
  for i in range(5):
679
710
  allowed = self.security_manager.check_rate_limit("test_user")
680
- results["rate_limit_checks"].append({
681
- "request": i + 1,
682
- "allowed": allowed
683
- })
684
-
711
+ results["rate_limit_checks"].append(
712
+ {"request": i + 1, "allowed": allowed}
713
+ )
714
+
685
715
  if not allowed:
686
716
  results["rate_limit_exceeded"] = True
687
717
  break
688
-
718
+
689
719
  except Exception as e:
690
720
  self.logger.error(f"Rate limiting demonstration failed: {str(e)}")
691
721
  results["error"] = str(e)
692
-
722
+
693
723
  return results
694
-
724
+
695
725
  def demonstrate_security_validation(self) -> Dict[str, Any]:
696
726
  """
697
727
  Demonstrate security validation capabilities.
698
-
728
+
699
729
  Returns:
700
730
  Dict with validation test results
701
731
  """
702
732
  self.logger.info("Demonstrating security validation capabilities...")
703
-
704
- results = {
705
- "request_validation": {},
706
- "configuration_validation": {}
707
- }
708
-
733
+
734
+ results = {"request_validation": {}, "configuration_validation": {}}
735
+
709
736
  try:
710
737
  # 1. Request Validation
711
738
  request_data = {
712
739
  "api_key": self.test_api_key,
713
740
  "required_permissions": ["read", "write"],
714
- "client_ip": "192.168.1.100"
741
+ "client_ip": "192.168.1.100",
715
742
  }
716
-
743
+
717
744
  result = self.security_manager.validate_request(request_data)
718
745
  results["request_validation"] = {
719
746
  "success": result.is_valid,
720
- "status": result.status.value
747
+ "status": result.status.value,
721
748
  }
722
-
749
+
723
750
  # 2. Configuration Validation
724
751
  result = self.security_manager.validate_configuration()
725
752
  results["configuration_validation"] = {
726
753
  "success": result.is_valid,
727
- "status": result.status.value
754
+ "status": result.status.value,
728
755
  }
729
-
756
+
730
757
  except Exception as e:
731
758
  self.logger.error(f"Security validation demonstration failed: {str(e)}")
732
759
  results["error"] = str(e)
733
-
760
+
734
761
  return results
735
-
762
+
736
763
  def demonstrate_security_monitoring(self) -> Dict[str, Any]:
737
764
  """
738
765
  Demonstrate security monitoring capabilities.
739
-
766
+
740
767
  Returns:
741
768
  Dict with monitoring test results
742
769
  """
743
770
  self.logger.info("Demonstrating security monitoring capabilities...")
744
-
745
- results = {
746
- "security_status": {},
747
- "security_metrics": {},
748
- "security_audit": {}
749
- }
750
-
771
+
772
+ results = {"security_status": {}, "security_metrics": {}, "security_audit": {}}
773
+
751
774
  try:
752
775
  # 1. Security Status
753
776
  status = self.security_manager.get_security_status()
754
777
  results["security_status"] = status
755
-
778
+
756
779
  # 2. Security Metrics
757
780
  metrics = self.security_manager.get_security_metrics()
758
781
  results["security_metrics"] = metrics
759
-
782
+
760
783
  # 3. Security Audit (not implemented yet, use empty dict)
761
784
  results["security_audit"] = {
762
785
  "authentication": [],
763
786
  "authorization": [],
764
787
  "certificate_operations": [],
765
- "ssl_operations": []
788
+ "ssl_operations": [],
766
789
  }
767
-
790
+
768
791
  except Exception as e:
769
792
  self.logger.error(f"Security monitoring demonstration failed: {str(e)}")
770
793
  results["error"] = str(e)
771
-
794
+
772
795
  return results
773
-
796
+
774
797
  def run_comprehensive_demo(self) -> Dict[str, Any]:
775
798
  """
776
799
  Run comprehensive demonstration of all framework capabilities.
777
-
800
+
778
801
  Returns:
779
802
  Dict with comprehensive test results
780
803
  """
781
804
  self.logger.info("Starting comprehensive security framework demonstration...")
782
-
805
+
783
806
  # Roles configuration already created in __init__
784
-
807
+
785
808
  # Run all demonstrations
786
809
  results = {
787
810
  "framework": "MCP Security Framework",
@@ -793,9 +816,9 @@ class ComprehensiveSecurityExample:
793
816
  "authorization": self.demonstrate_authorization(),
794
817
  "rate_limiting": self.demonstrate_rate_limiting(),
795
818
  "security_validation": self.demonstrate_security_validation(),
796
- "security_monitoring": self.demonstrate_security_monitoring()
819
+ "security_monitoring": self.demonstrate_security_monitoring(),
797
820
  }
798
-
821
+
799
822
  self.logger.info("Comprehensive demonstration completed successfully")
800
823
  return results
801
824
 
@@ -804,79 +827,126 @@ def main():
804
827
  """Main function to run the comprehensive example."""
805
828
  print("\n🚀 MCP Security Framework - Comprehensive Example")
806
829
  print("=" * 80)
807
-
830
+
808
831
  # Create example instance
809
832
  example = ComprehensiveSecurityExample()
810
-
833
+
811
834
  try:
812
835
  # Run comprehensive demonstration
813
836
  results = example.run_comprehensive_demo()
814
-
837
+
815
838
  # Print results
816
839
  print("\n📊 COMPREHENSIVE DEMONSTRATION RESULTS")
817
840
  print("=" * 80)
818
841
  print(f"Framework: {results['framework']}")
819
842
  print(f"Version: {results['version']}")
820
843
  print(f"Timestamp: {results['timestamp']}")
821
-
844
+
822
845
  print("\n🔐 CERTIFICATE MANAGEMENT RESULTS:")
823
- cert_mgmt = results['certificate_management']
824
- print(f" Root CA Creation: {'✅' if cert_mgmt.get('root_ca_creation', {}).get('success') else '❌'}")
825
- print(f" Intermediate CA Creation: {'✅' if cert_mgmt.get('intermediate_ca_creation', {}).get('success') else '❌'}")
826
- print(f" Server Cert Creation: {'✅' if cert_mgmt.get('server_cert_creation', {}).get('success') else '❌'}")
827
- print(f" Client Cert Creation: {'✅' if cert_mgmt.get('client_cert_creation', {}).get('success') else '❌'}")
828
- print(f" CSR Creation: {'✅' if cert_mgmt.get('csr_creation', {}).get('success') else '❌'}")
829
- print(f" CRL Creation: {'✅' if cert_mgmt.get('crl_creation', {}).get('success') else '❌'}")
830
- print(f" Certificate Validation: {'✅' if cert_mgmt.get('certificate_validation', {}).get('success') else '❌'}")
831
-
846
+ cert_mgmt = results["certificate_management"]
847
+ print(
848
+ f" Root CA Creation: {'✅' if cert_mgmt.get('root_ca_creation', {}).get('success') else '❌'}"
849
+ )
850
+ print(
851
+ f" Intermediate CA Creation: {'✅' if cert_mgmt.get('intermediate_ca_creation', {}).get('success') else '❌'}"
852
+ )
853
+ print(
854
+ f" Server Cert Creation: {'✅' if cert_mgmt.get('server_cert_creation', {}).get('success') else '❌'}"
855
+ )
856
+ print(
857
+ f" Client Cert Creation: {'✅' if cert_mgmt.get('client_cert_creation', {}).get('success') else '❌'}"
858
+ )
859
+ print(
860
+ f" CSR Creation: {'✅' if cert_mgmt.get('csr_creation', {}).get('success') else '❌'}"
861
+ )
862
+ print(
863
+ f" CRL Creation: {'✅' if cert_mgmt.get('crl_creation', {}).get('success') else '❌'}"
864
+ )
865
+ print(
866
+ f" Certificate Validation: {'✅' if cert_mgmt.get('certificate_validation', {}).get('success') else '❌'}"
867
+ )
868
+
832
869
  print("\n🔒 SSL/TLS MANAGEMENT RESULTS:")
833
- ssl_mgmt = results['ssl_tls_management']
834
- print(f" Server Context: {'✅' if ssl_mgmt.get('server_context_creation', {}).get('success') else '❌'}")
835
- print(f" Client Context: {'✅' if ssl_mgmt.get('client_context_creation', {}).get('success') else '❌'}")
836
- print(f" mTLS Context: {'✅' if ssl_mgmt.get('mtls_context_creation', {}).get('success') else '❌'}")
837
- print(f" SSL Validation: {'✅' if ssl_mgmt.get('ssl_validation', {}).get('success') else '❌'}")
838
-
870
+ ssl_mgmt = results["ssl_tls_management"]
871
+ print(
872
+ f" Server Context: {'✅' if ssl_mgmt.get('server_context_creation', {}).get('success') else '❌'}"
873
+ )
874
+ print(
875
+ f" Client Context: {'✅' if ssl_mgmt.get('client_context_creation', {}).get('success') else '❌'}"
876
+ )
877
+ print(
878
+ f" mTLS Context: {'✅' if ssl_mgmt.get('mtls_context_creation', {}).get('success') else '❌'}"
879
+ )
880
+ print(
881
+ f" SSL Validation: {'✅' if ssl_mgmt.get('ssl_validation', {}).get('success') else '❌'}"
882
+ )
883
+
839
884
  print("\n🔑 AUTHENTICATION RESULTS:")
840
- auth = results['authentication']
841
- print(f" API Key: {'✅' if auth.get('api_key_auth', {}).get('success') else '❌'}")
885
+ auth = results["authentication"]
886
+ print(
887
+ f" API Key: {'✅' if auth.get('api_key_auth', {}).get('success') else '❌'}"
888
+ )
842
889
  print(f" JWT: {'✅' if auth.get('jwt_auth', {}).get('success') else '❌'}")
843
- print(f" Certificate: {'✅' if auth.get('certificate_auth', {}).get('success') else '❌'}")
844
- print(f" Failed Auth: {'✅' if not auth.get('failed_auth', {}).get('success') else '❌'}")
845
-
890
+ print(
891
+ f" Certificate: {'✅' if auth.get('certificate_auth', {}).get('success') else '❌'}"
892
+ )
893
+ print(
894
+ f" Failed Auth: {'✅' if not auth.get('failed_auth', {}).get('success') else '❌'}"
895
+ )
896
+
846
897
  print("\n🔐 AUTHORIZATION RESULTS:")
847
- authz = results['authorization']
848
- print(f" Admin Permissions: {'✅' if authz.get('admin_permissions', {}).get('success') else '❌'}")
849
- print(f" User Permissions: {'✅' if authz.get('user_permissions', {}).get('success') else '❌'}")
850
- print(f" Readonly Permissions: {'✅' if authz.get('readonly_permissions', {}).get('success') else '❌'}")
851
- print(f" Denied Permissions: {'✅' if not authz.get('denied_permissions', {}).get('success') else '❌'}")
852
-
898
+ authz = results["authorization"]
899
+ print(
900
+ f" Admin Permissions: {'✅' if authz.get('admin_permissions', {}).get('success') else '❌'}"
901
+ )
902
+ print(
903
+ f" User Permissions: {'✅' if authz.get('user_permissions', {}).get('success') else '❌'}"
904
+ )
905
+ print(
906
+ f" Readonly Permissions: {'✅' if authz.get('readonly_permissions', {}).get('success') else '❌'}"
907
+ )
908
+ print(
909
+ f" Denied Permissions: {'✅' if not authz.get('denied_permissions', {}).get('success') else '❌'}"
910
+ )
911
+
853
912
  print("\n⚡ RATE LIMITING RESULTS:")
854
- rate_limit = results['rate_limiting']
913
+ rate_limit = results["rate_limiting"]
855
914
  print(f" Rate Limit Checks: {len(rate_limit.get('rate_limit_checks', []))}")
856
- print(f" Rate Limit Exceeded: {'❌' if rate_limit.get('rate_limit_exceeded') else '✅'}")
857
-
915
+ print(
916
+ f" Rate Limit Exceeded: {'❌' if rate_limit.get('rate_limit_exceeded') else '✅'}"
917
+ )
918
+
858
919
  print("\n🔒 SECURITY VALIDATION RESULTS:")
859
- validation = results['security_validation']
860
- print(f" Request Validation: {'✅' if validation.get('request_validation', {}).get('success') else '❌'}")
861
- print(f" Configuration Validation: {'✅' if validation.get('configuration_validation', {}).get('success') else '❌'}")
862
-
920
+ validation = results["security_validation"]
921
+ print(
922
+ f" Request Validation: {'✅' if validation.get('request_validation', {}).get('success') else '❌'}"
923
+ )
924
+ print(
925
+ f" Configuration Validation: {'✅' if validation.get('configuration_validation', {}).get('success') else '❌'}"
926
+ )
927
+
863
928
  print("\n📊 SECURITY MONITORING RESULTS:")
864
- monitoring = results['security_monitoring']
865
- print(f" Security Status: {'✅' if monitoring.get('security_status') else '❌'}")
866
- print(f" Security Metrics: {'✅' if monitoring.get('security_metrics') else '❌'}")
929
+ monitoring = results["security_monitoring"]
930
+ print(
931
+ f" Security Status: {'✅' if monitoring.get('security_status') else '❌'}"
932
+ )
933
+ print(
934
+ f" Security Metrics: {'✅' if monitoring.get('security_metrics') else '❌'}"
935
+ )
867
936
  print(f" Security Audit: {'✅' if monitoring.get('security_audit') else '❌'}")
868
-
937
+
869
938
  print("\n🎉 ALL FRAMEWORK CAPABILITIES DEMONSTRATED SUCCESSFULLY!")
870
939
  print("=" * 80)
871
-
940
+
872
941
  # Cleanup
873
942
  if example.work_dir and os.path.exists(example.work_dir):
874
943
  shutil.rmtree(example.work_dir)
875
944
  print(f"\n🧹 Cleaned up working directory: {example.work_dir}")
876
-
945
+
877
946
  except Exception as e:
878
947
  print(f"\n❌ Demonstration failed: {str(e)}")
879
948
  import traceback
949
+
880
950
  traceback.print_exc()
881
951
 
882
952