Skip to content

Prove pinned HTTPS SNI on a loopback handshake - #8

Merged
samrusani merged 1 commit into
mainfrom
tls-sni-pin
Aug 19, 2026
Merged

Prove pinned HTTPS SNI on a loopback handshake#8
samrusani merged 1 commit into
mainfrom
tls-sni-pin

Conversation

@samrusani

@samrusani samrusani commented Aug 19, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add a hermetic loopback HTTPS test that the site pin dials the validated address while the TLS server observes SNI on the origin hostname (sni-pin.example), with verify-on against a runtime openssl cert.
  • Keep the private httpx _pool._network_backend assignment fail-closed: installed HTTPTransport still has no public network_backend hook. Record that choice in DECISIONS.md.
  • Cover the fail-closed RuntimeError when _pool is not a ConnectionPool. Production _SiteFetcher still constructs _PinnedTransport(pinner) with default verify-on.

Test plan

  • Local pytest (736 collected/passed), ruff, mypy, language check
  • GitHub checks on 3.11, 3.12, and 3.13 (this test needs openssl on PATH and loopback sockets; ubuntu-latest has both)
  • Confirm test_pinned_transport_preserves_tls_sni_on_the_origin_hostname ran rather than skipped
  • Package and audit jobs green

The pin rewrites only the TCP peer; Host and SNI must stay on the origin name. That was documented and Host-header tested, not handshake-tested. httpx still has no public network_backend hook, so the private pool assignment stays and fails closed if the internals change.

Co-authored-by: Cursor <cursoragent@cursor.com>
@greptile-apps

greptile-apps Bot commented Aug 19, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds a loopback HTTPS integration test proving that pinned connections retain the origin hostname for TLS SNI while dialing the validated address. It also exposes transport constructor options for the test, verifies fail-closed behavior when httpx internals differ, and documents the private-backend decision.

  • Forwards _PinnedTransport keyword arguments to HTTPTransport while retaining unconditional backend pinning.
  • Generates a temporary verified TLS certificate and records server-observed SNI.
  • Adds explicit coverage for an incompatible httpx connection-pool shape.
  • Updates project decision, future-work, and handoff documentation.

Confidence Score: 5/5

The PR appears safe to merge, with no concrete correctness, security, or compatibility defect identified in the changed paths.

Production retains default certificate verification and unconditional address pinning, while the new test exercises TLS SNI against a trusted temporary certificate and the compatibility guard remains fail-closed.

Important Files Changed

Filename Overview
src/coldscreen/site.py Adds additive constructor keyword forwarding while retaining the guarded, unconditional installation of the pinned network backend.
tests/test_site.py Adds verified loopback TLS/SNI coverage and a focused test for fail-closed behavior when the expected httpx pool is unavailable.
DECISIONS.md Records why the private httpx pool assignment remains necessary and how its compatibility risk is contained.
FUTURE.md Replaces the completed SNI-test task with the remaining public-backend-hook migration.
HANDOFF.md Updates project status and recommended future work to reflect the new TLS proof.

Sequence Diagram

sequenceDiagram
    participant Client as httpx Client
    participant Transport as _PinnedTransport
    participant Pinner as _HostPinner
    participant TLS as Loopback TLS Server
    Client->>Transport: GET https://sni-pin.example:port/hello
    Transport->>Pinner: pin(sni-pin.example)
    Pinner-->>Transport: 127.0.0.1
    Transport->>TLS: TCP connect to 127.0.0.1
    Transport->>TLS: TLS ClientHello (SNI: sni-pin.example)
    TLS-->>Client: Verified HTTPS response
Loading

Reviews (1): Last reviewed commit: "Prove the pinned site transport keeps TL..." | Re-trigger Greptile

@samrusani
samrusani merged commit c4fea38 into main Aug 19, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant