mcp-security-framework 0.1.0__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 (76) hide show
  1. mcp_security_framework/__init__.py +96 -0
  2. mcp_security_framework/cli/__init__.py +18 -0
  3. mcp_security_framework/cli/cert_cli.py +511 -0
  4. mcp_security_framework/cli/security_cli.py +791 -0
  5. mcp_security_framework/constants.py +209 -0
  6. mcp_security_framework/core/__init__.py +61 -0
  7. mcp_security_framework/core/auth_manager.py +1011 -0
  8. mcp_security_framework/core/cert_manager.py +1663 -0
  9. mcp_security_framework/core/permission_manager.py +735 -0
  10. mcp_security_framework/core/rate_limiter.py +602 -0
  11. mcp_security_framework/core/security_manager.py +943 -0
  12. mcp_security_framework/core/ssl_manager.py +735 -0
  13. mcp_security_framework/examples/__init__.py +75 -0
  14. mcp_security_framework/examples/django_example.py +615 -0
  15. mcp_security_framework/examples/fastapi_example.py +472 -0
  16. mcp_security_framework/examples/flask_example.py +506 -0
  17. mcp_security_framework/examples/gateway_example.py +803 -0
  18. mcp_security_framework/examples/microservice_example.py +690 -0
  19. mcp_security_framework/examples/standalone_example.py +576 -0
  20. mcp_security_framework/middleware/__init__.py +250 -0
  21. mcp_security_framework/middleware/auth_middleware.py +292 -0
  22. mcp_security_framework/middleware/fastapi_auth_middleware.py +447 -0
  23. mcp_security_framework/middleware/fastapi_middleware.py +757 -0
  24. mcp_security_framework/middleware/flask_auth_middleware.py +465 -0
  25. mcp_security_framework/middleware/flask_middleware.py +591 -0
  26. mcp_security_framework/middleware/mtls_middleware.py +439 -0
  27. mcp_security_framework/middleware/rate_limit_middleware.py +403 -0
  28. mcp_security_framework/middleware/security_middleware.py +507 -0
  29. mcp_security_framework/schemas/__init__.py +109 -0
  30. mcp_security_framework/schemas/config.py +694 -0
  31. mcp_security_framework/schemas/models.py +709 -0
  32. mcp_security_framework/schemas/responses.py +686 -0
  33. mcp_security_framework/tests/__init__.py +0 -0
  34. mcp_security_framework/utils/__init__.py +121 -0
  35. mcp_security_framework/utils/cert_utils.py +525 -0
  36. mcp_security_framework/utils/crypto_utils.py +475 -0
  37. mcp_security_framework/utils/validation_utils.py +571 -0
  38. mcp_security_framework-0.1.0.dist-info/METADATA +411 -0
  39. mcp_security_framework-0.1.0.dist-info/RECORD +76 -0
  40. mcp_security_framework-0.1.0.dist-info/WHEEL +5 -0
  41. mcp_security_framework-0.1.0.dist-info/entry_points.txt +3 -0
  42. mcp_security_framework-0.1.0.dist-info/top_level.txt +2 -0
  43. tests/__init__.py +0 -0
  44. tests/test_cli/__init__.py +0 -0
  45. tests/test_cli/test_cert_cli.py +379 -0
  46. tests/test_cli/test_security_cli.py +657 -0
  47. tests/test_core/__init__.py +0 -0
  48. tests/test_core/test_auth_manager.py +582 -0
  49. tests/test_core/test_cert_manager.py +795 -0
  50. tests/test_core/test_permission_manager.py +395 -0
  51. tests/test_core/test_rate_limiter.py +626 -0
  52. tests/test_core/test_security_manager.py +841 -0
  53. tests/test_core/test_ssl_manager.py +532 -0
  54. tests/test_examples/__init__.py +8 -0
  55. tests/test_examples/test_fastapi_example.py +264 -0
  56. tests/test_examples/test_flask_example.py +238 -0
  57. tests/test_examples/test_standalone_example.py +292 -0
  58. tests/test_integration/__init__.py +0 -0
  59. tests/test_integration/test_auth_flow.py +502 -0
  60. tests/test_integration/test_certificate_flow.py +527 -0
  61. tests/test_integration/test_fastapi_integration.py +341 -0
  62. tests/test_integration/test_flask_integration.py +398 -0
  63. tests/test_integration/test_standalone_integration.py +493 -0
  64. tests/test_middleware/__init__.py +0 -0
  65. tests/test_middleware/test_fastapi_middleware.py +523 -0
  66. tests/test_middleware/test_flask_middleware.py +582 -0
  67. tests/test_middleware/test_security_middleware.py +493 -0
  68. tests/test_schemas/__init__.py +0 -0
  69. tests/test_schemas/test_config.py +811 -0
  70. tests/test_schemas/test_models.py +879 -0
  71. tests/test_schemas/test_responses.py +1054 -0
  72. tests/test_schemas/test_serialization.py +493 -0
  73. tests/test_utils/__init__.py +0 -0
  74. tests/test_utils/test_cert_utils.py +510 -0
  75. tests/test_utils/test_crypto_utils.py +603 -0
  76. tests/test_utils/test_validation_utils.py +477 -0
@@ -0,0 +1,250 @@
1
+ """
2
+ MCP Security Framework Middleware Package
3
+
4
+ This package provides comprehensive security middleware implementations
5
+ for various web frameworks, including FastAPI, Flask, and others.
6
+
7
+ Key Features:
8
+ - Framework-agnostic base middleware
9
+ - Framework-specific implementations
10
+ - Specialized middleware components
11
+ - Factory functions for easy integration
12
+ - Comprehensive security processing
13
+
14
+ Modules:
15
+ security_middleware: Base security middleware class
16
+ fastapi_middleware: FastAPI-specific implementation
17
+ flask_middleware: Flask-specific implementation
18
+ auth_middleware: Authentication-only middleware
19
+ rate_limit_middleware: Rate limiting-only middleware
20
+ mtls_middleware: mTLS-specific middleware
21
+
22
+ Factory Functions:
23
+ create_fastapi_security_middleware: Create FastAPI security middleware
24
+ create_flask_security_middleware: Create Flask security middleware
25
+ create_auth_middleware: Create authentication-only middleware
26
+ create_rate_limit_middleware: Create rate limiting middleware
27
+ create_mtls_middleware: Create mTLS middleware
28
+
29
+ Author: MCP Security Team
30
+ Version: 1.0.0
31
+ License: MIT
32
+ """
33
+
34
+ from typing import Optional
35
+
36
+ from .security_middleware import SecurityMiddleware, SecurityMiddlewareError
37
+ from .fastapi_middleware import FastAPISecurityMiddleware, FastAPIMiddlewareError
38
+ from .flask_middleware import FlaskSecurityMiddleware, FlaskMiddlewareError
39
+ from .auth_middleware import AuthMiddleware, AuthMiddlewareError
40
+ from .rate_limit_middleware import RateLimitMiddleware, RateLimitMiddlewareError
41
+ from .mtls_middleware import MTLSMiddleware, MTLSMiddlewareError
42
+
43
+ from ..core.security_manager import SecurityManager
44
+ from ..schemas.config import SecurityConfig
45
+
46
+
47
+ def create_fastapi_security_middleware(
48
+ security_manager: SecurityManager
49
+ ) -> FastAPISecurityMiddleware:
50
+ """
51
+ Create FastAPI security middleware.
52
+
53
+ Args:
54
+ security_manager (SecurityManager): Security manager instance
55
+
56
+ Returns:
57
+ FastAPISecurityMiddleware: Configured FastAPI security middleware
58
+
59
+ Raises:
60
+ FastAPIMiddlewareError: If middleware creation fails
61
+
62
+ Example:
63
+ >>> from mcp_security_framework.middleware import create_fastapi_security_middleware
64
+ >>> from fastapi import FastAPI
65
+ >>>
66
+ >>> app = FastAPI()
67
+ >>> security_manager = SecurityManager(config)
68
+ >>> middleware = create_fastapi_security_middleware(security_manager)
69
+ >>> app.add_middleware(middleware)
70
+ """
71
+ return FastAPISecurityMiddleware(security_manager)
72
+
73
+
74
+ def create_flask_security_middleware(
75
+ security_manager: SecurityManager
76
+ ) -> FlaskSecurityMiddleware:
77
+ """
78
+ Create Flask security middleware.
79
+
80
+ Args:
81
+ security_manager (SecurityManager): Security manager instance
82
+
83
+ Returns:
84
+ FlaskSecurityMiddleware: Configured Flask security middleware
85
+
86
+ Raises:
87
+ FlaskMiddlewareError: If middleware creation fails
88
+
89
+ Example:
90
+ >>> from mcp_security_framework.middleware import create_flask_security_middleware
91
+ >>> from flask import Flask
92
+ >>>
93
+ >>> app = Flask(__name__)
94
+ >>> security_manager = SecurityManager(config)
95
+ >>> middleware = create_flask_security_middleware(security_manager)
96
+ >>> app.wsgi_app = middleware(app.wsgi_app)
97
+ """
98
+ return FlaskSecurityMiddleware(security_manager)
99
+
100
+
101
+ def create_auth_middleware(
102
+ security_manager: SecurityManager,
103
+ framework: str = "fastapi",
104
+ cache_ttl: int = 300
105
+ ) -> AuthMiddleware:
106
+ """
107
+ Create authentication-only middleware for specified framework.
108
+
109
+ Args:
110
+ security_manager (SecurityManager): Security manager instance
111
+ framework (str): Target framework ("fastapi", "flask", "django")
112
+ cache_ttl (int): Cache TTL in seconds (default: 300)
113
+
114
+ Returns:
115
+ AuthMiddleware: Framework-specific authentication middleware
116
+
117
+ Raises:
118
+ ValueError: If framework is not supported
119
+ AuthMiddlewareError: If middleware creation fails
120
+
121
+ Example:
122
+ >>> from mcp_security_framework.middleware import create_auth_middleware
123
+ >>>
124
+ >>> security_manager = SecurityManager(config)
125
+ >>> auth_middleware = create_auth_middleware(security_manager, "fastapi")
126
+ """
127
+ if framework == "fastapi":
128
+ from .fastapi_auth_middleware import FastAPIAuthMiddleware
129
+ return FastAPIAuthMiddleware(security_manager.config, security_manager)
130
+ elif framework == "flask":
131
+ from .flask_auth_middleware import FlaskAuthMiddleware
132
+ return FlaskAuthMiddleware(security_manager.config, security_manager)
133
+ else:
134
+ raise ValueError(f"Unsupported framework: {framework}")
135
+
136
+
137
+ def create_rate_limit_middleware(
138
+ security_manager: SecurityManager
139
+ ) -> RateLimitMiddleware:
140
+ """
141
+ Create rate limiting middleware.
142
+
143
+ Args:
144
+ security_manager (SecurityManager): Security manager instance
145
+
146
+ Returns:
147
+ RateLimitMiddleware: Configured rate limiting middleware
148
+
149
+ Raises:
150
+ RateLimitMiddlewareError: If middleware creation fails
151
+
152
+ Example:
153
+ >>> from mcp_security_framework.middleware import create_rate_limit_middleware
154
+ >>>
155
+ >>> security_manager = SecurityManager(config)
156
+ >>> rate_limit_middleware = create_rate_limit_middleware(security_manager)
157
+ """
158
+ return RateLimitMiddleware(security_manager)
159
+
160
+
161
+ def create_mtls_middleware(
162
+ security_manager: SecurityManager
163
+ ) -> MTLSMiddleware:
164
+ """
165
+ Create mTLS middleware.
166
+
167
+ Args:
168
+ security_manager (SecurityManager): Security manager instance
169
+
170
+ Returns:
171
+ MTLSMiddleware: Configured mTLS middleware
172
+
173
+ Raises:
174
+ MTLSMiddlewareError: If middleware creation fails
175
+
176
+ Example:
177
+ >>> from mcp_security_framework.middleware import create_mtls_middleware
178
+ >>>
179
+ >>> security_manager = SecurityManager(config)
180
+ >>> mtls_middleware = create_mtls_middleware(security_manager)
181
+ """
182
+ return MTLSMiddleware(security_manager)
183
+
184
+
185
+ def create_security_middleware(
186
+ security_manager: SecurityManager,
187
+ framework: str = "fastapi"
188
+ ) -> SecurityMiddleware:
189
+ """
190
+ Create security middleware for specified framework.
191
+
192
+ Args:
193
+ security_manager (SecurityManager): Security manager instance
194
+ framework (str): Target framework ("fastapi", "flask", etc.)
195
+
196
+ Returns:
197
+ SecurityMiddleware: Configured security middleware
198
+
199
+ Raises:
200
+ SecurityMiddlewareError: If middleware creation fails
201
+
202
+ Example:
203
+ >>> from mcp_security_framework.middleware import create_security_middleware
204
+ >>>
205
+ >>> security_manager = SecurityManager(config)
206
+ >>> middleware = create_security_middleware(security_manager, "fastapi")
207
+ """
208
+ framework = framework.lower()
209
+
210
+ if framework == "fastapi":
211
+ return create_fastapi_security_middleware(security_manager)
212
+ elif framework == "flask":
213
+ return create_flask_security_middleware(security_manager)
214
+ else:
215
+ raise SecurityMiddlewareError(
216
+ f"Unsupported framework: {framework}",
217
+ error_code=-32041
218
+ )
219
+
220
+
221
+ # Export all middleware classes and exceptions
222
+ __all__ = [
223
+ # Base classes
224
+ "SecurityMiddleware",
225
+ "SecurityMiddlewareError",
226
+
227
+ # FastAPI middleware
228
+ "FastAPISecurityMiddleware",
229
+ "FastAPIMiddlewareError",
230
+
231
+ # Flask middleware
232
+ "FlaskSecurityMiddleware",
233
+ "FlaskMiddlewareError",
234
+
235
+ # Specialized middleware
236
+ "AuthMiddleware",
237
+ "AuthMiddlewareError",
238
+ "RateLimitMiddleware",
239
+ "RateLimitMiddlewareError",
240
+ "MTLSMiddleware",
241
+ "MTLSMiddlewareError",
242
+
243
+ # Factory functions
244
+ "create_fastapi_security_middleware",
245
+ "create_flask_security_middleware",
246
+ "create_auth_middleware",
247
+ "create_rate_limit_middleware",
248
+ "create_mtls_middleware",
249
+ "create_security_middleware",
250
+ ]
@@ -0,0 +1,292 @@
1
+ """
2
+ Authentication Middleware Module
3
+
4
+ This module provides specialized authentication-only middleware that
5
+ focuses solely on user authentication without authorization checks.
6
+
7
+ Key Features:
8
+ - Authentication-only processing
9
+ - Multiple authentication method support
10
+ - Authentication result caching
11
+ - Authentication event logging
12
+ - Framework-agnostic design
13
+
14
+ Classes:
15
+ AuthMiddleware: Authentication-only middleware
16
+ AuthMiddlewareError: Authentication middleware-specific error exception
17
+
18
+ Author: MCP Security Team
19
+ Version: 1.0.0
20
+ License: MIT
21
+ """
22
+
23
+ import logging
24
+ from abc import ABC, abstractmethod
25
+ from typing import Any, Dict, List, Optional
26
+
27
+ from .security_middleware import SecurityMiddleware, SecurityMiddlewareError
28
+ from ..schemas.models import AuthResult
29
+
30
+
31
+ class AuthMiddlewareError(SecurityMiddlewareError):
32
+ """Raised when authentication middleware encounters an error."""
33
+
34
+ def __init__(self, message: str, error_code: int = -32032):
35
+ self.message = message
36
+ self.error_code = error_code
37
+ super().__init__(self.message)
38
+
39
+
40
+ class AuthMiddleware(SecurityMiddleware):
41
+ """
42
+ Authentication-Only Middleware Class
43
+
44
+ This class provides authentication-only middleware that focuses
45
+ solely on user authentication without performing authorization
46
+ checks. It's useful for scenarios where authentication and
47
+ authorization are handled separately.
48
+
49
+ The AuthMiddleware implements:
50
+ - Authentication-only request processing
51
+ - Multiple authentication method support
52
+ - Authentication result caching
53
+ - Authentication event logging
54
+ - Framework-agnostic design
55
+
56
+ Key Responsibilities:
57
+ - Process requests through authentication pipeline only
58
+ - Handle multiple authentication methods
59
+ - Cache authentication results for performance
60
+ - Log authentication events and failures
61
+ - Provide authentication status to downstream components
62
+
63
+ Attributes:
64
+ Inherits all attributes from SecurityMiddleware
65
+ _auth_cache (Dict): Cache for authentication results
66
+ _cache_ttl (int): Time-to-live for cached results
67
+
68
+ Example:
69
+ >>> from mcp_security_framework.middleware import AuthMiddleware
70
+ >>>
71
+ >>> security_manager = SecurityManager(config)
72
+ >>> auth_middleware = AuthMiddleware(security_manager)
73
+ >>> app.add_middleware(auth_middleware)
74
+
75
+ Note:
76
+ This middleware only handles authentication. Authorization
77
+ should be handled separately by other middleware or
78
+ application logic.
79
+ """
80
+
81
+ def __init__(self, security_manager, cache_ttl: int = 300):
82
+ """
83
+ Initialize Authentication-Only Middleware.
84
+
85
+ Args:
86
+ security_manager: Security manager instance containing
87
+ all security components and configuration.
88
+ cache_ttl (int): Time-to-live for cached authentication
89
+ results in seconds. Defaults to 300 seconds (5 minutes).
90
+
91
+ Raises:
92
+ AuthMiddlewareError: If initialization fails
93
+ """
94
+ super().__init__(security_manager)
95
+ self.logger = logging.getLogger(f"{__name__}.{self.__class__.__name__}")
96
+ self._cache_ttl = cache_ttl
97
+
98
+ self.logger.info(
99
+ "Authentication middleware initialized",
100
+ extra={"cache_ttl": cache_ttl}
101
+ )
102
+
103
+ @abstractmethod
104
+ def __call__(self, request: Any, call_next: Any) -> Any:
105
+ """
106
+ Process request through authentication middleware.
107
+
108
+ This method implements the authentication-only processing
109
+ pipeline, focusing solely on user authentication.
110
+
111
+ Args:
112
+ request: Framework-specific request object
113
+ call_next: Framework-specific call_next function
114
+
115
+ Returns:
116
+ Framework-specific response object
117
+
118
+ Raises:
119
+ AuthMiddlewareError: If authentication processing fails
120
+ """
121
+ pass
122
+
123
+ def _authenticate_only(self, request: Any) -> AuthResult:
124
+ """
125
+ Perform authentication-only processing.
126
+
127
+ This method handles authentication without authorization
128
+ checks, making it suitable for scenarios where auth and
129
+ authz are separated.
130
+
131
+ Args:
132
+ request: Framework-specific request object
133
+
134
+ Returns:
135
+ AuthResult: Authentication result with user information
136
+
137
+ Raises:
138
+ AuthMiddlewareError: If authentication process fails
139
+ """
140
+ try:
141
+ if not self.config.auth.enabled:
142
+ return AuthResult(
143
+ is_valid=True,
144
+ status=AuthStatus.SUCCESS,
145
+ username="anonymous",
146
+ roles=[],
147
+ auth_method=None
148
+ )
149
+
150
+ # Check cache first
151
+ cache_key = self._get_cache_key(request)
152
+ if cache_key in self._auth_cache:
153
+ cached_result = self._auth_cache[cache_key]
154
+ if self._is_cache_valid(cached_result):
155
+ self.logger.debug(
156
+ "Using cached authentication result",
157
+ extra={"username": cached_result.username}
158
+ )
159
+ return cached_result
160
+
161
+ # Try each authentication method in order
162
+ for method in self.config.auth.methods:
163
+ auth_result = self._try_auth_method(request, method)
164
+ if auth_result.is_valid:
165
+ # Cache successful authentication result
166
+ self._cache_auth_result(cache_key, auth_result)
167
+
168
+ self.logger.info(
169
+ "Authentication successful",
170
+ extra={
171
+ "username": auth_result.username,
172
+ "auth_method": auth_result.auth_method,
173
+ "user_roles": auth_result.roles
174
+ }
175
+ )
176
+ return auth_result
177
+
178
+ # All authentication methods failed
179
+ self.logger.warning(
180
+ "All authentication methods failed",
181
+ extra={"auth_methods": self.config.auth.methods}
182
+ )
183
+
184
+ failed_result = AuthResult(
185
+ is_valid=False,
186
+ status=AuthStatus.FAILED,
187
+ username=None,
188
+ roles=[],
189
+ auth_method=None,
190
+ error_code=-32033,
191
+ error_message="All authentication methods failed"
192
+ )
193
+
194
+ # Cache failed result briefly to prevent repeated attempts
195
+ self._cache_auth_result(cache_key, failed_result, ttl=60)
196
+ return failed_result
197
+
198
+ except Exception as e:
199
+ self.logger.error(
200
+ "Authentication process failed",
201
+ extra={"error": str(e)},
202
+ exc_info=True
203
+ )
204
+ raise AuthMiddlewareError(
205
+ f"Authentication process failed: {str(e)}",
206
+ error_code=-32034
207
+ )
208
+
209
+ def _get_cache_key(self, request: Any) -> str:
210
+ """
211
+ Generate cache key for authentication result.
212
+
213
+ Args:
214
+ request: Framework-specific request object
215
+
216
+ Returns:
217
+ str: Cache key for authentication result
218
+ """
219
+ # Use a combination of IP and user agent for cache key
220
+ ip = self._get_rate_limit_identifier(request)
221
+ user_agent = self._get_user_agent(request)
222
+ return f"auth:{ip}:{user_agent}"
223
+
224
+ def _is_cache_valid(self, auth_result: AuthResult) -> bool:
225
+ """
226
+ Check if cached authentication result is still valid.
227
+
228
+ Args:
229
+ auth_result (AuthResult): Cached authentication result
230
+
231
+ Returns:
232
+ bool: True if cache is valid, False otherwise
233
+ """
234
+ # For now, assume cache is valid if it exists
235
+ # In a real implementation, you might check timestamps
236
+ return True
237
+
238
+ def _cache_auth_result(self, cache_key: str, auth_result: AuthResult, ttl: int = None) -> None:
239
+ """
240
+ Cache authentication result.
241
+
242
+ Args:
243
+ cache_key (str): Cache key for the result
244
+ auth_result (AuthResult): Authentication result to cache
245
+ ttl (int): Time-to-live in seconds (optional)
246
+ """
247
+ if ttl is None:
248
+ ttl = self._cache_ttl
249
+
250
+ # In a real implementation, you would store with timestamp
251
+ self._auth_cache[cache_key] = auth_result
252
+
253
+ def _clear_auth_cache(self) -> None:
254
+ """Clear all cached authentication results."""
255
+ self._auth_cache.clear()
256
+ self.logger.info("Authentication cache cleared")
257
+
258
+ def _get_user_agent(self, request: Any) -> str:
259
+ """
260
+ Get user agent from request.
261
+
262
+ Args:
263
+ request: Framework-specific request object
264
+
265
+ Returns:
266
+ str: User agent string
267
+ """
268
+ # This should be implemented by framework-specific subclasses
269
+ return "unknown"
270
+
271
+ def _log_auth_event(self, event_type: str, auth_result: AuthResult,
272
+ request_details: Dict[str, Any]) -> None:
273
+ """
274
+ Log authentication event.
275
+
276
+ Args:
277
+ event_type (str): Type of authentication event
278
+ auth_result (AuthResult): Authentication result
279
+ request_details (Dict[str, Any]): Request details
280
+ """
281
+ self.logger.info(
282
+ f"Authentication event: {event_type}",
283
+ extra={
284
+ "event_type": event_type,
285
+ "username": auth_result.username,
286
+ "auth_method": auth_result.auth_method,
287
+ "is_valid": auth_result.is_valid,
288
+ "error_code": auth_result.error_code,
289
+ "error_message": auth_result.error_message,
290
+ **request_details
291
+ }
292
+ )