mcp-security-framework 1.1.0__py3-none-any.whl → 1.1.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.
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.1.dist-info}/METADATA +2 -1
  34. mcp_security_framework-1.1.1.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.1.dist-info}/WHEEL +0 -0
  57. {mcp_security_framework-1.1.0.dist-info → mcp_security_framework-1.1.1.dist-info}/entry_points.txt +0 -0
  58. {mcp_security_framework-1.1.0.dist-info → mcp_security_framework-1.1.1.dist-info}/top_level.txt +0 -0
@@ -21,82 +21,98 @@ Version: 1.0.0
21
21
  License: MIT
22
22
  """
23
23
 
24
- import os
25
24
  import json
26
25
  import logging
27
- import tempfile
26
+ import os
28
27
  import shutil
29
- from typing import Dict, List, Any, Optional
28
+ import tempfile
30
29
  from datetime import datetime, timedelta, timezone
30
+ from typing import Any, Dict, List, Optional
31
31
 
32
+ from mcp_security_framework.constants import (
33
+ AUTH_METHODS,
34
+ DEFAULT_SECURITY_HEADERS,
35
+ ErrorCodes,
36
+ )
32
37
  from mcp_security_framework.core.security_manager import SecurityManager
33
38
  from mcp_security_framework.schemas.config import (
34
- SecurityConfig, AuthConfig, PermissionConfig, SSLConfig,
35
- CertificateConfig, RateLimitConfig, LoggingConfig
39
+ AuthConfig,
40
+ CertificateConfig,
41
+ LoggingConfig,
42
+ PermissionConfig,
43
+ RateLimitConfig,
44
+ SecurityConfig,
45
+ SSLConfig,
36
46
  )
37
47
  from mcp_security_framework.schemas.models import (
38
- AuthResult, ValidationResult, CertificatePair, CertificateInfo,
39
- AuthStatus, ValidationStatus, AuthMethod
40
- )
41
- from mcp_security_framework.constants import (
42
- DEFAULT_SECURITY_HEADERS, AUTH_METHODS, ErrorCodes
48
+ AuthMethod,
49
+ AuthResult,
50
+ AuthStatus,
51
+ CertificateInfo,
52
+ CertificatePair,
53
+ ValidationResult,
54
+ ValidationStatus,
43
55
  )
44
56
 
45
57
 
46
58
  class StandaloneSecurityExample:
47
59
  """
48
60
  Comprehensive Standalone Security Example
49
-
61
+
50
62
  This class demonstrates ALL capabilities of the MCP Security Framework
51
63
  in a standalone environment, serving as a complete integration test.
52
64
  """
53
-
65
+
54
66
  def __init__(self, config_path: Optional[str] = None):
55
67
  """
56
68
  Initialize the standalone security example.
57
-
69
+
58
70
  Args:
59
71
  config_path: Optional path to configuration file
60
72
  """
61
73
  self.config = self._load_config(config_path)
62
74
  self.security_manager = SecurityManager(self.config)
63
75
  self.logger = logging.getLogger(__name__)
64
-
76
+
65
77
  # Test data
66
78
  self.test_api_key = "admin_key_123"
67
79
  self.test_jwt_token = self._create_test_jwt_token()
68
80
  self.test_certificate = self._create_test_certificate()
69
-
81
+
70
82
  self.logger.info("Standalone Security Example initialized successfully")
71
-
83
+
72
84
  def _load_config(self, config_path: Optional[str] = None) -> SecurityConfig:
73
85
  """Load security configuration."""
74
86
  if config_path and os.path.exists(config_path):
75
- with open(config_path, 'r') as f:
87
+ with open(config_path, "r") as f:
76
88
  config_data = json.load(f)
77
89
  return SecurityConfig(**config_data)
78
-
90
+
79
91
  # Create comprehensive configuration
80
92
  return SecurityConfig(
81
93
  auth=AuthConfig(
82
94
  enabled=True,
83
- methods=[AUTH_METHODS["API_KEY"], AUTH_METHODS["JWT"], AUTH_METHODS["CERTIFICATE"]],
95
+ methods=[
96
+ AUTH_METHODS["API_KEY"],
97
+ AUTH_METHODS["JWT"],
98
+ AUTH_METHODS["CERTIFICATE"],
99
+ ],
84
100
  api_keys={
85
101
  "admin_key_123": {"username": "admin", "roles": ["admin", "user"]},
86
102
  "user_key_456": {"username": "user", "roles": ["user"]},
87
- "readonly_key_789": {"username": "readonly", "roles": ["readonly"]}
103
+ "readonly_key_789": {"username": "readonly", "roles": ["readonly"]},
88
104
  },
89
105
  jwt_secret="your-super-secret-jwt-key-change-in-production-12345",
90
106
  jwt_algorithm="HS256",
91
107
  jwt_expiry_hours=24,
92
108
  public_paths=["/health/", "/metrics/"],
93
- security_headers=DEFAULT_SECURITY_HEADERS
109
+ security_headers=DEFAULT_SECURITY_HEADERS,
94
110
  ),
95
111
  permissions=PermissionConfig(
96
112
  enabled=True,
97
113
  roles_file="config/roles.json",
98
114
  default_role="user",
99
- hierarchy_enabled=True
115
+ hierarchy_enabled=True,
100
116
  ),
101
117
  ssl=SSLConfig(
102
118
  enabled=False, # Disable for standalone example
@@ -104,14 +120,14 @@ class StandaloneSecurityExample:
104
120
  key_file=None,
105
121
  ca_cert_file=None,
106
122
  verify_mode="CERT_REQUIRED",
107
- min_version="TLSv1.2"
123
+ min_version="TLSv1.2",
108
124
  ),
109
125
  certificates=CertificateConfig(
110
126
  enabled=False, # Disable for standalone example
111
127
  ca_cert_path=None,
112
128
  ca_key_path=None,
113
129
  cert_validity_days=365,
114
- key_size=2048
130
+ key_size=2048,
115
131
  ),
116
132
  rate_limit=RateLimitConfig(
117
133
  enabled=True,
@@ -120,7 +136,7 @@ class StandaloneSecurityExample:
120
136
  burst_limit=2,
121
137
  window_size_seconds=60,
122
138
  storage_backend="memory",
123
- cleanup_interval=300
139
+ cleanup_interval=300,
124
140
  ),
125
141
  logging=LoggingConfig(
126
142
  enabled=True,
@@ -130,24 +146,29 @@ class StandaloneSecurityExample:
130
146
  max_file_size=10,
131
147
  backup_count=5,
132
148
  console_output=True,
133
- json_format=False
149
+ json_format=False,
134
150
  ),
135
151
  debug=True,
136
152
  environment="test",
137
- version="1.0.0"
153
+ version="1.0.0",
138
154
  )
139
-
155
+
140
156
  def _create_test_jwt_token(self) -> str:
141
157
  """Create a test JWT token."""
142
158
  import jwt
159
+
143
160
  payload = {
144
161
  "username": "test_user",
145
162
  "roles": ["user"],
146
- "exp": datetime.now(timezone.utc) + timedelta(hours=1)
163
+ "exp": datetime.now(timezone.utc) + timedelta(hours=1),
147
164
  }
148
- jwt_secret = self.config.auth.jwt_secret.get_secret_value() if self.config.auth.jwt_secret else "default-jwt-secret-for-testing"
165
+ jwt_secret = (
166
+ self.config.auth.jwt_secret.get_secret_value()
167
+ if self.config.auth.jwt_secret
168
+ else "default-jwt-secret-for-testing"
169
+ )
149
170
  return jwt.encode(payload, jwt_secret, algorithm="HS256")
150
-
171
+
151
172
  def _create_test_certificate(self) -> str:
152
173
  """Create a test certificate."""
153
174
  return """-----BEGIN CERTIFICATE-----
@@ -162,104 +183,104 @@ eSBMdGQwHhcNMTkwMzI2MTIzMzQ5WhcNMjAwMzI1MTIzMzQ5WjBFMQswCQYDVQQG
162
183
  EwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lk
163
184
  Z2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
164
185
  -----END CERTIFICATE-----"""
165
-
186
+
166
187
  def demonstrate_authentication(self) -> Dict[str, Any]:
167
188
  """
168
189
  Demonstrate ALL authentication methods.
169
-
190
+
170
191
  Returns:
171
192
  Dict with authentication test results
172
193
  """
173
194
  self.logger.info("Demonstrating authentication capabilities...")
174
-
195
+
175
196
  results = {
176
197
  "api_key_auth": {},
177
198
  "jwt_auth": {},
178
199
  "certificate_auth": {},
179
- "failed_auth": {}
200
+ "failed_auth": {},
180
201
  }
181
-
202
+
182
203
  # 1. API Key Authentication
183
204
  try:
184
- auth_result = self.security_manager.authenticate_user({
185
- "method": "api_key",
186
- "api_key": self.test_api_key
187
- })
205
+ auth_result = self.security_manager.authenticate_user(
206
+ {"method": "api_key", "api_key": self.test_api_key}
207
+ )
188
208
  results["api_key_auth"] = {
189
209
  "success": auth_result.is_valid,
190
210
  "username": auth_result.username,
191
211
  "roles": auth_result.roles,
192
- "auth_method": auth_result.auth_method.value
212
+ "auth_method": auth_result.auth_method.value,
193
213
  }
194
- self.logger.info(f"API Key auth: {auth_result.username} - {auth_result.roles}")
214
+ self.logger.info(
215
+ f"API Key auth: {auth_result.username} - {auth_result.roles}"
216
+ )
195
217
  except Exception as e:
196
218
  results["api_key_auth"] = {"error": str(e)}
197
-
219
+
198
220
  # 2. JWT Authentication
199
221
  try:
200
- auth_result = self.security_manager.authenticate_user({
201
- "method": "jwt",
202
- "token": self.test_jwt_token
203
- })
222
+ auth_result = self.security_manager.authenticate_user(
223
+ {"method": "jwt", "token": self.test_jwt_token}
224
+ )
204
225
  results["jwt_auth"] = {
205
226
  "success": auth_result.is_valid,
206
227
  "username": auth_result.username,
207
228
  "roles": auth_result.roles,
208
- "auth_method": auth_result.auth_method.value
229
+ "auth_method": auth_result.auth_method.value,
209
230
  }
210
231
  self.logger.info(f"JWT auth: {auth_result.username} - {auth_result.roles}")
211
232
  except Exception as e:
212
233
  results["jwt_auth"] = {"error": str(e)}
213
-
234
+
214
235
  # 3. Certificate Authentication
215
236
  try:
216
- auth_result = self.security_manager.authenticate_user({
217
- "method": "certificate",
218
- "certificate": self.test_certificate
219
- })
237
+ auth_result = self.security_manager.authenticate_user(
238
+ {"method": "certificate", "certificate": self.test_certificate}
239
+ )
220
240
  results["certificate_auth"] = {
221
241
  "success": auth_result.is_valid,
222
242
  "username": auth_result.username,
223
243
  "roles": auth_result.roles,
224
- "auth_method": auth_result.auth_method.value
244
+ "auth_method": auth_result.auth_method.value,
225
245
  }
226
- self.logger.info(f"Certificate auth: {auth_result.username} - {auth_result.roles}")
246
+ self.logger.info(
247
+ f"Certificate auth: {auth_result.username} - {auth_result.roles}"
248
+ )
227
249
  except Exception as e:
228
250
  results["certificate_auth"] = {"error": str(e)}
229
-
251
+
230
252
  # 4. Failed Authentication
231
253
  try:
232
- auth_result = self.security_manager.authenticate_user({
233
- "method": "api_key",
234
- "api_key": "invalid_key"
235
- })
254
+ auth_result = self.security_manager.authenticate_user(
255
+ {"method": "api_key", "api_key": "invalid_key"}
256
+ )
236
257
  results["failed_auth"] = {
237
258
  "success": auth_result.is_valid,
238
259
  "error_message": auth_result.error_message,
239
- "error_code": auth_result.error_code
260
+ "error_code": auth_result.error_code,
240
261
  }
241
262
  self.logger.info(f"Failed auth test: {auth_result.error_message}")
242
263
  except Exception as e:
243
264
  results["failed_auth"] = {"error": str(e)}
244
-
265
+
245
266
  return results
246
-
267
+
247
268
  def demonstrate_authorization(self) -> Dict[str, Any]:
248
269
  """
249
270
  Demonstrate authorization capabilities.
250
-
271
+
251
272
  Returns:
252
273
  Dict with authorization test results
253
274
  """
254
275
  self.logger.info("Demonstrating authorization capabilities...")
255
-
276
+
256
277
  results = {
257
278
  "admin_permissions": {},
258
279
  "user_permissions": {},
259
280
  "readonly_permissions": {},
260
- "denied_permissions": {}
281
+ "denied_permissions": {},
261
282
  }
262
-
283
+
263
284
  # 1. Admin permissions
264
285
  try:
265
286
  result = self.security_manager.check_permissions(
@@ -267,12 +288,12 @@ Z2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
267
288
  )
268
289
  results["admin_permissions"] = {
269
290
  "success": result.is_valid,
270
- "status": result.status.value
291
+ "status": result.status.value,
271
292
  }
272
293
  self.logger.info(f"Admin permissions: {result.is_valid}")
273
294
  except Exception as e:
274
295
  results["admin_permissions"] = {"error": str(e)}
275
-
296
+
276
297
  # 2. User permissions
277
298
  try:
278
299
  result = self.security_manager.check_permissions(
@@ -280,94 +301,85 @@ Z2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
280
301
  )
281
302
  results["user_permissions"] = {
282
303
  "success": result.is_valid,
283
- "status": result.status.value
304
+ "status": result.status.value,
284
305
  }
285
306
  self.logger.info(f"User permissions: {result.is_valid}")
286
307
  except Exception as e:
287
308
  results["user_permissions"] = {"error": str(e)}
288
-
309
+
289
310
  # 3. Readonly permissions
290
311
  try:
291
- result = self.security_manager.check_permissions(
292
- ["readonly"], ["read"]
293
- )
312
+ result = self.security_manager.check_permissions(["readonly"], ["read"])
294
313
  results["readonly_permissions"] = {
295
314
  "success": result.is_valid,
296
- "status": result.status.value
315
+ "status": result.status.value,
297
316
  }
298
317
  self.logger.info(f"Readonly permissions: {result.is_valid}")
299
318
  except Exception as e:
300
319
  results["readonly_permissions"] = {"error": str(e)}
301
-
320
+
302
321
  # 4. Denied permissions
303
322
  try:
304
- result = self.security_manager.check_permissions(
305
- ["readonly"], ["delete"]
306
- )
323
+ result = self.security_manager.check_permissions(["readonly"], ["delete"])
307
324
  results["denied_permissions"] = {
308
325
  "success": result.is_valid,
309
326
  "status": result.status.value,
310
- "error_message": result.error_message
327
+ "error_message": result.error_message,
311
328
  }
312
329
  self.logger.info(f"Denied permissions: {result.is_valid}")
313
330
  except Exception as e:
314
331
  results["denied_permissions"] = {"error": str(e)}
315
-
332
+
316
333
  return results
317
-
334
+
318
335
  def demonstrate_rate_limiting(self) -> Dict[str, Any]:
319
336
  """
320
337
  Demonstrate rate limiting capabilities.
321
-
338
+
322
339
  Returns:
323
340
  Dict with rate limiting test results
324
341
  """
325
342
  self.logger.info("Demonstrating rate limiting capabilities...")
326
-
327
- results = {
328
- "rate_limit_checks": [],
329
- "rate_limit_exceeded": False
330
- }
331
-
343
+
344
+ results = {"rate_limit_checks": [], "rate_limit_exceeded": False}
345
+
332
346
  identifier = "test_user_123"
333
-
347
+
334
348
  # Test rate limiting
335
349
  for i in range(5):
336
350
  try:
337
351
  allowed = self.security_manager.check_rate_limit(identifier)
338
- results["rate_limit_checks"].append({
339
- "request": i + 1,
340
- "allowed": allowed
341
- })
342
- self.logger.info(f"Rate limit check {i+1}: {'Allowed' if allowed else 'Blocked'}")
343
-
352
+ results["rate_limit_checks"].append(
353
+ {"request": i + 1, "allowed": allowed}
354
+ )
355
+ self.logger.info(
356
+ f"Rate limit check {i+1}: {'Allowed' if allowed else 'Blocked'}"
357
+ )
358
+
344
359
  if not allowed:
345
360
  results["rate_limit_exceeded"] = True
346
361
  break
347
-
362
+
348
363
  except Exception as e:
349
- results["rate_limit_checks"].append({
350
- "request": i + 1,
351
- "error": str(e)
352
- })
353
-
364
+ results["rate_limit_checks"].append({"request": i + 1, "error": str(e)})
365
+
354
366
  return results
355
-
367
+
356
368
  def demonstrate_certificate_management(self) -> Dict[str, Any]:
357
369
  """
358
370
  Demonstrate certificate management capabilities.
359
-
371
+
360
372
  Returns:
361
373
  Dict with certificate management test results
362
374
  """
363
375
  self.logger.info("Demonstrating certificate management capabilities...")
364
-
376
+
365
377
  results = {
366
378
  "certificate_creation": {},
367
379
  "certificate_validation": {},
368
- "certificate_info": {}
380
+ "certificate_info": {},
369
381
  }
370
-
382
+
371
383
  # 1. Certificate creation (if enabled)
372
384
  if self.config.certificates.enabled:
373
385
  try:
@@ -376,19 +388,19 @@ Z2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
376
388
  "common_name": "test-client.example.com",
377
389
  "organization": "Test Organization",
378
390
  "country": "US",
379
- "validity_days": 365
391
+ "validity_days": 365,
380
392
  }
381
-
393
+
382
394
  # Note: This would require actual CA files
383
395
  # cert_pair = self.security_manager.create_certificate(cert_config)
384
396
  results["certificate_creation"] = {
385
397
  "success": True,
386
- "message": "Certificate creation capability demonstrated"
398
+ "message": "Certificate creation capability demonstrated",
387
399
  }
388
400
  self.logger.info("Certificate creation capability demonstrated")
389
401
  except Exception as e:
390
402
  results["certificate_creation"] = {"error": str(e)}
391
-
403
+
392
404
  # 2. Certificate validation
393
405
  try:
394
406
  # Test with dummy certificate
@@ -398,81 +410,74 @@ Z2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
398
410
  serial_number="123456789",
399
411
  valid_from=datetime.now(timezone.utc),
400
412
  valid_until=datetime.now(timezone.utc) + timedelta(days=365),
401
- is_valid=True
413
+ is_valid=True,
402
414
  )
403
415
  results["certificate_validation"] = {
404
416
  "success": True,
405
417
  "certificate_info": {
406
418
  "subject": cert_info.subject,
407
419
  "issuer": cert_info.issuer,
408
- "is_valid": cert_info.is_valid
409
- }
420
+ "is_valid": cert_info.is_valid,
421
+ },
410
422
  }
411
423
  self.logger.info("Certificate validation capability demonstrated")
412
424
  except Exception as e:
413
425
  results["certificate_validation"] = {"error": str(e)}
414
-
426
+
415
427
  return results
416
-
428
+
417
429
  def demonstrate_security_validation(self) -> Dict[str, Any]:
418
430
  """
419
431
  Demonstrate security validation capabilities.
420
-
432
+
421
433
  Returns:
422
434
  Dict with validation test results
423
435
  """
424
436
  self.logger.info("Demonstrating security validation capabilities...")
425
-
426
- results = {
427
- "request_validation": {},
428
- "configuration_validation": {}
429
- }
430
-
437
+
438
+ results = {"request_validation": {}, "configuration_validation": {}}
439
+
431
440
  # 1. Request validation
432
441
  try:
433
442
  request_data = {
434
443
  "api_key": self.test_api_key,
435
444
  "required_permissions": ["read", "write"],
436
- "client_ip": "192.168.1.100"
445
+ "client_ip": "192.168.1.100",
437
446
  }
438
-
447
+
439
448
  result = self.security_manager.validate_request(request_data)
440
449
  results["request_validation"] = {
441
450
  "success": result.is_valid,
442
- "status": result.status.value
451
+ "status": result.status.value,
443
452
  }
444
453
  self.logger.info(f"Request validation: {result.is_valid}")
445
454
  except Exception as e:
446
455
  results["request_validation"] = {"error": str(e)}
447
-
456
+
448
457
  # 2. Configuration validation
449
458
  try:
450
459
  result = self.security_manager.validate_configuration()
451
460
  results["configuration_validation"] = {
452
461
  "success": result.is_valid,
453
- "status": result.status.value
462
+ "status": result.status.value,
454
463
  }
455
464
  self.logger.info(f"Configuration validation: {result.is_valid}")
456
465
  except Exception as e:
457
466
  results["configuration_validation"] = {"error": str(e)}
458
-
467
+
459
468
  return results
460
-
469
+
461
470
  def demonstrate_security_monitoring(self) -> Dict[str, Any]:
462
471
  """
463
472
  Demonstrate security monitoring capabilities.
464
-
473
+
465
474
  Returns:
466
475
  Dict with monitoring test results
467
476
  """
468
477
  self.logger.info("Demonstrating security monitoring capabilities...")
469
-
470
- results = {
471
- "security_status": {},
472
- "security_metrics": {},
473
- "security_audit": {}
474
- }
475
-
478
+
479
+ results = {"security_status": {}, "security_metrics": {}, "security_audit": {}}
480
+
476
481
  # 1. Security status
477
482
  try:
478
483
  status = self.security_manager.get_security_status()
@@ -480,26 +485,26 @@ Z2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
480
485
  "status": status.status.value,
481
486
  "message": status.message,
482
487
  "version": status.version,
483
- "metadata": status.metadata
488
+ "metadata": status.metadata,
484
489
  }
485
490
  print(f"Security status: {results['security_status']}")
486
491
  self.logger.info("Security status retrieved successfully")
487
492
  except Exception as e:
488
493
  results["security_status"] = {"error": str(e)}
489
494
  print(f"Security status error: {str(e)}")
490
-
495
+
491
496
  # 2. Security metrics
492
497
  try:
493
498
  metrics = self.security_manager.get_security_metrics()
494
499
  results["security_metrics"] = {
495
500
  "authentication_attempts": metrics.get("authentication_attempts", 0),
496
501
  "security_events": metrics.get("security_events", 0),
497
- "uptime_seconds": metrics.get("uptime_seconds", 0)
502
+ "uptime_seconds": metrics.get("uptime_seconds", 0),
498
503
  }
499
504
  self.logger.info("Security metrics retrieved successfully")
500
505
  except Exception as e:
501
506
  results["security_metrics"] = {"error": str(e)}
502
-
507
+
503
508
  # 3. Security audit
504
509
  try:
505
510
  audit = self.security_manager.perform_security_audit()
@@ -507,23 +512,23 @@ Z2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
507
512
  "authentication": audit.get("authentication", {}),
508
513
  "authorization": audit.get("authorization", {}),
509
514
  "rate_limiting": audit.get("rate_limiting", {}),
510
- "ssl": audit.get("ssl", {})
515
+ "ssl": audit.get("ssl", {}),
511
516
  }
512
517
  self.logger.info("Security audit completed successfully")
513
518
  except Exception as e:
514
519
  results["security_audit"] = {"error": str(e)}
515
-
520
+
516
521
  return results
517
-
522
+
518
523
  def run_comprehensive_demo(self) -> Dict[str, Any]:
519
524
  """
520
525
  Run comprehensive demonstration of ALL framework capabilities.
521
-
526
+
522
527
  Returns:
523
528
  Dict with all demonstration results
524
529
  """
525
530
  self.logger.info("Starting comprehensive security framework demonstration...")
526
-
531
+
527
532
  demo_results = {
528
533
  "timestamp": datetime.now(timezone.utc).isoformat(),
529
534
  "framework": "MCP Security Framework",
@@ -533,16 +538,16 @@ Z2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
533
538
  "rate_limiting": self.demonstrate_rate_limiting(),
534
539
  "certificate_management": self.demonstrate_certificate_management(),
535
540
  "security_validation": self.demonstrate_security_validation(),
536
- "security_monitoring": self.demonstrate_security_monitoring()
541
+ "security_monitoring": self.demonstrate_security_monitoring(),
537
542
  }
538
-
543
+
539
544
  self.logger.info("Comprehensive demonstration completed successfully")
540
545
  return demo_results
541
-
546
+
542
547
  def process_request(self, request_data: Dict[str, Any]) -> Dict[str, Any]:
543
548
  """
544
549
  Process a security request.
545
-
550
+
546
551
  Args:
547
552
  request_data: Dictionary containing request information
548
553
  - credentials: Authentication credentials
@@ -550,7 +555,7 @@ Z2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
550
555
  - resource: Resource being accessed
551
556
  - identifier: Client identifier for rate limiting
552
557
  - data: Optional data for write operations
553
-
558
+
554
559
  Returns:
555
560
  Dictionary with processing results
556
561
  """
@@ -561,7 +566,7 @@ Z2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
561
566
  resource = request_data.get("resource", "/")
562
567
  identifier = request_data.get("identifier", "unknown")
563
568
  data = request_data.get("data")
564
-
569
+
565
570
  # Check rate limiting
566
571
  rate_limit_result = self.security_manager.check_rate_limit(identifier)
567
572
  if not rate_limit_result:
@@ -569,52 +574,48 @@ Z2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
569
574
  "success": False,
570
575
  "status_code": 429,
571
576
  "error": "Rate limit exceeded",
572
- "retry_after": 60
577
+ "retry_after": 60,
573
578
  }
574
-
579
+
575
580
  # Authenticate request
576
581
  auth_result = None
577
582
  if "api_key" in credentials:
578
- auth_result = self.security_manager.authenticate_user({
579
- "method": "api_key",
580
- "api_key": credentials["api_key"]
581
- })
583
+ auth_result = self.security_manager.authenticate_user(
584
+ {"method": "api_key", "api_key": credentials["api_key"]}
585
+ )
582
586
  elif "jwt_token" in credentials:
583
- auth_result = self.security_manager.authenticate_user({
584
- "method": "jwt",
585
- "token": credentials["jwt_token"]
586
- })
587
+ auth_result = self.security_manager.authenticate_user(
588
+ {"method": "jwt", "token": credentials["jwt_token"]}
589
+ )
587
590
  elif "certificate" in credentials:
588
- auth_result = self.security_manager.authenticate_user({
589
- "method": "certificate",
590
- "certificate": credentials["certificate"]
591
- })
592
-
591
+ auth_result = self.security_manager.authenticate_user(
592
+ {"method": "certificate", "certificate": credentials["certificate"]}
593
+ )
594
+
593
595
  # Check authentication
594
596
  if not auth_result or not auth_result.is_valid:
595
597
  return {
596
598
  "success": False,
597
599
  "status_code": 401,
598
600
  "error": "Authentication failed",
599
- "auth_result": auth_result.model_dump() if auth_result else None
601
+ "auth_result": auth_result.model_dump() if auth_result else None,
600
602
  }
601
-
603
+
602
604
  # Check authorization
603
605
  required_permissions = self._get_required_permissions(action, resource)
604
606
  authz_result = self.security_manager.check_permissions(
605
- auth_result.roles,
606
- required_permissions
607
+ auth_result.roles, required_permissions
607
608
  )
608
-
609
+
609
610
  if not authz_result.is_valid:
610
611
  return {
611
612
  "success": False,
612
613
  "status_code": 403,
613
614
  "error": "Authorization failed",
614
615
  "auth_result": auth_result.model_dump(),
615
- "authz_result": authz_result.model_dump()
616
+ "authz_result": authz_result.model_dump(),
616
617
  }
617
-
618
+
618
619
  # Process the request
619
620
  result = {
620
621
  "success": True,
@@ -623,113 +624,113 @@ Z2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
623
624
  "authz_result": authz_result.model_dump(),
624
625
  "data": data if action == "write" else None,
625
626
  "resource": resource,
626
- "action": action
627
+ "action": action,
627
628
  }
628
-
629
+
629
630
  # Log the successful request
630
631
  self.logger.info(f"Request processed successfully: {action} {resource}")
631
-
632
+
632
633
  return result
633
-
634
+
634
635
  except Exception as e:
635
636
  self.logger.error(f"Error processing request: {str(e)}")
636
637
  return {
637
638
  "success": False,
638
639
  "status_code": 500,
639
- "error": f"Internal server error: {str(e)}"
640
+ "error": f"Internal server error: {str(e)}",
640
641
  }
641
-
642
+
642
643
  def _get_required_permissions(self, action: str, resource: str) -> List[str]:
643
644
  """Get required permissions for action and resource."""
644
645
  if action == "read":
645
- return ["read:own"] # Use read:own instead of read
646
+ return ["read"]
646
647
  elif action == "write":
647
- return ["write:own"] # Use write:own instead of write
648
+ return ["write"]
648
649
  elif action == "delete":
649
- return ["delete:own"] # Use delete:own instead of delete
650
- elif "admin" in resource:
650
+ return ["delete"]
651
+ elif action == "admin":
651
652
  return ["admin"]
652
653
  else:
653
- return ["read:own"] # Use read:own instead of read
654
+ return ["read"]
654
655
 
655
656
 
656
657
  class StandaloneExampleTest:
657
658
  """Test class for standalone example."""
658
-
659
+
659
660
  def test_authentication(self):
660
661
  """Test authentication capabilities."""
661
662
  example = StandaloneSecurityExample()
662
663
  results = example.demonstrate_authentication()
663
-
664
+
664
665
  # Verify API key authentication works
665
666
  assert results["api_key_auth"]["success"] == True
666
667
  assert results["api_key_auth"]["username"] == "admin"
667
668
  assert "admin" in results["api_key_auth"]["roles"]
668
-
669
+
669
670
  # Verify JWT authentication works
670
671
  assert results["jwt_auth"]["success"] == True
671
672
  assert results["jwt_auth"]["username"] == "test_user"
672
-
673
+
673
674
  # Verify failed authentication is handled
674
675
  assert results["failed_auth"]["success"] == False
675
-
676
+
676
677
  print("✅ Authentication tests passed")
677
-
678
+
678
679
  def test_authorization(self):
679
680
  """Test authorization capabilities."""
680
681
  example = StandaloneSecurityExample()
681
682
  results = example.demonstrate_authorization()
682
-
683
+
683
684
  # Verify admin permissions work
684
685
  assert results["admin_permissions"]["success"] == True
685
-
686
+
686
687
  # Verify user permissions work
687
688
  assert results["user_permissions"]["success"] == True
688
-
689
+
689
690
  # Verify readonly permissions work
690
691
  assert results["readonly_permissions"]["success"] == True
691
-
692
+
692
693
  print("✅ Authorization tests passed")
693
-
694
+
694
695
  def test_rate_limiting(self):
695
696
  """Test rate limiting capabilities."""
696
697
  example = StandaloneSecurityExample()
697
698
  results = example.demonstrate_rate_limiting()
698
-
699
+
699
700
  # Verify rate limiting checks work
700
701
  assert len(results["rate_limit_checks"]) > 0
701
702
  assert results["rate_limit_checks"][0]["allowed"] == True
702
-
703
+
703
704
  print("✅ Rate limiting tests passed")
704
-
705
+
705
706
  def test_security_validation(self):
706
707
  """Test security validation capabilities."""
707
708
  example = StandaloneSecurityExample()
708
709
  results = example.demonstrate_security_validation()
709
-
710
+
710
711
  # Verify request validation works
711
712
  assert results["request_validation"]["success"] == True
712
-
713
+
713
714
  # Verify configuration validation works
714
715
  assert results["configuration_validation"]["success"] == True
715
-
716
+
716
717
  print("✅ Security validation tests passed")
717
-
718
+
718
719
  def test_security_monitoring(self):
719
720
  """Test security monitoring capabilities."""
720
721
  example = StandaloneSecurityExample()
721
722
  results = example.demonstrate_security_monitoring()
722
-
723
+
723
724
  # Verify security status works
724
725
  assert "status" in results["security_status"]
725
726
  assert "message" in results["security_status"]
726
-
727
+
727
728
  # Verify security metrics work
728
729
  assert "authentication_attempts" in results["security_metrics"]
729
-
730
+
730
731
  # Verify security audit works
731
732
  assert "authentication" in results["security_audit"]
732
-
733
+
733
734
  print("✅ Security monitoring tests passed")
734
735
 
735
736
 
@@ -737,43 +738,67 @@ def main():
737
738
  """Main function to run the standalone example."""
738
739
  print("\n🚀 MCP Security Framework - Standalone Example")
739
740
  print("=" * 60)
740
-
741
+
741
742
  # Create example instance
742
743
  example = StandaloneSecurityExample()
743
-
744
+
744
745
  # Run comprehensive demonstration
745
746
  results = example.run_comprehensive_demo()
746
-
747
+
747
748
  # Print results
748
749
  print("\n📊 COMPREHENSIVE DEMONSTRATION RESULTS")
749
750
  print("=" * 60)
750
751
  print(f"Framework: {results['framework']}")
751
752
  print(f"Version: {results['version']}")
752
753
  print(f"Timestamp: {results['timestamp']}")
753
-
754
+
754
755
  print("\n🔐 AUTHENTICATION RESULTS:")
755
- print(f" API Key: {'✅' if results['authentication']['api_key_auth']['success'] else '❌'}")
756
- print(f" JWT: {'✅' if results['authentication']['jwt_auth']['success'] else '❌'}")
757
- print(f" Certificate: {'✅' if results['authentication']['certificate_auth']['success'] else '❌'}")
758
-
756
+ print(
757
+ f" API Key: {'✅' if results['authentication']['api_key_auth']['success'] else '❌'}"
758
+ )
759
+ print(
760
+ f" JWT: {'✅' if results['authentication']['jwt_auth']['success'] else '❌'}"
761
+ )
762
+ print(
763
+ f" Certificate: {'✅' if results['authentication']['certificate_auth']['success'] else '❌'}"
764
+ )
765
+
759
766
  print("\n🔑 AUTHORIZATION RESULTS:")
760
- print(f" Admin Permissions: {'✅' if results['authorization']['admin_permissions']['success'] else '❌'}")
761
- print(f" User Permissions: {'✅' if results['authorization']['user_permissions']['success'] else '❌'}")
762
- print(f" Readonly Permissions: {'✅' if results['authorization']['readonly_permissions']['success'] else '❌'}")
763
-
767
+ print(
768
+ f" Admin Permissions: {'✅' if results['authorization']['admin_permissions']['success'] else '❌'}"
769
+ )
770
+ print(
771
+ f" User Permissions: {'✅' if results['authorization']['user_permissions']['success'] else '❌'}"
772
+ )
773
+ print(
774
+ f" Readonly Permissions: {'✅' if results['authorization']['readonly_permissions']['success'] else '❌'}"
775
+ )
776
+
764
777
  print("\n⚡ RATE LIMITING RESULTS:")
765
778
  print(f" Rate Limit Checks: {len(results['rate_limiting']['rate_limit_checks'])}")
766
- print(f" Rate Limit Exceeded: {'❌' if results['rate_limiting']['rate_limit_exceeded'] else '✅'}")
767
-
779
+ print(
780
+ f" Rate Limit Exceeded: {'❌' if results['rate_limiting']['rate_limit_exceeded'] else '✅'}"
781
+ )
782
+
768
783
  print("\n🔒 SECURITY VALIDATION RESULTS:")
769
- print(f" Request Validation: {'✅' if results['security_validation']['request_validation']['success'] else '❌'}")
770
- print(f" Configuration Validation: {'✅' if results['security_validation']['configuration_validation']['success'] else '❌'}")
771
-
784
+ print(
785
+ f" Request Validation: {'✅' if results['security_validation']['request_validation']['success'] else '❌'}"
786
+ )
787
+ print(
788
+ f" Configuration Validation: {'✅' if results['security_validation']['configuration_validation']['success'] else '❌'}"
789
+ )
790
+
772
791
  print("\n📊 SECURITY MONITORING RESULTS:")
773
- print(f" Security Status: {'✅' if 'ssl_enabled' in results['security_monitoring']['security_status'] else '❌'}")
774
- print(f" Security Metrics: {'✅' if 'authentication_attempts' in results['security_monitoring']['security_metrics'] else '❌'}")
775
- print(f" Security Audit: {'✅' if 'authentication' in results['security_monitoring']['security_audit'] else '❌'}")
776
-
792
+ print(
793
+ f" Security Status: {'✅' if 'ssl_enabled' in results['security_monitoring']['security_status'] else '❌'}"
794
+ )
795
+ print(
796
+ f" Security Metrics: {'✅' if 'authentication_attempts' in results['security_monitoring']['security_metrics'] else '❌'}"
797
+ )
798
+ print(
799
+ f" Security Audit: {'✅' if 'authentication' in results['security_monitoring']['security_audit'] else '❌'}"
800
+ )
801
+
777
802
  print("\n🎉 ALL FRAMEWORK CAPABILITIES DEMONSTRATED SUCCESSFULLY!")
778
803
  print("=" * 60)
779
804
 
@@ -787,6 +812,6 @@ if __name__ == "__main__":
787
812
  test.test_rate_limiting()
788
813
  test.test_security_validation()
789
814
  test.test_security_monitoring()
790
-
815
+
791
816
  print("\nExample Usage:")
792
817
  main()