← Back to Blog

Enforcing mTLS across Microservices using Istio Service Mesh



Enforcing mTLS across Microservices using Istio Service Mesh

Why Zero-Trust Matters in Kubernetes

Relying solely on perimeter security inside a Kubernetes cluster introduces significant risk. Once an attacker bypasses the ingress layer, they can typically move laterally across the flat network with minimal resistance.

A zero-trust model addresses this vulnerability by requiring every internal request to be authenticated, authorized, and encrypted. Istio simplifies this process: it offloads mutual TLS (mTLS) from your application code into Envoy sidecar proxies deployed alongside your pods.

Istio serves as the Certificate Authority (CA), manages automatic certificate rotation, and configures Envoy sidecars to establish encrypted TLS tunnels for all inter-service communication.

---

1. Enabling Strict mTLS Cluster-Wide

By default, Istio operates in PERMISSIVE mode to allow workload migration without disrupting existing plaintext connections. To enforce full encryption, update the configuration to STRICT using a PeerAuthentication policy.

# strict-mtls.yaml
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
 name: default-strict-mtls
 namespace: istio-system # Applying to istio-system makes it cluster-scoped
spec:
 mtls:
 mode: STRICT

Breakdown:

  • kind: PeerAuthentication: Governs how sidecars handle incoming traffic.
  • namespace: istio-system: Applying this policy within Istio's root namespace enforces mTLS globally across the entire service mesh.
  • mode: STRICT: Instructs sidecars to reject any unencrypted HTTP or raw TCP connection. Workloads will accept only connections encrypted with a valid Istio certificate.

---

2. Restricting Access with AuthorizationPolicies

While mTLS handles encryption and authentication (verifying who is issuing the request), access control requires explicit authorization rules (verifying what actions they are permitted to execute).

Istio assigns SPIFFE (Secure Production Identity Framework for Everyone) identities based on Kubernetes ServiceAccounts. You can utilize these identities within an AuthorizationPolicy to secure sensitive endpoints.

# authz-policy-finance.yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: require-frontend-identity
 namespace: finance-app
spec:
 selector:
 matchLabels:
 app: payment-processor # Target workload
 action: ALLOW
 rules:
 - from:
 - source:
 # Require a valid cryptographically verified SPIFFE ID
 principals: ["cluster.local/ns/frontend-app/sa/frontend-service-account"]
 to:
 - operation:
 methods: ["POST"]
 paths: ["/api/v1/process-payment"]

Breakdown:

  • action: ALLOW: When an ALLOW rule is defined, Istio defaults to denying all unspecified requests.
  • selector.matchLabels: Applies this security policy specifically to the payment-processor pod in the finance-app namespace.
  • source.principals: Validates the client's identity using its mTLS certificate. In this configuration, only requests originating from frontend-service-account within the frontend-app namespace are accepted, preventing IP spoofing attempts.
  • operation: Restricts access strictly to POST /api/v1/process-payment, blocking all other HTTP methods and endpoints.

---

Combining strict mTLS with SPIFFE-based authorization rules delivers robust service-level security without requiring modifications to your application source code.