Architecture
Service architecture, components, and data flow
This page describes how tlsproxy is structured internally, how its components interact, and how data moves from an incoming encrypted client connection through to your plain-text backend service. Understanding this architecture helps you configure the proxy correctly, diagnose connectivity issues, and reason about the security boundaries tlsproxy establishes on your behalf.
TLS Listener Type: Network listener (TCP) The TLS Listener binds to the configured public port (typically 443) and accepts incoming encrypted connections from clients. It is your service's public-facing entry point. Every client connection arrives here first, so the address and port you expose to the internet correspond directly to this component.
TLS Terminator
Type: Protocol handler (Twisted TLSMemoryBIOProtocol)
Built on Twisted's asynchronous I/O engine, the TLS Terminator performs the TLS handshake, validates client credentials if mutual TLS is configured, and decrypts the incoming byte stream. Once decryption is complete, it hands a plain-text data stream to the Router. This is where your certificates are loaded and applied; a misconfigured certificate chain will surface as an error at this layer.
Request Router
Type: Internal routing logic
The Router inspects the decrypted request — for example, the HTTP Host header or SNI value captured during the handshake — and determines which backend target should receive the traffic. You define routing rules in the proxy configuration, and this component evaluates them at runtime for every request.
Connection Pool Type: Backend connection manager The Connection Pool maintains reusable plain-text TCP connections to your backend services. Rather than opening a new socket for every inbound request, the pool reuses existing connections, reducing latency and resource consumption on your backends. Pool size limits are governed by your configuration.
Backend Services Type: External (user-managed) Your backend services receive plain, unencrypted HTTP traffic from the Connection Pool. They do not need to handle TLS themselves — that responsibility is fully delegated to tlsproxy. The backends can be any HTTP-speaking process running on localhost or an internal network address.
Admin API Type: HTTP management interface The Admin API exposes HTTP endpoints that let you inspect proxy status, reload configuration, and verify connectivity without restarting the process. You interact with it via standard HTTP requests to its dedicated port. It is the primary interface for operational management and is covered in detail in the API Reference section.
The following trace walks a single HTTPS request from a client through tlsproxy to your backend and back.
1. Client initiates a TLS connection Your client opens a TCP connection to the tlsproxy TLS Listener on the public port. The Twisted event loop accepts the socket and passes it to the TLS Terminator.
2. TLS handshake The TLS Terminator negotiates TLS with the client, presenting the server certificate you have configured. If you have enabled mutual TLS, the client must also present a valid certificate at this step. A failed handshake returns a TLS alert to the client and logs the error; no traffic reaches the backend.
3. Request decryption and routing
Once the handshake succeeds, the TLS Terminator decrypts the incoming bytes and forwards the plain-text HTTP request to the Request Router. The Router reads the Host header (or the SNI hostname captured during the handshake) and matches it against your configured routing rules to select a backend target.
4. Backend connection The Router asks the Connection Pool for an available connection to the selected backend. If a reusable connection exists, it is returned immediately. Otherwise, the pool opens a new plain-text TCP connection to your backend's address and port.
5. Plain-text forwarding The decrypted request bytes are written to the backend connection. Your backend service receives a normal HTTP request with no TLS overhead. It processes the request and writes its HTTP response back through the same socket.
6. Response path The response travels back through the Connection Pool to the TLS Terminator, which re-encrypts it and sends it to the client over the existing TLS session.
7. Connection handling For HTTP/1.1 keep-alive requests, the TLS session and the backend connection remain open for subsequent requests. For short-lived connections, the pool returns the backend socket to its idle pool (up to the configured limit) rather than closing it immediately.
Operational control path (Admin API) Separate from the data path, you can send HTTP requests to the Admin API at any time to reload certificates, update routing rules, or query health status. These control operations do not interrupt in-flight client connections.
1. Twisted as the async runtime tlsproxy is built on the Twisted framework rather than a thread-per-connection model. Twisted's event-driven, single-threaded reactor handles many concurrent connections efficiently without the overhead of OS thread scheduling. The trade-off is that CPU-bound work in a callback blocks the entire reactor; tlsproxy mitigates this by keeping its own processing minimal and delegating I/O to the event loop.
2. TLS termination in the proxy, not the backend Decrypting TLS at the proxy boundary means your backend services are simpler — they speak plain HTTP and never handle certificates. This centralises certificate management (rotation, mutual TLS policy) in one place. The deliberate trade-off is that traffic between tlsproxy and your backends is unencrypted, which is acceptable when both run on the same host or a trusted private network but requires additional controls (e.g., a loopback-only backend bind address) in shared environments.
3. SNI-based and Host-header-based routing
The Router uses both the TLS SNI extension and the HTTP Host header to make routing decisions. SNI is available before decryption completes, enabling early routing logic; the Host header provides a second matching opportunity for proxies that serve multiple virtual hosts under a single IP. This dual-signal approach keeps configuration flexible without requiring separate listener ports per service.
4. Dedicated Admin API port The management interface runs on a separate port rather than sharing the public TLS port. This makes it straightforward to apply firewall rules that restrict admin access to trusted networks while keeping the public proxy port open. It also means a misconfigured TLS certificate cannot accidentally block you from reaching management endpoints.
5. Connection pooling to backends Reusing backend connections reduces the latency cost of TCP and HTTP handshakes for high-request-rate workloads. The pool is bounded to prevent resource exhaustion on backends. A simpler design would open and close a connection per request, which was rejected because it would impose unacceptable overhead at moderate traffic levels.
Plain-text backend traffic
Because tlsproxy terminates TLS and forwards plain HTTP, the segment between tlsproxy and your backend is unencrypted. This is intentional for simplicity, but it means you should ensure the backend listens only on 127.0.0.1 or an isolated network interface. If your threat model requires end-to-end encryption, tlsproxy is not the right tool — consider a full mTLS mesh or a proxy that supports encrypted backend connections.
Single-process, single-reactor design Twisted's reactor is single-threaded. tlsproxy does not distribute work across multiple CPU cores natively. For workloads that saturate a single core at the TLS termination layer, you would need to run multiple tlsproxy instances behind a load balancer and partition traffic between them. A multi-process or multi-threaded proxy (e.g., nginx, HAProxy, Envoy) may be a better fit for very high TLS throughput requirements.
No built-in load balancing across backend instances The routing layer maps a hostname or rule to a single backend address. tlsproxy does not perform round-robin or health-check-based balancing across a pool of backend replicas. If you need that capability, place a load balancer (or a service discovery–aware sidecar) between tlsproxy and your backends.
Certificate management is your responsibility tlsproxy reads certificates from the paths you configure; it does not automatically renew them. You must integrate certificate rotation (e.g., via a cron job or a secrets manager) and trigger a configuration reload through the Admin API. Tools designed with automatic renewal in mind (e.g., Caddy, Traefik) may be preferable if certificate lifecycle automation is a primary concern.
Best suited for trusted, internal networks tlsproxy is designed for developer and operator use cases — bridging encrypted external traffic to plain-text internal services during development, testing, or in controlled internal environments. It is not hardened for deployment as a public-internet edge proxy at scale; for that role, evaluate purpose-built reverse proxies with DDoS mitigation, WAF integration, and rate limiting.