security(rest): put the schema fetch behind the pinned CA, on its own port - #175
Merged
Merged
Conversation
… port `panel_http_port` served two transports with opposite security properties: the bridge's CA download, plaintext by design because it fetches the very anchor everything else is checked against, and the client's schema fetch, which should ride the pinned HTTPS transport whenever the caller holds one. One parameter fed both, so a consumer that pinned a CA could not move its schema fetch to HTTPS without pointing the CA download at a TLS port it speaks plaintext to (SpanPanel/span#264). `SpanMqttClient` takes `panel_https_port`, and both schema fetches — connect and every redispatch refetch — go HTTPS on it whenever an `ssl_context` is supplied; naming the port without an anchor is refused rather than left silently plaintext. `create_span_client` routes its one `port` into the slot matching its transport, and documents the diagnostic-CA-read corollary. A verification failure gets a name: `SpanPanelTLSVerificationError`, a subclass of `SpanPanelConnectionError` so every existing except clause keeps its meaning, raised only when `ssl.SSLCertVerificationError` is in the cause chain because ambiguous evidence must not look terminal. The redispatch retry loop leaves it to raise — it cannot succeed on a later attempt under the same anchor — and its wrapper logs it as what it is instead of blaming a slow boot. The CA download itself no longer emits the plaintext-transport warning and no longer spends the once-per-host slot: the fetch of the anchor is unverifiable by construction, carries no credential in either direction, and every caller states its own trust posture — the warning as it stood named credentials that call never carries, which is the log line the issue reported. Every other bootstrap call warns exactly as before.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Splits the schema fetch's port from the CA download's, so a consumer holding a pinned CA can put its schema reads on verified HTTPS without pointing the deliberately-plaintext CA download at a TLS port. This is the library half of SpanPanel/span#264, where a pinned integration's schema fetch ran plaintext at every startup and the transport warning said so.
How
SpanMqttClienttakespanel_https_port;_fetch_schema— the connect-time read and every redispatch refetch — rides it under anssl_context, whilepanel_http_portstays with the bridge's CA fetches. Naming the HTTPS port without an anchor raisesSpanPanelValidationError, mirroring_build_url's refusal of port 80 with a context from the other direction.create_span_clientroutes its oneportinto the slot matching its transport (it was already read as the HTTPS port under a context by every REST call the factory makes), and documents the diagnostic-CA-read corollary.SpanPanelTLSVerificationError(SpanPanelConnectionError): raised only whenssl.SSLCertVerificationErroris in the transport error's cause chain, so ambiguous handshake failures never look terminal, and every existingexcept SpanPanelConnectionErrorkeeps its meaning. The redispatch retry loop leaves it to raise — it cannot succeed on a later attempt under the same session anchor — and the redispatch wrapper logs it as a verification failure instead of a slow boot.Verification
tests/test_schema_fetch_transport_split.py, reworkedtests/test_plaintext_warning.py), including guards that the bridge keeps the plaintext port when the schema fetch moves, that the retry loop makes exactly one attempt on a verification failure, and that the CA download's exemption does not swallow a later legitimate warning.Version 3.4.0. The adapter distributions are untouched (no
SchemaAdapterchange), so schema-0 1.1.2 / schema-1 1.1.3 remain current. SpanPanel/span consumes this via its 3.4.0 pin; its CI cannot pass until this releases to PyPI.