mTLS at scale

STRICT mode and the PERMISSIVE migration path.

Advanced35 min · lesson 8 of 15

Mutual TLS is the encryption-and-authentication backbone of the zero-trust data plane. At scale, the interesting questions are how you enforce it everywhere and how you migrate a running system to it without an outage.

STRICT mode and the migration path

In a mesh, mTLS is governed by a policy — Istio’s PeerAuthentication. STRICT mode requires mTLS and rejects any plaintext connection to the workloads, which is the zero-trust target: no cleartext east-west traffic is accepted. But flipping STRICT on across a live cluster would break any client not yet in the mesh, so you migrate through PERMISSIVE mode, which accepts both mTLS and plaintext. You enable the mesh everywhere, confirm via observability that all traffic is already flowing over mTLS, and only then switch to STRICT. This audit-then-enforce pattern is the same safe rollout used for every policy in the course.

migrate to STRICT mTLS safely
# Step 1 — PERMISSIVE while migrating: accept mTLS AND plaintext.
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata: { name: default, namespace: prod }
spec: { mtls: { mode: PERMISSIVE } }
# Step 2 — confirm (via Hubble/Kiali) that ALL traffic is already mTLS, then:
spec: { mtls: { mode: STRICT } } # plaintext now rejected
# A workload without a mesh identity can no longer connect.

Identity and automatic rotation

mTLS is only as strong as the identities behind the certificates. The mesh CA (istiod, or Linkerd’s identity component) issues each workload a short-lived certificate bound to its SPIFFE identity — derived from its Kubernetes service account — and rotates it automatically well before expiry, so there is no long-lived key to steal and no manual renewal to forget. This means "encrypt everything east-west" comes with strong, continuously-rotated authentication built in: each connection proves both sides’ identities, and a compromised certificate is useful only until its brief lifetime ends. Encryption without this identity would be far weaker; the two are inseparable in a well-run mesh.

mTLS at scale
1mesh CA issuescertsshort-lived, per…2PERMISSIVE(migrate)accept mTLS + plaintext3confirm alltraffic mTLSvia observability4STRICT(enforce)reject plaintext east-west
Auto-issued, auto-rotated identity certs plus a PERMISSIVE→STRICT rollout give encrypted, authenticated east-west without an outage.
Flipping STRICT before migrating breaks plaintext clients
Enabling STRICT mTLS while some clients still speak plaintext (not yet meshed, or an external caller) will sever those connections instantly. Always run PERMISSIVE first, verify via observability that traffic is fully mTLS, and handle non-mesh callers (an ingress or exception) before enforcing STRICT.