Skip to main content

TLS / HTTPS & the Secure Handshake

Level 1: Level 1: Foundations & Mental Modelsmedium30 mintlssecuritymtls

TLS 1.3 is a 1-RTT handshake; cut cost with resumption and reuse, choose the termination point deliberately, and use mTLS for service identity.

Update your TLS mental model to 1.3

Most engineers carry stale TLS mental models from the 1.2 era. Update them: TLS 1.3 is a 1-RTT handshake, and 0-RTT on resumption. That single fact changes the latency math for every HTTPS design.

What the handshake does in one round trip: the client sends a ClientHello with its key share and supported ciphers; the server responds with its key share, certificate, and Finished; the client verifies and can send application data on its next flight. One RTT and you have a shared symmetric key. The certificate lets the client verify server identity: the cert is signed by a Certificate Authority (CA) the client trusts, forming a chain up to a root CA in the client's trust store. SNI (Server Name Indication) is the client telling the server, in the clear, which hostname it wants, so one IP hosting many tenants (a CDN, a shared LB) can present the right certificate.

Interview nuance: certificate expiry is one of the most common real-world outage causes (an unrotated cert on a load balancer takes the whole site down at midnight). Always mention automated rotation (ACME/Let's Encrypt, AWS ACM) as part of a TLS design.

Check yourself
TLS 1.3 0-RTT lets a returning client send application data in its very first flight, saving a full round trip. Should you enable it for every endpoint, including 'POST /charge'?

Cutting handshake cost

  • Session resumption: after a first full handshake, the server issues a session ticket; a returning client presents it and skips the certificate exchange, dropping to a cheaper handshake.
  • 0-RTT (early data): on resumption, TLS 1.3 lets the client send application data in its very first flight, before the handshake completes, saving a full round trip. The caveat that interviewers will push on: 0-RTT early data is replayable. An attacker who captures it can resend it, so you must only allow 0-RTT for idempotent requests (GET, or writes guarded by an idempotency key). Never let a non-idempotent POST /charge ride on 0-RTT.
  • Connection reuse: the cheapest handshake is the one you do not do. Keep connections warm so you handshake once and reuse.

Where do you terminate TLS?

Three common choices; the tradeoff is latency/operational-simplicity versus how far encryption reaches:

  • Terminate at the edge/LB: the ALB, CDN POP, or Envoy front proxy decrypts, and traffic behind it is plaintext (or re-encrypted). This offloads crypto from app servers, centralizes cert management, and lets the L7 proxy read requests for routing. The cost: the internal network sees plaintext, which is only acceptable if that network is trusted.
  • End-to-end / passthrough: TLS is not terminated until the app, so even the LB cannot read the request (it must be an L4 LB). Maximum confidentiality, but you lose L7 routing and pay crypto on every app server.
  • Re-encrypt inside the mesh: terminate at the edge for routing, then open a fresh TLS connection to the backend. This is the common enterprise answer: edge features plus encrypted internal hops.

mTLS (mutual TLS) extends this: not only does the client verify the server, the server verifies the client's certificate too. This gives cryptographic service-to-service identity, the backbone of zero-trust architectures and service meshes (Istio, Linkerd) where "is this caller really the orders service" cannot rely on network location. Each service gets a short-lived cert from an internal CA, and the mesh rotates them automatically.

Recap: TLS 1.3 is a 1-RTT handshake (0-RTT on resumption, but only for idempotent requests due to replay), you cut cost with session resumption and connection reuse, you choose termination by trading internal visibility for edge features, and mTLS gives services cryptographic identity for zero-trust.

Check yourself

Match each requirement from a design review to the TLS termination choice it points to.

Route on paths and headers; the internal network is trusted, so plaintext behind the LB is acceptable
Not even the load balancer may read requests; confidentiality beats everything
Want L7 routing at the edge and encrypted hops inside too
Centralize certificate management and take crypto load off the app servers

Apply

Your turn

The task this lesson builds to.

Design TLS termination for a multi-region service: decide where you terminate, how you cut handshake latency, and how services authenticate each other.

Think about

  1. Where do you terminate TLS and what is the latency vs security tradeoff?
  2. How do session resumption and 0-RTT cut handshake cost, and what is the replay caveat?
  3. Why use mTLS between services?

Practice

Make it stick

A second problem on the same idea, so it survives past today.

Design the TLS and identity architecture for a bank's payment microservices where a compliance rule forbids plaintext on any wire, even inside the VPC, and every service call must be cryptographically attributable to a specific service identity for audit. Explain termination, key rotation, and how you keep the added crypto from blowing the latency budget.

Think about

  1. Where does plaintext exist in an edge-terminate design, and why does that violate the rule here?
  2. How do short-lived, auto-rotated certificates change the blast radius of a leaked key?
  3. Which crypto cost dominates (handshakes or steady-state), and what amortizes it?