mcp-security-framework 2.3.0__tar.gz → 2.3.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.3.0 → mcp_security_framework-2.3.1}/PKG-INFO +5 -1
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/__init__.py +1 -1
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/core/cert_manager.py +18 -1
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/core/ssl_manager.py +1 -0
- mcp_security_framework-2.3.1/mcp_security_framework/examples/tls_certificate_regressions_example.py +142 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/middleware/fastapi_middleware.py +1 -1
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/schemas/config.py +19 -13
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework.egg-info/PKG-INFO +5 -1
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework.egg-info/SOURCES.txt +1 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework.egg-info/requires.txt +4 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/pyproject.toml +6 -2
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/LICENSE +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/README.md +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/cli/__init__.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/cli/cert_cli.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/cli/security_cli.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/constants.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/core/__init__.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/core/adapter_wrapper.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/core/audit_logger.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/core/auth_manager.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/core/permission_manager.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/core/rate_limiter.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/core/security_adapter.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/core/security_manager.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/examples/__init__.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/examples/adapter_example.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/examples/auth_methods_example.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/examples/cert_inspection_example.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/examples/certificate_roles_example.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/examples/comprehensive_example.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/examples/crl_retrieval_example.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/examples/fastapi_example.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/examples/flask_example.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/examples/gateway_example.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/examples/microservice_example.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/examples/protected_keys_example.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/examples/standalone_example.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/middleware/__init__.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/middleware/auth_middleware.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/middleware/fastapi_auth_middleware.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/middleware/flask_auth_middleware.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/middleware/flask_middleware.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/middleware/mtls_middleware.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/middleware/rate_limit_middleware.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/middleware/security_middleware.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/schemas/__init__.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/schemas/models.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/schemas/operation_context.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/schemas/responses.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/utils/__init__.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/utils/cert_utils/__init__.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/utils/cert_utils/chain.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/utils/cert_utils/errors.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/utils/cert_utils/inspection.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/utils/cert_utils/parsing.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/utils/cert_utils/revocation.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/utils/cert_utils/roles.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/utils/crl_client.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/utils/crypto_utils.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/utils/datetime_compat.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/utils/validation_utils.py +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework.egg-info/dependency_links.txt +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework.egg-info/entry_points.txt +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework.egg-info/top_level.txt +0 -0
- {mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-security-framework
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.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>
|
|
@@ -60,6 +60,10 @@ Requires-Dist: pytest>=7.0.0; extra == "test"
|
|
|
60
60
|
Requires-Dist: pytest-cov>=4.0.0; extra == "test"
|
|
61
61
|
Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
|
|
62
62
|
Requires-Dist: pytest-mock>=3.8.0; extra == "test"
|
|
63
|
+
Requires-Dist: fastapi>=0.68.0; extra == "test"
|
|
64
|
+
Requires-Dist: uvicorn[standard]>=0.15.0; extra == "test"
|
|
65
|
+
Requires-Dist: flask>=2.0.0; extra == "test"
|
|
66
|
+
Requires-Dist: flask-cors>=3.0.0; extra == "test"
|
|
63
67
|
Requires-Dist: httpx>=0.24.0; extra == "test"
|
|
64
68
|
Dynamic: license-file
|
|
65
69
|
|
|
@@ -27,6 +27,7 @@ Version: 1.0.0
|
|
|
27
27
|
License: MIT
|
|
28
28
|
"""
|
|
29
29
|
|
|
30
|
+
import ipaddress
|
|
30
31
|
import logging
|
|
31
32
|
import os
|
|
32
33
|
from datetime import datetime, timedelta, timezone
|
|
@@ -248,6 +249,14 @@ def _certificate_type_of(certificate) -> CertificateType:
|
|
|
248
249
|
return CertificateType.CLIENT
|
|
249
250
|
|
|
250
251
|
|
|
252
|
+
def _subject_alt_name(value: str) -> x509.GeneralName:
|
|
253
|
+
"""Return the correct SAN type for a DNS name or IP literal string."""
|
|
254
|
+
try:
|
|
255
|
+
return x509.IPAddress(ipaddress.ip_address(value))
|
|
256
|
+
except ValueError:
|
|
257
|
+
return x509.DNSName(value)
|
|
258
|
+
|
|
259
|
+
|
|
251
260
|
class CertificateManager:
|
|
252
261
|
"""
|
|
253
262
|
Certificate Management Class
|
|
@@ -1023,6 +1032,10 @@ class CertificateManager:
|
|
|
1023
1032
|
x509.SubjectKeyIdentifier.from_public_key(private_key.public_key()),
|
|
1024
1033
|
critical=False,
|
|
1025
1034
|
)
|
|
1035
|
+
builder = builder.add_extension(
|
|
1036
|
+
x509.AuthorityKeyIdentifier.from_issuer_public_key(ca_key.public_key()),
|
|
1037
|
+
critical=False,
|
|
1038
|
+
)
|
|
1026
1039
|
|
|
1027
1040
|
# Add roles and permissions to certificate extensions
|
|
1028
1041
|
# Validate and normalize roles using CertificateRole enum
|
|
@@ -1333,11 +1346,15 @@ class CertificateManager:
|
|
|
1333
1346
|
x509.SubjectKeyIdentifier.from_public_key(private_key.public_key()),
|
|
1334
1347
|
critical=False,
|
|
1335
1348
|
)
|
|
1349
|
+
builder = builder.add_extension(
|
|
1350
|
+
x509.AuthorityKeyIdentifier.from_issuer_public_key(ca_key.public_key()),
|
|
1351
|
+
critical=False,
|
|
1352
|
+
)
|
|
1336
1353
|
|
|
1337
1354
|
# Add Subject Alternative Name (SAN) if provided
|
|
1338
1355
|
if server_config.subject_alt_names:
|
|
1339
1356
|
san_names = [
|
|
1340
|
-
|
|
1357
|
+
_subject_alt_name(name) for name in server_config.subject_alt_names
|
|
1341
1358
|
]
|
|
1342
1359
|
|
|
1343
1360
|
builder = builder.add_extension(
|
|
@@ -518,6 +518,7 @@ class SSLManager:
|
|
|
518
518
|
else:
|
|
519
519
|
# For other modes, use default context with verification
|
|
520
520
|
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
|
|
521
|
+
context.check_hostname = bool(self.config.check_hostname)
|
|
521
522
|
context.verify_mode = self._get_verify_mode(actual_verify_mode)
|
|
522
523
|
|
|
523
524
|
# Set minimum TLS version
|
mcp_security_framework-2.3.1/mcp_security_framework/examples/tls_certificate_regressions_example.py
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TLS and certificate regression examples.
|
|
3
|
+
|
|
4
|
+
These examples are deliberately small and file-backed. They exercise public
|
|
5
|
+
configuration and certificate APIs with real SSL contexts and X.509 artifacts,
|
|
6
|
+
so callers can copy the patterns into their own applications without relying on
|
|
7
|
+
test doubles.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import ipaddress
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from tempfile import TemporaryDirectory
|
|
13
|
+
from typing import Dict
|
|
14
|
+
|
|
15
|
+
from cryptography import x509
|
|
16
|
+
from cryptography.x509.oid import ExtensionOID
|
|
17
|
+
|
|
18
|
+
from mcp_security_framework import SSLConfig
|
|
19
|
+
from mcp_security_framework.core.cert_manager import CertificateManager
|
|
20
|
+
from mcp_security_framework.core.ssl_manager import SSLManager
|
|
21
|
+
from mcp_security_framework.schemas.config import (
|
|
22
|
+
CAConfig,
|
|
23
|
+
CertificateConfig,
|
|
24
|
+
ServerCertConfig,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _manager(root: Path) -> CertificateManager:
|
|
29
|
+
"""Create a CertificateManager that writes only under the given root."""
|
|
30
|
+
return CertificateManager(
|
|
31
|
+
CertificateConfig(
|
|
32
|
+
enabled=True,
|
|
33
|
+
ca_creation_mode=True,
|
|
34
|
+
cert_storage_path=str(root / "certs"),
|
|
35
|
+
key_storage_path=str(root / "keys"),
|
|
36
|
+
)
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def ca_only_client_tls_config_is_valid() -> SSLConfig:
|
|
41
|
+
"""Build one-way client TLS config that trusts a CA without client identity."""
|
|
42
|
+
with TemporaryDirectory(prefix="sf-ca-only-client-tls-") as tmp:
|
|
43
|
+
root = Path(tmp)
|
|
44
|
+
ca_pair = _manager(root).create_root_ca(
|
|
45
|
+
CAConfig(
|
|
46
|
+
common_name="Example CA",
|
|
47
|
+
organization="Example Org",
|
|
48
|
+
key_size=2048,
|
|
49
|
+
)
|
|
50
|
+
)
|
|
51
|
+
return SSLConfig(
|
|
52
|
+
enabled=True,
|
|
53
|
+
verify=True,
|
|
54
|
+
ca_cert_file=ca_pair.certificate_path,
|
|
55
|
+
check_hostname=True,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def client_context_honors_disabled_hostname_check() -> bool:
|
|
60
|
+
"""Return whether create_client_context preserves check_hostname=False."""
|
|
61
|
+
config = SSLConfig(enabled=False, verify=True, check_hostname=False)
|
|
62
|
+
context = SSLManager(config).create_client_context()
|
|
63
|
+
return context.check_hostname
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def issued_leaf_extension_presence() -> Dict[str, bool]:
|
|
67
|
+
"""Return whether an issued server certificate has RFC 5280 key ids."""
|
|
68
|
+
with TemporaryDirectory(prefix="sf-leaf-key-ids-") as tmp:
|
|
69
|
+
root = Path(tmp)
|
|
70
|
+
manager = _manager(root)
|
|
71
|
+
ca_pair = manager.create_root_ca(
|
|
72
|
+
CAConfig(
|
|
73
|
+
common_name="Key Identifier CA",
|
|
74
|
+
organization="Example Org",
|
|
75
|
+
key_size=2048,
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
server_pair = manager.create_server_certificate(
|
|
79
|
+
ServerCertConfig(
|
|
80
|
+
common_name="localhost",
|
|
81
|
+
organization="Example Org",
|
|
82
|
+
key_size=2048,
|
|
83
|
+
ca_cert_path=ca_pair.certificate_path,
|
|
84
|
+
ca_key_path=ca_pair.private_key_path,
|
|
85
|
+
subject_alt_names=["localhost"],
|
|
86
|
+
)
|
|
87
|
+
)
|
|
88
|
+
cert = x509.load_pem_x509_certificate(
|
|
89
|
+
Path(server_pair.certificate_path).read_bytes()
|
|
90
|
+
)
|
|
91
|
+
return {
|
|
92
|
+
"subject_key_identifier": _has_extension(
|
|
93
|
+
cert, ExtensionOID.SUBJECT_KEY_IDENTIFIER
|
|
94
|
+
),
|
|
95
|
+
"authority_key_identifier": _has_extension(
|
|
96
|
+
cert, ExtensionOID.AUTHORITY_KEY_IDENTIFIER
|
|
97
|
+
),
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def ip_subject_alt_name_is_encoded_as_ip_address() -> Dict[str, bool]:
|
|
102
|
+
"""Return how create_server_certificate encodes a loopback SAN."""
|
|
103
|
+
with TemporaryDirectory(prefix="sf-ip-san-") as tmp:
|
|
104
|
+
root = Path(tmp)
|
|
105
|
+
manager = _manager(root)
|
|
106
|
+
ca_pair = manager.create_root_ca(
|
|
107
|
+
CAConfig(
|
|
108
|
+
common_name="IP SAN CA",
|
|
109
|
+
organization="Example Org",
|
|
110
|
+
key_size=2048,
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
server_pair = manager.create_server_certificate(
|
|
114
|
+
ServerCertConfig(
|
|
115
|
+
common_name="127.0.0.1",
|
|
116
|
+
organization="Example Org",
|
|
117
|
+
key_size=2048,
|
|
118
|
+
ca_cert_path=ca_pair.certificate_path,
|
|
119
|
+
ca_key_path=ca_pair.private_key_path,
|
|
120
|
+
subject_alt_names=["127.0.0.1"],
|
|
121
|
+
)
|
|
122
|
+
)
|
|
123
|
+
cert = x509.load_pem_x509_certificate(
|
|
124
|
+
Path(server_pair.certificate_path).read_bytes()
|
|
125
|
+
)
|
|
126
|
+
san = cert.extensions.get_extension_for_oid(
|
|
127
|
+
ExtensionOID.SUBJECT_ALTERNATIVE_NAME
|
|
128
|
+
).value
|
|
129
|
+
expected_ip = ipaddress.ip_address("127.0.0.1")
|
|
130
|
+
return {
|
|
131
|
+
"has_ip_address": expected_ip in san.get_values_for_type(x509.IPAddress),
|
|
132
|
+
"has_dns_name": "127.0.0.1" in san.get_values_for_type(x509.DNSName),
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _has_extension(cert: x509.Certificate, oid: x509.ObjectIdentifier) -> bool:
|
|
137
|
+
"""Return True when the certificate contains the extension."""
|
|
138
|
+
try:
|
|
139
|
+
cert.extensions.get_extension_for_oid(oid)
|
|
140
|
+
except x509.ExtensionNotFound:
|
|
141
|
+
return False
|
|
142
|
+
return True
|
|
@@ -73,7 +73,7 @@ def require_permissions(*permissions: str) -> Any:
|
|
|
73
73
|
permissions to routes that opt in.
|
|
74
74
|
"""
|
|
75
75
|
|
|
76
|
-
def _required_permissions_marker() -> None:
|
|
76
|
+
async def _required_permissions_marker() -> None:
|
|
77
77
|
"""
|
|
78
78
|
Carry the declared permissions; it is never called for its result.
|
|
79
79
|
|
|
@@ -231,21 +231,27 @@ class SSLConfig(BaseModel):
|
|
|
231
231
|
def validate_ssl_configuration(self) -> Self:
|
|
232
232
|
"""Validate SSL configuration consistency."""
|
|
233
233
|
if self.enabled:
|
|
234
|
-
|
|
235
|
-
|
|
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:
|
|
234
|
+
if self.cert_file or self.key_file:
|
|
235
|
+
if not (self.cert_file and self.key_file):
|
|
245
236
|
raise ValueError(
|
|
246
|
-
"SSL
|
|
247
|
-
"files are required"
|
|
237
|
+
"SSL certificate and key files must be configured together"
|
|
248
238
|
)
|
|
239
|
+
if self.client_cert_file or self.client_key_file:
|
|
240
|
+
if not (self.client_cert_file and self.client_key_file):
|
|
241
|
+
raise ValueError(
|
|
242
|
+
"SSL client certificate and key files must be configured "
|
|
243
|
+
"together"
|
|
244
|
+
)
|
|
245
|
+
if (
|
|
246
|
+
self.verify
|
|
247
|
+
and not self.material_from_memory
|
|
248
|
+
and not self.ca_cert_file
|
|
249
|
+
and not (self.cert_file and self.key_file)
|
|
250
|
+
):
|
|
251
|
+
raise ValueError(
|
|
252
|
+
"SSL enabled with verification but certificate and key "
|
|
253
|
+
"files are required"
|
|
254
|
+
)
|
|
249
255
|
return self
|
|
250
256
|
|
|
251
257
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-security-framework
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.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>
|
|
@@ -60,6 +60,10 @@ Requires-Dist: pytest>=7.0.0; extra == "test"
|
|
|
60
60
|
Requires-Dist: pytest-cov>=4.0.0; extra == "test"
|
|
61
61
|
Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
|
|
62
62
|
Requires-Dist: pytest-mock>=3.8.0; extra == "test"
|
|
63
|
+
Requires-Dist: fastapi>=0.68.0; extra == "test"
|
|
64
|
+
Requires-Dist: uvicorn[standard]>=0.15.0; extra == "test"
|
|
65
|
+
Requires-Dist: flask>=2.0.0; extra == "test"
|
|
66
|
+
Requires-Dist: flask-cors>=3.0.0; extra == "test"
|
|
63
67
|
Requires-Dist: httpx>=0.24.0; extra == "test"
|
|
64
68
|
Dynamic: license-file
|
|
65
69
|
|
|
@@ -35,6 +35,7 @@ mcp_security_framework/examples/gateway_example.py
|
|
|
35
35
|
mcp_security_framework/examples/microservice_example.py
|
|
36
36
|
mcp_security_framework/examples/protected_keys_example.py
|
|
37
37
|
mcp_security_framework/examples/standalone_example.py
|
|
38
|
+
mcp_security_framework/examples/tls_certificate_regressions_example.py
|
|
38
39
|
mcp_security_framework/middleware/__init__.py
|
|
39
40
|
mcp_security_framework/middleware/auth_middleware.py
|
|
40
41
|
mcp_security_framework/middleware/fastapi_auth_middleware.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "mcp-security-framework"
|
|
7
|
-
version = "2.3.
|
|
7
|
+
version = "2.3.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"}
|
|
@@ -81,6 +81,10 @@ test = [
|
|
|
81
81
|
"pytest-cov>=4.0.0",
|
|
82
82
|
"pytest-asyncio>=0.21.0",
|
|
83
83
|
"pytest-mock>=3.8.0",
|
|
84
|
+
"fastapi>=0.68.0",
|
|
85
|
+
"uvicorn[standard]>=0.15.0",
|
|
86
|
+
"flask>=2.0.0",
|
|
87
|
+
"flask-cors>=3.0.0",
|
|
84
88
|
"httpx>=0.24.0",
|
|
85
89
|
]
|
|
86
90
|
|
|
@@ -161,6 +165,7 @@ python_files = ["test_*.py", "*_test.py"]
|
|
|
161
165
|
python_classes = ["Test*"]
|
|
162
166
|
python_functions = ["test_*"]
|
|
163
167
|
markers = [
|
|
168
|
+
"asyncio: marks tests that run on an asyncio event loop",
|
|
164
169
|
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
|
|
165
170
|
"integration: marks tests as integration tests",
|
|
166
171
|
"unit: marks tests as unit tests",
|
|
@@ -189,4 +194,3 @@ exclude_lines = [
|
|
|
189
194
|
"class .*\\bProtocol\\):",
|
|
190
195
|
"@(abc\\.)?abstractmethod",
|
|
191
196
|
]
|
|
192
|
-
|
|
File without changes
|
|
File without changes
|
{mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/cli/__init__.py
RENAMED
|
File without changes
|
{mcp_security_framework-2.3.0 → mcp_security_framework-2.3.1}/mcp_security_framework/cli/cert_cli.py
RENAMED
|
File without changes
|
|
File without changes
|
{mcp_security_framework-2.3.0 → mcp_security_framework-2.3.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|