How Service Meshes Enforce mTLS Between Microservices
How Istio and Linkerd use sidecar proxies, certificate rotation, and mutual TLS to encrypt and authenticate all service-to-service communication.
Introduction
In a microservices architecture, dozens of services communicate over the internal cluster network. Without encryption, a compromised node can sniff internal API traffic. Without authentication, a rogue service can impersonate a legitimate one. Service meshes like Istio and Linkerd solve both problems by intercepting all pod-to-pod TCP traffic through a sidecar proxy, applying mutual TLS (mTLS) transparently β without requiring any changes to application code.
Step-by-Step: How Istio mTLS Works
flowchart TD
A["1. Sidecar Injection"]
B["2. Certificate Issuance (SPIFFE Identity)"]
C["3. Mutual TLS Handshake"]
D["4. Authorization Policy"]
E["5. Observability"]
A --> B
B --> C
C --> D
D --> E
Step 1: Sidecar Injection
When Istio is installed, it injects an Envoy sidecar proxy into every pod via a mutating admission webhook:
# Namespace-level auto-injection
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
istio-injection: enabled # Trigger automatic sidecar injection
Every pod now has two containers: the application container and the Envoy proxy. iptables rules redirect all inbound and outbound traffic through Envoy on ports 15001 (outbound) and 15006 (inbound).
Step 2: Certificate Issuance (SPIFFE Identity)
Istioβs control plane (istiod) acts as a Certificate Authority. Each sidecar receives an X.509 certificate encoding a SPIFFE (Secure Production Identity Framework For Everyone) identity:
SPIFFE URI: spiffe://cluster.local/ns/production/sa/payment-service
Format: spiffe://<trust-domain>/ns/<namespace>/sa/<service-account>
Certificates are rotated automatically every 24 hours (configurable). The private key never leaves the pod β only the CSR goes to istiod.
Step 3: Mutual TLS Handshake
When Service A calls Service B, both sidecars perform a TLS handshake where both sides present certificates:
Standard TLS: Client verifies Server cert (one-way)
Mutual TLS: Client verifies Server cert AND Server verifies Client cert (two-way)
Handshake:
Client Envoy β Server Envoy: ClientHello
Server Envoy β Client Envoy: ServerHello + Server Cert (SPIFFE identity)
Client Envoy β Server Envoy: Client Cert (SPIFFE identity) + ClientFinished
Server Envoy validates client cert against trust bundle
[Encrypted session established]
Step 4: Authorization Policy
After identity is established via mTLS, Istio applies AuthorizationPolicy to control which services can call which:
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: payment-service-policy
namespace: production
spec:
selector:
matchLabels:
app: payment-service
action: ALLOW
rules:
- from:
- source:
principals:
- "cluster.local/ns/production/sa/checkout-service"
to:
- operation:
methods: ["POST"]
paths: ["/charge", "/refund"]
Only the checkout-service service account can make POST requests to payment endpoints β all other traffic is denied at the proxy level, before it reaches the application.
Step 5: Observability β Traffic Without Code Changes
Because all traffic flows through Envoy, Istio automatically generates:
Metrics: Request rate, error rate, latency P50/P95/P99 per service pair
Traces: Distributed traces with automatic propagation of trace headers
Logs: Access logs with mTLS peer identity, response codes, latency
# View mTLS status for all services
istioctl x authz check <pod-name>
# Check certificate for a sidecar
istioctl proxy-config secret <pod-name> -o json | jq '.dynamicActiveSecrets'
# Visualize service mesh traffic in Kiali
kubectl port-forward -n istio-system svc/kiali 20001:20001
Key Takeaways
- Service meshes inject Envoy sidecar proxies via Kubernetes mutating admission webhooks β zero application code changes required.
- SPIFFE identities (tied to Kubernetes service accounts) are encoded in X.509 certificates, providing cryptographic service identity.
- Mutual TLS authenticates both client and server β a compromised service cannot impersonate another because it lacks the correct certificate.
- AuthorizationPolicy objects provide microsegmentation: only explicitly allowed service-account-to-service-account calls are permitted.
- Certificate rotation happens automatically every 24 hours β the control plane pushes new certificates before expiry with zero connection disruption.
Historical figures, architectures, and capabilities are for informational purposes only. Not technical, professional, legal, or financial advice. Sources: Research papers, developer documentation.