Initial curated ITWorx_MCP_Hub source from 368fba691ea8d23403b4d56b53b5ec670d7c5020
This commit is contained in:
commit
cb5be898ea
663 files changed
+82674
No files matched your search
@@ -0,0 +1,17 @@
|
||||
"""Production runtime configuration primitives."""
|
||||
|
||||
from .secret_files import (
|
||||
SecretFileError,
|
||||
read_secret_file,
|
||||
validate_required_secret_paths,
|
||||
validate_secret_file,
|
||||
)
|
||||
from .service_tokens import issue_broker_service_token
|
||||
|
||||
__all__ = [
|
||||
"SecretFileError",
|
||||
"issue_broker_service_token",
|
||||
"read_secret_file",
|
||||
"validate_required_secret_paths",
|
||||
"validate_secret_file",
|
||||
]
|
||||
@@ -0,0 +1,94 @@
|
||||
"""Fail-closed secret-file access without value projection or logging."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import stat
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class SecretFileError(RuntimeError):
|
||||
"""Stable non-secret error raised for an invalid runtime secret file."""
|
||||
|
||||
|
||||
def validate_secret_file(
|
||||
path: Path,
|
||||
*,
|
||||
root: Path = Path("/run/secrets"),
|
||||
expected_uid: int | None = None,
|
||||
expected_gid: int | None = None,
|
||||
max_bytes: int = 8192,
|
||||
) -> bytes:
|
||||
"""Return bounded bytes only after containment, mode, owner, and content checks."""
|
||||
|
||||
try:
|
||||
resolved_root = root.resolve(strict=True)
|
||||
resolved = path.resolve(strict=True)
|
||||
resolved.relative_to(resolved_root)
|
||||
metadata = resolved.stat()
|
||||
except (OSError, ValueError) as exc:
|
||||
raise SecretFileError("required secret file is unavailable") from exc
|
||||
if not stat.S_ISREG(metadata.st_mode):
|
||||
raise SecretFileError("required secret path is not a regular file")
|
||||
mode = stat.S_IMODE(metadata.st_mode)
|
||||
if os.name != "nt" and (mode & 0o077 or mode & 0o111 or not mode & 0o400):
|
||||
raise SecretFileError("required secret file permissions are unsafe")
|
||||
if expected_uid is not None and metadata.st_uid != expected_uid:
|
||||
raise SecretFileError("required secret file owner is invalid")
|
||||
if expected_gid is not None and metadata.st_gid != expected_gid:
|
||||
raise SecretFileError("required secret file group is invalid")
|
||||
try:
|
||||
payload = resolved.read_bytes()
|
||||
except OSError as exc:
|
||||
raise SecretFileError("required secret file is unreadable") from exc
|
||||
payload = payload.rstrip(b"\r\n")
|
||||
if (
|
||||
not payload
|
||||
or len(payload) > max_bytes
|
||||
or b"\x00" in payload
|
||||
or b"\r" in payload.rstrip(b"\r\n")
|
||||
or b"\n" in payload.rstrip(b"\r\n")
|
||||
):
|
||||
raise SecretFileError("required secret file content is invalid")
|
||||
return payload
|
||||
|
||||
|
||||
def read_secret_file(
|
||||
path: Path,
|
||||
*,
|
||||
root: Path = Path("/run/secrets"),
|
||||
expected_uid: int | None = None,
|
||||
expected_gid: int | None = None,
|
||||
max_bytes: int = 8192,
|
||||
) -> str:
|
||||
"""Read a UTF-8 secret at its internal consumption boundary."""
|
||||
|
||||
payload = validate_secret_file(
|
||||
path,
|
||||
root=root,
|
||||
expected_uid=expected_uid,
|
||||
expected_gid=expected_gid,
|
||||
max_bytes=max_bytes,
|
||||
)
|
||||
try:
|
||||
return payload.decode("utf-8")
|
||||
except UnicodeDecodeError as exc:
|
||||
raise SecretFileError("required secret file encoding is invalid") from exc
|
||||
|
||||
|
||||
def validate_required_secret_paths(raw: str) -> None:
|
||||
"""Validate a comma-separated production startup contract without returning values."""
|
||||
|
||||
if not raw.strip():
|
||||
return
|
||||
expected_uid = (
|
||||
int(os.environ["SECRET_EXPECTED_UID"]) if os.getenv("SECRET_EXPECTED_UID") else None
|
||||
)
|
||||
expected_gid = (
|
||||
int(os.environ["SECRET_EXPECTED_GID"]) if os.getenv("SECRET_EXPECTED_GID") else None
|
||||
)
|
||||
for value in raw.split(","):
|
||||
path = Path(value.strip())
|
||||
if not path.is_absolute():
|
||||
raise SecretFileError("required secret path must be absolute")
|
||||
validate_secret_file(path, expected_uid=expected_uid, expected_gid=expected_gid)
|
||||
@@ -0,0 +1,39 @@
|
||||
"""Short-lived internal service tokens shared by trusted runtime components."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
import time
|
||||
|
||||
|
||||
def issue_broker_service_token(
|
||||
secret: str,
|
||||
project: str,
|
||||
environment: str,
|
||||
*,
|
||||
ttl_seconds: int = 60,
|
||||
) -> str:
|
||||
"""Issue a bounded Docker broker token for one validated project context."""
|
||||
|
||||
payload = {
|
||||
"aud": "docker-read-broker",
|
||||
"project": project,
|
||||
"environment": environment,
|
||||
"exp": int(time.time()) + ttl_seconds,
|
||||
}
|
||||
encoded = (
|
||||
base64.urlsafe_b64encode(json.dumps(payload, separators=(",", ":")).encode())
|
||||
.decode()
|
||||
.rstrip("=")
|
||||
)
|
||||
signature = (
|
||||
base64.urlsafe_b64encode(
|
||||
hmac.new(secret.encode(), encoded.encode(), hashlib.sha256).digest()
|
||||
)
|
||||
.decode()
|
||||
.rstrip("=")
|
||||
)
|
||||
return f"{encoded}.{signature}"
|
||||
@@ -0,0 +1,103 @@
|
||||
"""Process-local MCP runtime supervision and recovery telemetry."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
import socket
|
||||
import time
|
||||
from datetime import UTC, datetime
|
||||
from threading import Lock
|
||||
from typing import Any
|
||||
|
||||
from mcp.server.context import CallNext, ServerRequestContext
|
||||
from mcp.shared.exceptions import MCPError
|
||||
|
||||
|
||||
class RuntimeSupervisor:
|
||||
"""Track transport health without turning tool failures into process failures."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._started_monotonic = time.monotonic()
|
||||
self._started_at = datetime.now(UTC).isoformat()
|
||||
material = f"{socket.gethostname()}:{os.getpid()}:{self._started_at}".encode()
|
||||
self.worker_id = hashlib.sha256(material).hexdigest()[:16]
|
||||
self.generation = os.environ.get(
|
||||
"HUB_RUNTIME_GENERATION",
|
||||
os.environ.get("GITEA_CONNECTOR_BUILD_SHA", "development"),
|
||||
)[:64]
|
||||
self.restart_count = max(int(os.environ.get("HUB_RUNTIME_RESTART_COUNT", "0")), 0)
|
||||
self._lock = Lock()
|
||||
self._in_flight = 0
|
||||
self._requests = 0
|
||||
self._failures = 0
|
||||
self._last_error_code: str | None = None
|
||||
self._last_fatal_error_code: str | None = None
|
||||
self._circuit_state = "CLOSED"
|
||||
self._recovery_count = 0
|
||||
|
||||
def started(self) -> None:
|
||||
with self._lock:
|
||||
self._in_flight += 1
|
||||
self._requests += 1
|
||||
|
||||
def completed(self) -> None:
|
||||
with self._lock:
|
||||
self._in_flight = max(self._in_flight - 1, 0)
|
||||
if self._circuit_state == "DEGRADED":
|
||||
self._circuit_state = "CLOSED"
|
||||
self._recovery_count += 1
|
||||
|
||||
def failed(self, code: str, *, fatal: bool) -> None:
|
||||
with self._lock:
|
||||
self._in_flight = max(self._in_flight - 1, 0)
|
||||
self._failures += 1
|
||||
self._last_error_code = code[:128]
|
||||
if fatal:
|
||||
self._last_fatal_error_code = code[:128]
|
||||
self._circuit_state = "DEGRADED"
|
||||
|
||||
def snapshot(self) -> dict[str, Any]:
|
||||
with self._lock:
|
||||
return {
|
||||
"workerId": self.worker_id,
|
||||
"sessionId": None,
|
||||
"sessionMode": "stateless-resumable-http",
|
||||
"resumable": True,
|
||||
"startedAt": self._started_at,
|
||||
"uptimeSeconds": max(int(time.monotonic() - self._started_monotonic), 0),
|
||||
"restartCount": self.restart_count,
|
||||
"generation": self.generation,
|
||||
"circuitState": self._circuit_state,
|
||||
"recoveryCount": self._recovery_count,
|
||||
"requests": self._requests,
|
||||
"inFlight": self._in_flight,
|
||||
"failures": self._failures,
|
||||
"lastErrorCode": self._last_error_code,
|
||||
"lastFatalErrorCode": self._last_fatal_error_code,
|
||||
}
|
||||
|
||||
|
||||
SUPERVISOR = RuntimeSupervisor()
|
||||
|
||||
|
||||
class SupervisorMiddleware:
|
||||
"""Keep per-operation errors observable while preserving the next request."""
|
||||
|
||||
async def __call__(self, ctx: ServerRequestContext[Any, Any], call_next: CallNext) -> Any:
|
||||
SUPERVISOR.started()
|
||||
try:
|
||||
result = await call_next(ctx)
|
||||
except MCPError as exc:
|
||||
data = exc.data if isinstance(exc.data, dict) else {}
|
||||
SUPERVISOR.failed(str(data.get("code", "MCP_ERROR")), fatal=False)
|
||||
raise
|
||||
except Exception as exc:
|
||||
SUPERVISOR.failed(type(exc).__name__, fatal=True)
|
||||
raise
|
||||
SUPERVISOR.completed()
|
||||
return result
|
||||
|
||||
|
||||
def runtime_snapshot() -> dict[str, Any]:
|
||||
return SUPERVISOR.snapshot()
|
||||
Reference in new issue
Block a user