Off the path: introducing ticketconnect

Most of what we write here is about getting into a TLS connection to upgrade its cryptography — inline, redirect, or proxy. Every one of those stands somewhere in the path. There is a fourth move that stands nowhere in the path at all, and today we are releasing it as open source: ticketconnect.

The endpoints you can't touch

Post-quantum crypto is arriving on a schedule, and it keeps running into the same wall: the long tail of endpoints you can't touch. Fleets of legacy services on OpenSSL that can't negotiate X25519MLKEM768 and can't be rebuilt, re-imaged, and redeployed on the deadline's timetable. You cannot post-quantum-upgrade what you cannot recompile.

Resume your way in

ticketconnect leans on one property of TLS 1.3: PSK resumption derives its session keys from the ticket, not from a fresh key exchange. So if a legacy client resumes on a ticket that came from a post-quantum handshake, that connection is keyed by quantum-safe material — even though the client itself never negotiated PQC.

It makes that happen without changing the client. A node agent performs the X25519MLKEM768 handshake the client can't, and installs the resulting resumption session directly into the client's own process. The client's next connection simply resumes — on a PQC-rooted PSK it never asked for. Off the data path: no proxy, no socket, no config, no image rebuild. Deploy one DaemonSet and the fleet's connections start resuming post-quantum.

Public API only

Here is the part we are proud of. An eBPF uprobe catches SSL_connect and briefly freezes the thread; the installation then happens over ptrace, using only public OpenSSL APIs (d2i_SSL_SESSION + SSL_set_session) — never a private struct offset.

That single constraint collapses three problems at once:

It is fail-closed throughout, and there is no silent downgrade: a miss falls back to ordinary TLS and emits an event. On the wire, that was always the only ground truth worth trusting.

Proof, not a demo

We care about not overclaiming, so the claims are verified rather than asserted. On a real Kubernetes cluster, an unmodified looping client did full handshakes — then, the moment the agent was deployed and with zero changes to the client, its connections became 111 consecutive X25519MLKEM768 resumptions. A packet capture proves the resumed ticket is byte-for-byte the one the agent fetched, and a negative control shows the client cannot resume on its own. So it is genuinely the injected ticket, not a coincidence.

What it is, and isn't

ticketconnect is an honest, experimental v1 — a compliance and crypto-agility bridge to buy time for legacy fleets while proper endpoint migration happens over years, not a replacement for it. Today it is OpenSSL and x86-64 only, single-destination, and resumption-based (the first connection to a cold destination is classical). And it is a privileged, node-wide agent, so it warrants the same scrutiny as any eBPF/ptrace tool. We would rather say that plainly than oversell it.

It's open source

ticketconnect is MIT-licensed and on GitHub, with the design docs, a security model, and container images. You can watch the whole thing happen on one host in a single command:

git clone https://github.com/connectedinformation/ticketconnect
cd ticketconnect && ./demo/run_host_demo.sh

Where our inline work stands in the path, ticketconnect stands beside the process. Both are ways to give a connection post-quantum protection it could not negotiate for itself — you pick the one that fits what you're allowed to touch. If you work on PQC migration, we'd value your eyes on it, including where you think it's wrong: github.com/connectedinformation/ticketconnect.

← All posts