# TLS and certificates

> How a client proves it’s talking to the real server and agrees a key no one else can read — and what mTLS adds.

Concept · Application & cloud security · https://levelcode.org/concepts/tls

**TLS** (Transport Layer Security; SSL is its retired predecessor) secures a connection with three guarantees:

- **Confidentiality:** nobody on the network path can read the traffic.
- **Integrity:** nobody can change it undetected.
- **Authentication:** the client is talking to the server it meant to reach, not an impostor.

HTTPS is HTTP over TLS. So are secure database connections, gRPC and most service-to-service traffic.

## The TLS 1.3 handshake, simplified

```text
Client → Server: ClientHello (supported ciphers, key share)
Server → Client: ServerHello (chosen cipher, key share), certificate, signature, Finished
Client → Server: Finished                      ← one round trip, then encrypted data
```

1. Both sides do a **key exchange** (ephemeral Diffie–Hellman). Each derives the same session key without ever sending it, and recording the traffic now won't let anyone decrypt it later, even if the server's long-term key is stolen (*forward secrecy*).
2. The server proves its identity with a **certificate**, and a signature showing it holds the matching private key.

TLS 1.3 needs one round trip on top of TCP's own; QUIC/HTTP/3 merges the two. See [TCP vs UDP](https://levelcode.org/concepts/tcp-vs-udp).

## Certificates and trust

A certificate binds a **public key** to **names** (`api.example.com`, `*.example.com`) and is signed by a **certificate authority**. The client checks:

- the **chain** leads from the server's certificate, through intermediates, to a root CA in its trust store;
- the **name** matches the host it dialled;
- the certificate **hasn't expired** (and hasn't been revoked).

Most certificate outages are expiries. Automate issuance and renewal with ACME (Let's Encrypt, cert-manager) and alert well before expiry. Servers must send the **full intermediate chain**; a missing intermediate works in some clients and fails in others.

## mTLS: both sides prove who they are

In normal TLS only the server presents a certificate. In **mutual TLS**, the client presents one too, so the server knows *which service* is calling, not just that the channel is encrypted. Service meshes issue short-lived certificates to every workload and run mTLS automatically. That's the basis of zero-trust networking inside a cluster. See the [service mesh lesson](https://levelcode.org/roadmaps/devsecops/service-mesh).

## Common mistakes

- **Turning verification off** (`InsecureSkipVerify: true`, `verify=False`, `curl -k`) "just for now." That keeps the encryption but drops authentication, so anyone in the middle can impersonate the server.
- **Terminating TLS at the load balancer** and sending plaintext to backends over a network you don't control.
- **Enabling old versions or ciphers** for compatibility. Allow TLS 1.2 and 1.3 only.
