Istio's zero-trust story — encryption and identity with no app code — and why this repo turns it off.
Your win: explain how Istio does mutual TLS and workload identity
(PeerAuthentication, SPIFFE, istiod as CA) — the cert-exam material — and articulate why this
repo deliberately leaves it off, and what it does instead.
How Istio does mTLS (the concept)
The headline feature of a service mesh's security story is mutual TLS
between sidecars, with no application changes. When it's on, every service-to-service
call is encrypted and both ends prove their identity.1
Three pieces make it work:
istiod is the Certificate Authority. It issues each workload a
short-lived certificate; the sidecars rotate them automatically.
Identity is SPIFFE. The cert encodes
spiffe://<trust-domain>/ns/<namespace>/sa/<service-account> —
built from the Pod's Kubernetes ServiceAccount (Course 2 L12). So a
workload's identity is its ServiceAccount, cryptographically.
PeerAuthentication sets the mode.STRICT (require mTLS),
PERMISSIVE (accept mTLS or plaintext — the migration mode), or
DISABLE. It can be mesh-wide, per-namespace, or per-workload.2
Authentication ≠ authorization
mTLS answers "who is calling?" (it proves identity). It does not
answer "is this caller allowed to do that?" — that's AuthorizationPolicy (Lesson 10).
Keep the two separate: mTLS = identity + encryption; authz = access control on top.
What this repo actually does — and doesn't
Anchor — mTLS is OFF here
Be precise, because it's the opposite of the textbook default. In this repo:
enableAutoMtls: false
(deployments/helm/platforms/istio/istiod-values.yaml:13) —
in base/stag/prod (only local sets it true).
No PeerAuthentication exists anywhere in the repo — so
there's no STRICT/PERMISSIVE policy; in-cluster traffic is effectively plaintext.
outboundTrafficPolicy.mode: ALLOW_ANY
(:11-12) — egress to unknown hosts is allowed too.
So this is not a zero-trust mesh. The security boundary is the edge
(the ingress Gateway's TLS termination, Lesson 5), and inside the cluster traffic is trusted.
Why a team might choose this — and the trade-off
In-mesh mTLS costs CPU/latency on every hop and adds operational complexity (cert rotation,
debugging TLS failures). A team may judge that a private cluster with edge TLS is a good
enough boundary for now, and skip it. That's a legitimate engineering call — but
it means a compromised Pod can talk to any other, unencrypted. The honest interview answer:
"We use Istio for routing + edge TLS + telemetry, not in-mesh mTLS — a deliberate
trade-off; turning on STRICT PeerAuthentication would be the zero-trust upgrade."(Worth confirming the reasoning with the platform team.)
The identity is still there, waiting
Even with mTLS off, every Pod still has its ServiceAccount identity (used for GCP Workload
Identity, Course 2 L12). So enabling STRICT mTLS later wouldn't require new identities — the
SPIFFE names derive from ServiceAccounts that already exist. The door is built; it's just not
locked.
Backend use case
Backend use case: this is the real explanation for `enableAutoMtls: false`, the absence of backend PeerAuthentication, and the repo’s edge-first security boundary.
Common mistake
Common mistake: giving a textbook Istio zero-trust answer without acknowledging that this repo deliberately opts out of that model for backend traffic.
In plain English
Plain English: Istio can provide identity and mTLS between workloads, but this repo mostly chooses not to enable that posture for backend traffic.
Check yourself (from memory)
Q1. In Istio, a workload's identity is derived from its…
istiod (the CA) issues a SPIFFE cert
…/ns/<ns>/sa/<sa> — identity = ServiceAccount.
Q2. The policy that sets mTLS to STRICT/PERMISSIVE is…
PeerAuthentication controls peer (workload) mTLS mode.
AuthorizationPolicy is access control; RequestAuthentication is end-user JWTs.
Q3. In this repo, in-mesh mTLS is…
enableAutoMtls: false and no PeerAuthentication —
routing + edge TLS + telemetry mesh, not zero-trust.
How Istio does mTLS/identity — and this repo's opt-out.
recall, then click to reveal
Istio mTLS = encrypted + mutually-authenticated service-to-service calls,
NO app code. THREE PIECES: (1) ISTIOD is the CA, issues short-lived certs, sidecars rotate
them; (2) IDENTITY = SPIFFE spiffe://td/ns/<ns>/sa/<sa> from the Pod's
ServiceAccount; (3) PEERAUTHENTICATION sets mode — STRICT / PERMISSIVE (migration) / DISABLE,
mesh/ns/workload scoped. mTLS proves WHO (auth); AuthorizationPolicy decides ALLOWED (Lesson
10). REPO (opposite of default): enableAutoMtls: false
(istiod-values.yaml:13), NO PeerAuthentication, outboundTrafficPolicy:
ALLOW_ANY → NOT zero-trust; boundary is the EDGE (ingress TLS), in-cluster plaintext.
Trade-off: saves CPU/complexity but a compromised Pod can reach any other. Identities (SAs)
already exist, so STRICT is a future upgrade, not a rebuild.
Want to see what enabling STRICT mTLS would take here, or how PERMISSIVE mode enables a safe
migration? Ask me.