A TLS (Transport Layer Security) handshake agrees on a fresh symmetric key and verifies the server certificate for every connection. It is an expensive process, carrying round trips and asymmetric computation. Working with TLS in practice, you find three places where this basic behavior alone falls short: the handshake cost of reconnecting to the same server, a trust scope that authenticates only the server and leaves the client anonymous, and the renewal burden of certificates that have an expiry.

None of the three changes the protocol itself. They are an operational layer that resumes, extends, and automates the basic handshake.

Session Resumption

The core cost of a handshake is key agreement, which is where the asymmetric computation and round trips go. Yet a client often reconnects to a server it reached moments ago. Renegotiating the key from scratch each time is wasteful. Session resumption reuses the secret agreed on in a previous session to abbreviate the handshake.

There are two approaches.

Session ID has the server store the session state. On the first handshake the server assigns an ID to the session and keeps that session’s key and state in its own memory. When the client reconnects and presents the ID, the server looks up the stored state and skips key agreement. The downside is that the server has to hold the state of every active session. As sessions grow the memory burden grows with them, and multiple servers behind a load balancer have to share that state.

Session Ticket hands the state storage to the client. The server encrypts the session state with a key only it knows, packages it as a ticket, and gives it to the client. On reconnection the client presents the ticket, and the server decrypts it to restore the session state. The server only manages the single ticket encryption key, so it stores no per-session state regardless of how many sessions there are.

TLS 1.3 unified the two into a PSK (Pre-Shared Key). It uses a secret derived from the previous handshake as the pre-shared key for the next connection.

sequenceDiagram
    participant C as Client
    participant S as Server

    Note over C,S: Initial handshake
    S->>C: NewSessionTicket (issues session ticket)
    Note over C,S: ── later reconnection ──
    C->>S: ClientHello + ticket / PSK
    S->>C: ServerHello (key agreement skipped)
    Note over C,S: Resumed via abbreviated handshake

0-RTT

Session resumption reduces round trips but does not eliminate them. TLS 1.3 goes one step further. A client holding a PSK can put application data in the very first packet of a reconnection. Since it waits for zero round trips (RTT, round-trip time), this is called 0-RTT, or early data. Reconnection latency all but disappears.

There is a cost. Early data is sent before the handshake completes, so it does not get the full protection that ordinary TLS data has. It is especially vulnerable to replay attacks. If an attacker captures an early data packet and sends it to the server again as-is, the server may process it as a legitimate request twice. A payment or state-changing request running twice becomes a problem.

So 0-RTT comes with constraints. The rule is to allow only idempotent requests in early data: read-only requests whose result doesn’t change when processed twice, such as a GET. On the server side, anti-replay defenses record a ticket as single-use or apply a short time window to filter out replays. State-changing requests are safer sent outside 0-RTT.

mTLS

TLS so far authenticates only the server. The client verifies the server’s certificate, but the server never checks who the client is. On the public web this is enough; the user authenticates separately at the application layer, through something like a login.

In a controlled environment, though, you sometimes want to authenticate the connection itself. mTLS (mutual TLS) is two-way authentication. During the handshake the server also demands a certificate from the client with a CertificateRequest, and the client presents its certificate along with a signature made using its private key. Since a certificate is public and can be copied, this signature is what proves the client is the actual owner of the certificate. The connection is established only when both sides verify each other’s certificate and signature.

sequenceDiagram
    participant C as Client
    participant S as Server

    C->>S: ClientHello
    S->>C: ServerHello + Certificate
    S->>C: CertificateRequest
    C->>S: Certificate + CertificateVerify (cert + signature)
    Note over C,S: Both certificates and signatures verified mutually
    Note over C,S: Connection established

It is used mainly for internal communication between microservices or in a service mesh. When service A calls service B, it confirms through a certificate that the other side is a trusted service. Because identity is verified at connection setup rather than in application code, a request that has broken into the internal network can be filtered at the network layer.

ACME

Certificates have an expiry. Once expired they must be renewed, and a neglected expired certificate breaks connections. Back when certificates were issued and renewed by hand, missing an expiry and taking down a service was a frequent accident.

ACME (Automatic Certificate Management Environment) is a protocol that automates this issuance and renewal. Let’s Encrypt spread widely by issuing free certificates through it. A client like certbot talks to a CA (Certificate Authority) over ACME and fetches certificates automatically.

The heart of it is domain ownership validation. The CA has to confirm that whoever requested the certificate actually controls that domain. ACME mainly uses two challenges.

HTTP-01 has you place a CA-specified token at a particular web path on the domain. The CA reaches that path and checks the token, proving control of the domain.

DNS-01 has you register the token as a DNS TXT record on the domain. The CA queries DNS to verify it. It works without a web server and is used to issue wildcard certificates.

flowchart TD
    A["ACME client
certbot, etc."] -->|certificate request| CA["CA
Let's Encrypt"] CA -->|issues challenge| A A -->|"place token
HTTP-01: web path
DNS-01: TXT record"| D["Domain"] CA -.verifies.-> D CA -->|issues certificate| A

Once validation passes, the CA issues the certificate. The client repeats this process automatically before expiry to renew. With no human in the loop, outages from expiry disappear.

Wrapping Up

If the handshake is the foundation that builds a secure channel, session resumption handles its repeated cost, mTLS handles the trust scope that authentication reaches, and ACME handles the operational burden of certificates. None of the three changes the TLS protocol; they resume, extend, and automate its behavior. Once you understand the basic handshake, most of the TLS configuration you meet in practice reads as a variation on these three.

References