A Shared Wire Needs a Sealed Envelope
A ticket proves who is calling. It does not hide what is said, and it does not prove who is answering. On a Thunderbolt bridge that is acceptable: the wire is a cable between two Macs on one desk, and nothing else is on it. On the house's Ethernet and Wi-Fi it is not. Every device in the house shares those segments (televisions, a printer, a guest's phone), and a ticket sent in clear text there can be copied by anything that listens. So Delta's rule for the shared LAN is short: TLS only, and the ticket rides inside it.
The gateway enforces the first half before it reads a single header. On a connection classified as lan, it peeks at the first byte. A TLS connection opens with a handshake record whose first byte is 0x16; anything else is plain HTTP, and the gateway closes the connection with a log line: "refused plain HTTP on the shared LAN … (TLS required)". There is no fallback to clear text on that route, for anyone.
Who Signs a Family Mac's Certificate?
Ordinary TLS answers "who is answering?" with a certificate authority: a third party signs a certificate for a hostname, and the client checks the signature chain and the name. That model fits a public website. It fits a family of Macs badly. Their LAN addresses are private and change with DHCP, no public CA will sign for them, and running a private CA means a signing key that has to live somewhere and be protected forever.
Delta skips the authority entirely. Each Mac generates its own self-signed certificate once, the first time the gateway needs it: RSA 2048, valid for ten years, named delta-<label>, written under <state root>/tls/ with the folder at 0700 and the key at 0600. The key is never copied anywhere. Then the Mac publishes the SHA-256 of that certificate (over its DER bytes) as tls_sha256 in its identity document.
Here is the move that makes it work: the identity document is served on /v1/identity, and that path, like /v1/tickets, answers only over the tailnet. So the fingerprint a peer learns was delivered by the Mac it claims to describe, authenticated by WireGuard. The pin has the same root of trust as the ticket.
Pinning, Step by Step
- The calling Mac reads the peer's identity document over the tailnet (kept for five minutes) and picks a LAN route with Track 3's rules. The route carries the fingerprint it was told.
- It opens TLS with a client context that checks neither hostname nor chain:
check_hostname = False,verify_mode = CERT_NONE. That looks alarming until you read the next step. - Right after the handshake, before any request is written, it hashes the certificate the peer actually presented and compares it with the pin. Equal: proceed, and send the ticket inside the encrypted channel. Different, or no pin at all: close the connection, forget the cached identity document, and refuse the route with a named cause.
Turning off the library's verification is safe here only because a stricter check replaces it. A CA check asks "did somebody trustworthy vouch for this name?". The pin asks "is this exactly the certificate this Mac told me, over an authenticated channel, that it holds?". For two machines that already know each other, the second question is the better one. Forgetting the identity document on a mismatch matters too: if the peer legitimately regenerated its certificate (its state folder was reset), the next attempt reads the new fingerprint over the tailnet instead of failing forever on a stale pin.
This Is Not Trust on First Use
SSH's familiar prompt ("The authenticity of host … can't be established") is trust on first use: the client believes whatever key it sees the first time and complains only if it changes later. The first contact is the weak moment, and an attacker on the wire at that moment wins. Delta has no first-use moment. The pin always arrives over WireGuard, so even the very first LAN connection to a new peer is checked against a fingerprint that came from that peer.
Why the Other Two Routes Carry No TLS
| Route | Encryption | Why |
|---|---|---|
| tailnet | WireGuard (already) | A second handshake stacked inside the tunnel would add cost and no secrecy (Dad's ruling, 2026-11-09) |
| Thunderbolt bridge | none; ticket in the clear | A cable between two Macs carries nobody else's traffic; it measured 28.3 Gbit/s plain |
| shared LAN | TLS, pinned | Everything in the house shares the segment |
TLS is not free on these Macs. Delta runs on Apple's python3, whose ssl module is built on LibreSSL 2.8.3. Over 10GbE, plain HTTP moved 9.0 to 9.2 Gbit/s; TLS moved 1.9 Gbit/s on one stream and 3.6 on four. The architecture doc gives the ciphers themselves at about 400 MB/s per stream for ChaCha20 and 115 to 150 MB/s for AES-GCM, which has no hardware help in that LibreSSL; a whole transfer also hashes and writes every byte, and one stream of it measured the lower 1.9 Gbit/s. The gap between the ciphers is why the cipher list puts ChaCha20 first, and the slow single stream is why the LAN runs six workers. The same old LibreSSL is also why the key is RSA: it refused an elliptic-curve key with "no shared cipher".