# #region CoreSslTrust [C:4] [TYPE Module] [SEMANTICS ssl,tls,trust,certs,security] # @BRIEF Centralized SSL/TLS trust context for all Python HTTP clients. # @LAYER Infrastructure # @INVARIANT Never returns verify=False from environment configuration. # The application does not disable TLS verification via env var. # All trust anchors come from the system CA store populated # at container startup via CERTS_PATH (/opt/certs) mount. # @RATIONALE Previously LLM_SSL_VERIFY, LLM_CA_CERT_URLS, and per-client # _get_verify / _get_ssl_verify functions were scattered across # llm_analysis, translate, and agent code. This centralizes # them into one contract: system CA store is the single source # of trust, populated once per container at startup. # @REJECTED Per-client SSL verify toggle was rejected — caused operators # to manage LLM TLS separately from Superset/Git/backend TLS, # and allowed LLM_SSL_VERIFY=false to become a permanent # workaround instead of fixing cert installation. import os import ssl from pathlib import Path DEFAULT_CAPATH = "/etc/ssl/certs" # ── Public API ──────────────────────────────────────────────────────── def system_ssl_context() -> ssl.SSLContext: """Return an SSLContext that trusts the system CA store. Prefers capath over cafile because OpenSSL 3.x ignores intermediate CA certificates in flat bundle files (ADR-0009 Finding 7). Falls back to default context if capath directory is not available (rare edge case, e.g. minimal containers without ca-certificates). """ if os.path.isdir(DEFAULT_CAPATH): return ssl.create_default_context(capath=DEFAULT_CAPATH) return ssl.create_default_context() def httpx_verify() -> ssl.SSLContext: """Return SSL verification context for httpx clients. Alias for system_ssl_context() to provide a clear API for the main HTTP library used across the project (httpx). """ return system_ssl_context() def describe_context(ctx: ssl.SSLContext | bool | None) -> str: """Return a diagnostic description of the SSL verification state. Does NOT leak key material or secret values. SSLContext in Python 3.13 does not expose capath/cafile as public attributes — verify_load_locations info is internal to OpenSSL. Instead, reports whether /etc/ssl/certs (DEFAULT_CAPATH) is available and the cert count in the system bundle. """ if ctx is False: return "DISABLED (verify=False — should not happen in production)" if ctx is None: return "DEFAULT (certifi)" if isinstance(ctx, ssl.SSLContext): bundle = Path(DEFAULT_CAPATH) / "ca-certificates.crt" cert_count = 0 if bundle.exists(): cert_count = bundle.read_bytes().count(b"-----BEGIN CERTIFICATE-----") mode = "CERT_REQUIRED" if ctx.verify_mode == ssl.CERT_REQUIRED else str(ctx.verify_mode) return f"SSLContext(verify_mode={mode}, system_certs={cert_count})" return f"unknown({type(ctx).__name__})" def cert_dir_inventory(certs_path: str = "/opt/certs") -> dict: """Inventory /opt/certs for operator diagnostics. Returns counts of recognized trust candidates, server/private files, and unrecognized files. """ result: dict[str, list[str]] = { "trust_candidates": [], "server_files": [], "invalid": [], } base = Path(certs_path) if not base.is_dir(): return result for f in sorted(base.iterdir()): if not f.is_file(): continue name = f.name.lower() if name in ("server.crt", "server.key", "server.pem") or any(name.endswith(ext) for ext in (".key", ".p12", ".pfx")): result["server_files"].append(str(f)) continue if any(name.endswith(ext) for ext in (".crt", ".pem", ".cer", ".der")): result["trust_candidates"].append(str(f)) else: result["invalid"].append(str(f)) return result # #endregion CoreSslTrust