mcp-security-framework 2.2.0__tar.gz → 2.2.1__tar.gz
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.
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/PKG-INFO +1 -1
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/__init__.py +1 -1
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/core/ssl_manager.py +24 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/examples/protected_keys_example.py +29 -12
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/schemas/config.py +23 -6
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework.egg-info/PKG-INFO +1 -1
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/pyproject.toml +1 -1
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/LICENSE +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/README.md +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/cli/__init__.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/cli/cert_cli.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/cli/security_cli.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/constants.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/core/__init__.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/core/adapter_wrapper.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/core/audit_logger.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/core/auth_manager.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/core/cert_manager.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/core/permission_manager.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/core/rate_limiter.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/core/security_adapter.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/core/security_manager.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/examples/__init__.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/examples/adapter_example.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/examples/cert_inspection_example.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/examples/comprehensive_example.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/examples/crl_retrieval_example.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/examples/fastapi_example.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/examples/flask_example.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/examples/gateway_example.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/examples/microservice_example.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/examples/standalone_example.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/middleware/__init__.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/middleware/auth_middleware.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/middleware/fastapi_auth_middleware.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/middleware/fastapi_middleware.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/middleware/flask_auth_middleware.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/middleware/flask_middleware.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/middleware/mtls_middleware.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/middleware/rate_limit_middleware.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/middleware/security_middleware.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/schemas/__init__.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/schemas/models.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/schemas/operation_context.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/schemas/responses.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/utils/__init__.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/utils/cert_utils.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/utils/crl_client.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/utils/crypto_utils.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/utils/datetime_compat.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/utils/validation_utils.py +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework.egg-info/SOURCES.txt +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework.egg-info/dependency_links.txt +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework.egg-info/entry_points.txt +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework.egg-info/requires.txt +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework.egg-info/top_level.txt +0 -0
- {mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-security-framework
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.1
|
|
4
4
|
Summary: Universal security framework for microservices with SSL/TLS, authentication, authorization, and rate limiting. Added extensible security adapter system for custom operation validation, structured audit logging, and operation context support. Comprehensive test coverage with 1104+ tests. Fully backward compatible. Requires cryptography>=42.0.0 for certificate operations.
|
|
5
5
|
Author-email: Vasiliy Zdanovskiy <vasilyvz@gmail.com>
|
|
6
6
|
Maintainer-email: Vasiliy Zdanovskiy <vasilyvz@gmail.com>
|
|
@@ -235,10 +235,22 @@ class SSLManager:
|
|
|
235
235
|
|
|
236
236
|
# Validate required files or data
|
|
237
237
|
if cert_data is None and not cert_file:
|
|
238
|
+
if self.config.material_from_memory:
|
|
239
|
+
raise SSLConfigurationError(
|
|
240
|
+
"material_from_memory=True but cert_data was not supplied; "
|
|
241
|
+
"provide cert_data as PEM bytes or "
|
|
242
|
+
"set material_from_memory=False"
|
|
243
|
+
)
|
|
238
244
|
raise SSLConfigurationError(
|
|
239
245
|
"Server certificate file or data is required"
|
|
240
246
|
)
|
|
241
247
|
if key_data is None and not key_file:
|
|
248
|
+
if self.config.material_from_memory:
|
|
249
|
+
raise SSLConfigurationError(
|
|
250
|
+
"material_from_memory=True but key_data was not supplied; "
|
|
251
|
+
"provide key_data as PEM bytes or "
|
|
252
|
+
"set material_from_memory=False"
|
|
253
|
+
)
|
|
242
254
|
raise SSLConfigurationError(
|
|
243
255
|
"Server private key file or data is required"
|
|
244
256
|
)
|
|
@@ -423,6 +435,18 @@ class SSLManager:
|
|
|
423
435
|
verify_mode = verify_mode or self.config.verify_mode
|
|
424
436
|
min_version = min_version or self.config.min_tls_version
|
|
425
437
|
|
|
438
|
+
# Validate that material_from_memory promises are kept
|
|
439
|
+
if cert_data is None and self.config.material_from_memory:
|
|
440
|
+
raise SSLConfigurationError(
|
|
441
|
+
"material_from_memory=True but cert_data was not supplied; "
|
|
442
|
+
"provide cert_data as PEM bytes or set material_from_memory=False"
|
|
443
|
+
)
|
|
444
|
+
if key_data is None and self.config.material_from_memory:
|
|
445
|
+
raise SSLConfigurationError(
|
|
446
|
+
"material_from_memory=True but key_data was not supplied; "
|
|
447
|
+
"provide key_data as PEM bytes or set material_from_memory=False"
|
|
448
|
+
)
|
|
449
|
+
|
|
426
450
|
# Check cache (only for file-based contexts)
|
|
427
451
|
cache_key = None
|
|
428
452
|
if cert_data is None and key_data is None:
|
|
@@ -57,7 +57,7 @@ def _build_certificate_config() -> CertificateConfig:
|
|
|
57
57
|
|
|
58
58
|
def _build_ssl_config() -> SSLConfig:
|
|
59
59
|
"""Build a temporary SSL configuration for this example."""
|
|
60
|
-
return SSLConfig(enabled=True, verify=False)
|
|
60
|
+
return SSLConfig(enabled=True, verify=False, material_from_memory=False)
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
def _create_encrypted_key(password: str) -> tuple:
|
|
@@ -88,7 +88,6 @@ def main() -> None:
|
|
|
88
88
|
print("=" * 70)
|
|
89
89
|
|
|
90
90
|
cert_config = _build_certificate_config()
|
|
91
|
-
ssl_config = _build_ssl_config()
|
|
92
91
|
|
|
93
92
|
# Capability 1: Create a root CA with a passphrase-protected key
|
|
94
93
|
print("\n1. Creating a root CA with a passphrase-protected private key...")
|
|
@@ -182,18 +181,24 @@ def main() -> None:
|
|
|
182
181
|
else:
|
|
183
182
|
raise
|
|
184
183
|
|
|
185
|
-
# Capability 5: Create SSL context from in-memory
|
|
184
|
+
# Capability 5: Create SSL context from in-memory bytes (SECURE config)
|
|
186
185
|
print("\n5. Creating SSL context from in-memory certificate and key bytes...")
|
|
187
186
|
with open(server_pair.certificate_path, "rb") as f:
|
|
188
187
|
cert_bytes = f.read()
|
|
189
188
|
with open(server_pair.private_key_path, "rb") as f:
|
|
190
189
|
key_bytes = f.read()
|
|
191
190
|
|
|
192
|
-
|
|
191
|
+
secure_ssl_config = SSLConfig(enabled=True, verify=True, material_from_memory=True)
|
|
192
|
+
print(
|
|
193
|
+
f" Config: enabled={secure_ssl_config.enabled}, "
|
|
194
|
+
f"verify={secure_ssl_config.verify}, "
|
|
195
|
+
f"material_from_memory={secure_ssl_config.material_from_memory}"
|
|
196
|
+
)
|
|
197
|
+
ssl_manager = SSLManager(secure_ssl_config)
|
|
193
198
|
_ = ssl_manager.create_server_context(cert_data=cert_bytes, key_data=key_bytes)
|
|
194
|
-
print(" SSL context created from in-memory bytes: SUCCESS")
|
|
199
|
+
print(" SSL context created from in-memory bytes (SECURE): SUCCESS")
|
|
195
200
|
|
|
196
|
-
# Capability 6: Create SSL context from encrypted in-memory key
|
|
201
|
+
# Capability 6: Create SSL context from encrypted in-memory key (SECURE)
|
|
197
202
|
print("\n6. Creating SSL context from encrypted in-memory key with passphrase...")
|
|
198
203
|
# Read the original server key and encrypt it
|
|
199
204
|
with open(server_pair.private_key_path, "rb") as f:
|
|
@@ -212,13 +217,21 @@ def main() -> None:
|
|
|
212
217
|
)
|
|
213
218
|
|
|
214
219
|
ssl_config_with_password = SSLConfig(
|
|
215
|
-
enabled=True,
|
|
220
|
+
enabled=True,
|
|
221
|
+
verify=True,
|
|
222
|
+
material_from_memory=True,
|
|
223
|
+
key_password="test_pass",
|
|
224
|
+
)
|
|
225
|
+
print(
|
|
226
|
+
f" Config: enabled={ssl_config_with_password.enabled}, "
|
|
227
|
+
f"verify={ssl_config_with_password.verify}, "
|
|
228
|
+
f"material_from_memory={ssl_config_with_password.material_from_memory}"
|
|
216
229
|
)
|
|
217
230
|
ssl_manager_with_pass = SSLManager(ssl_config_with_password)
|
|
218
231
|
_ = ssl_manager_with_pass.create_server_context(
|
|
219
232
|
cert_data=cert_bytes, key_data=encrypted_server_key
|
|
220
233
|
)
|
|
221
|
-
print(" SSL context created from encrypted in-memory key: SUCCESS")
|
|
234
|
+
print(" SSL context created from encrypted in-memory key (SECURE): SUCCESS")
|
|
222
235
|
|
|
223
236
|
# Capability 7: Try cert_data without key_data (should fail)
|
|
224
237
|
print("\n7. Attempting to supply cert_data without key_data (should fail)...")
|
|
@@ -231,7 +244,7 @@ def main() -> None:
|
|
|
231
244
|
else:
|
|
232
245
|
raise
|
|
233
246
|
|
|
234
|
-
# Capability 8: Create
|
|
247
|
+
# Capability 8: Create CA workflow from PEM bytes (no disk files) SECURE config
|
|
235
248
|
print("\n8. Running complete CA workflow from PEM bytes (no disk CA files)...")
|
|
236
249
|
|
|
237
250
|
# Create a root CA for this demonstration
|
|
@@ -283,9 +296,13 @@ def main() -> None:
|
|
|
283
296
|
encryption_algorithm=serialization.NoEncryption(),
|
|
284
297
|
)
|
|
285
298
|
|
|
286
|
-
# Now use those bytes through the SSL context
|
|
287
|
-
|
|
288
|
-
|
|
299
|
+
# Now use those bytes through the SSL context with secure config
|
|
300
|
+
secure_ca_config = SSLConfig(enabled=True, verify=True, material_from_memory=True)
|
|
301
|
+
secure_ca_manager = SSLManager(secure_ca_config)
|
|
302
|
+
_ = secure_ca_manager.create_server_context(
|
|
303
|
+
cert_data=ca_cert_pem, key_data=ca_key_pem
|
|
304
|
+
)
|
|
305
|
+
print(" CA workflow completed entirely in memory (SECURE): SUCCESS")
|
|
289
306
|
|
|
290
307
|
msg = "ALL PROTECTED KEY AND IN-MEMORY MATERIAL CAPABILITIES "
|
|
291
308
|
msg += "DEMONSTRATED SUCCESSFULLY"
|
|
@@ -93,6 +93,7 @@ class SSLConfig(BaseModel):
|
|
|
93
93
|
client_cert_file: Path to client certificate file
|
|
94
94
|
client_key_file: Path to client private key file
|
|
95
95
|
client_key_password: Passphrase for client private key file
|
|
96
|
+
material_from_memory: Certificate and key supplied as PEM bytes, not files
|
|
96
97
|
verify_mode: SSL verification mode
|
|
97
98
|
min_tls_version: Minimum TLS version to support
|
|
98
99
|
max_tls_version: Maximum TLS version to support
|
|
@@ -132,6 +133,13 @@ class SSLConfig(BaseModel):
|
|
|
132
133
|
default=None, description="Passphrase for client private key file"
|
|
133
134
|
)
|
|
134
135
|
verify: bool = Field(default=True, description="Whether to verify SSL certificates")
|
|
136
|
+
material_from_memory: bool = Field(
|
|
137
|
+
default=False,
|
|
138
|
+
description=(
|
|
139
|
+
"Certificate and key are supplied to the context builders as PEM "
|
|
140
|
+
"bytes rather than named by cert_file/key_file"
|
|
141
|
+
),
|
|
142
|
+
)
|
|
135
143
|
verify_mode: str = Field(
|
|
136
144
|
default="CERT_REQUIRED", description="SSL verification mode"
|
|
137
145
|
)
|
|
@@ -223,12 +231,21 @@ class SSLConfig(BaseModel):
|
|
|
223
231
|
def validate_ssl_configuration(self) -> Self:
|
|
224
232
|
"""Validate SSL configuration consistency."""
|
|
225
233
|
if self.enabled:
|
|
226
|
-
# If verify is disabled, don't require certificate files
|
|
227
|
-
if self.verify and
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
234
|
+
# If verify is disabled, don't require certificate files or memory flag
|
|
235
|
+
if self.verify and not self.material_from_memory:
|
|
236
|
+
# material_from_memory=False means files are required.
|
|
237
|
+
# material_from_memory=True means bytes will be supplied at call time,
|
|
238
|
+
# so files are not checked here. This keeps the early error for the
|
|
239
|
+
# common case — everyone who configures file paths — and makes the
|
|
240
|
+
# intent visible in the configuration itself, which is where an auditor
|
|
241
|
+
# will look. An explicit opt-in prevents the false positive that occurs
|
|
242
|
+
# when someone sets verify=True in secure-by-default code but hasn't yet
|
|
243
|
+
# assembled the bytes.
|
|
244
|
+
if not self.cert_file or not self.key_file:
|
|
245
|
+
raise ValueError(
|
|
246
|
+
"SSL enabled with verification but certificate and key "
|
|
247
|
+
"files are required"
|
|
248
|
+
)
|
|
232
249
|
return self
|
|
233
250
|
|
|
234
251
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-security-framework
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.1
|
|
4
4
|
Summary: Universal security framework for microservices with SSL/TLS, authentication, authorization, and rate limiting. Added extensible security adapter system for custom operation validation, structured audit logging, and operation context support. Comprehensive test coverage with 1104+ tests. Fully backward compatible. Requires cryptography>=42.0.0 for certificate operations.
|
|
5
5
|
Author-email: Vasiliy Zdanovskiy <vasilyvz@gmail.com>
|
|
6
6
|
Maintainer-email: Vasiliy Zdanovskiy <vasilyvz@gmail.com>
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "mcp-security-framework"
|
|
7
|
-
version = "2.2.
|
|
7
|
+
version = "2.2.1"
|
|
8
8
|
description = "Universal security framework for microservices with SSL/TLS, authentication, authorization, and rate limiting. Added extensible security adapter system for custom operation validation, structured audit logging, and operation context support. Comprehensive test coverage with 1104+ tests. Fully backward compatible. Requires cryptography>=42.0.0 for certificate operations."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
File without changes
|
|
File without changes
|
{mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/cli/__init__.py
RENAMED
|
File without changes
|
{mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/cli/cert_cli.py
RENAMED
|
File without changes
|
|
File without changes
|
{mcp_security_framework-2.2.0 → mcp_security_framework-2.2.1}/mcp_security_framework/constants.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|