Build a Service Mesh (Envoy / Istio style) (13 scenes)
Scene 09 · mTLS — identity for both sides
TLS proves the server, mTLS proves both. The control plane mints short-lived certs that carry a stable workload identity — pod IPs are not identities.
Previously

Rate limiting and routing both want to know WHO is calling — but pod IPs change every restart, so the proxy needs a stronger answer to 'who are you' than an IP.

Scene 10
mTLS — identity for both sides
Diagram
Two sidecars facing each other, with a 'Control Plane · CA' box above them that mints short-lived certs. Each cert displays a **workload identity** — a stable name (e.g. `prod/checkout`) that the CA signs into the cert, so it survives pod restarts and IP changes — together with a TTL clock. The connection line between the sidecars shows the handshake mode: dashed/red for plaintext (no auth), grey for TLS (server-only auth), green for **mTLS** (mutual TLS — a handshake where BOTH client and server present certificates, so each side ends up with a cryptographic identity for the other). The identity-policy panel below evaluates a rule of the form 'only X may call Y' against the verified names from the handshake; it can only return ALLOWED when both sides have a cert. (Real-world footnote: the workload-name format is SPIFFE; the cert is sometimes called an SVID; the enforcement-mode resource in Istio is PeerAuthentication.)
Control Plane · CAissues short-lived workload certsSIDECAR Aprod/orderenvoy proxyno identitySIDECAR Bprod/checkoutenvoy proxyno identityplaintext · no authIDENTITY POLICYonly prod/order may call prod/checkoutDENIED · no client identitycannot enforce identity policy on plaintext trafficPlaintext: neither side knows the other's name beyond an IP. The policy cannot be enforced.
The control plane mints a short-lived cert for each sidecar, carrying a workload name — `prod/order` on the left, `prod/checkout` on the right. Watch the handshake: A presents its cert, B verifies it, B presents its cert, A verifies. Both sides finish with a cryptographic identity for the other — not an IP.
Implementation
Sidecar.onBoot
control plane (Istiod) signs a short-lived SVID per workload
1def on_sidecar_boot():
2 # workload name comes from the pod's serviceAccount + namespace
3 workload_name = spiffe_id(pod.namespace, pod.service_account)
4 # e.g. spiffe://cluster.local/ns/prod/sa/checkout
5 csr = generate_csr(workload_name)
6 svid = control_plane.sign(csr, ttl=24h) # via SDS
7 install(svid.cert, svid.key)
8 schedule_renewal(at = svid.expiry - 1h)
Sidecar.onConnect
mutual handshake — each side verifies the other's SVID
1def on_connect(peer):
2 peer.cert = peer.present_cert()
3 ok = verify_signed_by_ca(peer.cert)
4 ok = ok and (peer.cert.expiry > now())
5 if not ok:
6 close(peer, reason='untrusted')
7 # SPIFFE ID baked into the cert by the CA
8 peer.workload_name = peer.cert.spiffe_id
9 # mutual: the server ALSO presents its cert to the client
10 present_my_cert(peer)
Policy.evaluate
'X may call Y' needs a cryptographic name for X
1def evaluate(req):
2 caller = req.peer.workload_name # from peer's SVID
3 callee = self.workload_name
4 allowed = rules.lookup(caller, callee)
5 if not allowed:
6 return DENY # 403
7 return ALLOW
8# TLS gives the client a name for the callee.
9# mTLS gives the server a name for the CALLER — the new bit.