Skip to main content
Cloud & AI Hub
Browse
Glossary AI Directory Playgrounds Models Prompts Explainers Strategy Matrix Benchmark Decoder
advanced 10 mins Read

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.