> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Service Mesh Security Encryption and Identity

> Explains using Istio mTLS and SPIFFE identities with PeerAuthentication and AuthorizationPolicy to encrypt pod traffic and enforce service-to-service access control in Kubernetes.

Securing a Kubernetes cluster requires layers of protection: access control (RBAC), configuration validation (admission control), and runtime constraints (Pod Security Standards). Equally important is securing pod-to-pod traffic inside the cluster so workloads cannot eavesdrop on or impersonate one another. This document shows how mutual TLS (mTLS) and service-level authorization work together in an Istio service mesh to provide encryption, strong service identity, and service-to-service access control.

Why this matters

* Kubernetes networking is plaintext by default — a compromised pod can sniff traffic on the same node.
* There is no native service identity, so one pod can pretend to be another.
* No built-in, identity-based mechanism exists to restrict which services can call which.

Istio + mTLS solves these issues by:

* Encrypting traffic in transit.
* Issuing SPIFFE-based identities to workloads.
* Enabling identity-based authentication and authorization using AuthorizationPolicy.

How Istio implements mTLS
Istio’s control plane (istiod) acts as a certificate authority that issues short-lived X.509 certificates to sidecar proxies (Envoy). Each certificate encodes a SPIFFE identity (trust domain, namespace, service account). When Pod A calls Pod B, the local Envoy sidecars perform mutual TLS: they validate each other’s certificate and establish an encrypted connection. Applications keep sending plain HTTP to their local sidecar; all encryption and authentication happen at the sidecar layer, so no application changes are required.

![A three-panel diagram titled "How Istio mTLS Works" showing Istiod (control plane) issuing SPIFFE certificates to sidecar proxies and Envoy sidecars at the source and destination. Arrows show the source sidecar intercepts and encrypts outgoing traffic with the pod’s certificate, and the destination sidecar verifies, decrypts, and forwards it to the app.](https://mintcdn.com/kodekloud-c4ac6d9a/HODaDxDN1KDeTnSr/images/Prep-Course-Certified-Cloud-Native-Platform-Engineering-CNPE/Security-and-Policy-Enforcement/Service-Mesh-Security-Encryption-and-Identity/istio-mtls-sidecar-istiod-spiffe-diagram.jpg?fit=max\&auto=format\&n=HODaDxDN1KDeTnSr\&q=85\&s=67c9c575eff932343ed796a71b4d3c67)

PeerAuthentication — configuring mTLS mode
Istio’s PeerAuthentication resource controls mTLS behavior. The important field is `spec.mtls.mode`. The common modes are:

| Mode | Behavior | When to use |
| - | - | - |
| `STRICT` | Requires mTLS for all inbound connections to the scoped target | Production / strongest security |
| `PERMISSIVE` | Accepts both mTLS and plaintext | Migration period to avoid disruptions |
| `DISABLE` | Turns off mTLS for the scoped target | Rare cases, debugging or legacy workloads |

Example: enable strict mTLS for the `payments` namespace

```yaml theme={null}
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: payments
spec:
  mtls:
    mode: STRICT
```

Scope and precedence

* A `PeerAuthentication` named `default` in `istio-system` affects the entire mesh.
* A `default` resource in a target namespace affects only that namespace.
* Adding a `selector` allows you to scope mTLS to specific workloads (label selector), enabling fine-grained rollout.

If you want to enable strict mTLS for a namespace, create a `PeerAuthentication` named `default` in that namespace with `mode: STRICT`.

![A presentation slide titled "PeerAuthentication: Configuring mTLS" that shows examples for mesh-wide, namespace, and workload configurations. It includes labeled boxes explaining where to apply settings (e.g., "Apply in istio-system namespace", "Apply in target namespace") and outcomes like "Entire mesh uses STRICT" and "payments namespace uses STRICT."](https://mintcdn.com/kodekloud-c4ac6d9a/HODaDxDN1KDeTnSr/images/Prep-Course-Certified-Cloud-Native-Platform-Engineering-CNPE/Security-and-Policy-Enforcement/Service-Mesh-Security-Encryption-and-Identity/peerauthentication-configuring-mtls-examples.jpg?fit=max\&auto=format\&n=HODaDxDN1KDeTnSr\&q=85\&s=c9e7c9d39cf8313df63a647f0f0d9395)

AuthorizationPolicy — service-level RBAC
PeerAuthentication provides encryption and identity. AuthorizationPolicy uses that identity to allow or deny service-to-service calls. Policies use SPIFFE principals (the identity issued by Istiod) to control which callers are allowed to access a service and which operations they may perform.

Example: allow only the `web-app` service account in the `frontend` namespace to call the `payment-api` service, limiting operations to GET and POST under `/api/*`:

```yaml theme={null}
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-api-only
  namespace: payments
spec:
  selector:
    matchLabels:
      app: payment-api

  rules:
  - from:
    - source:
        principals:
        - "cluster.local/ns/frontend/sa/web-app"

    to:
    - operation:
        methods: ["GET", "POST"]
        paths: ["/api/*"]
```

Note: AuthorizationPolicy path-matching syntax can vary across Istio versions. Some control planes accept glob-style patterns like "/api/\*", while others require explicit match types (for example, using a `prefix` or `regex` match). If you see validation errors, switch to the explicit match form your Istio version expects (e.g., a prefix or regex-based match).

These two resources together

* PeerAuthentication guarantees callers present a verifiable SPIFFE identity.
* AuthorizationPolicy evaluates those identities and enforces fine-grained allow/deny rules.

![A presentation slide titled "AuthorizationPolicy: Service-to-Service" explaining that mTLS provides identity which AuthorizationPolicy uses for access control. It warns that without mTLS strict mode pods can fake identities, while SPIFFE certificates prove the caller.](https://mintcdn.com/kodekloud-c4ac6d9a/HODaDxDN1KDeTnSr/images/Prep-Course-Certified-Cloud-Native-Platform-Engineering-CNPE/Security-and-Policy-Enforcement/Service-Mesh-Security-Encryption-and-Identity/authorizationpolicy-mtls-prevents-identity-spoofing.jpg?fit=max\&auto=format\&n=HODaDxDN1KDeTnSr\&q=85\&s=94042a97c65416319cd4f5a9159e76a4)

Note: Some Istio versions and examples show SPIFFE IDs with the `spiffe://` prefix (for example, `spiffe://cluster.local/ns/frontend/sa/web-app`). In many AuthorizationPolicy examples the prefix is omitted (`cluster.local/ns/frontend/sa/web-app`) — both forms are commonly seen, but check your [Istio Service Mesh](https://learn.kodekloud.com/user/courses/istio-service-mesh) version and use the form that your control plane expects.

How to verify your configuration

1. Confirm the PeerAuthentication resource exists for the target namespace:

```bash theme={null}
kubectl get peerauthentication -n payments
```

Sample output:

```bash theme={null}
NAME      AGE
default   2d
```

2. Inspect effective mTLS and policy configuration for a pod with `istioctl` (replace the pod name):

```bash theme={null}
istioctl x describe pod payment-api-xxx -n payments
```

This command shows which PeerAuthentication and AuthorizationPolicy resources apply to the pod and the effective mTLS mode.

3. Verify sidecar injection and readiness. A 2/2 READY indicates the application container plus the Envoy sidecar are present:

```bash theme={null}
kubectl get pods -n payments
```

Sample output:

```bash theme={null}
NAME                READY   STATUS
payment-api-xxx     2/2     Running
```

A 1/1 READY indicates the sidecar is not injected or is unhealthy; mTLS will not be enforced for that pod.

Migration pattern (safe rollout)

* Step 1: Enable automatic sidecar injection on the namespace:

```bash theme={null}
kubectl label namespace payments istio-injection=enabled
# Redeploy or rollout restart workloads to inject sidecars
kubectl rollout restart deployment -n payments
```

* Step 2: Start with a `PeerAuthentication` in `PERMISSIVE` mode at the appropriate scope so non-mesh workloads can still communicate.
* Step 3: Monitor traffic and validate sidecar behavior using observability tools like Kiali, `istioctl`, and application logs.
* Step 4: When confident, switch the `PeerAuthentication` to `STRICT` to reject plaintext connections.
* Step 5: Add `AuthorizationPolicy` resources to enforce service-level access control.

We always test before enforcing. Use permissive mode and observability to validate communication and certificate issuance before moving to strict enforcement.

![The slide titled "Migrating to STRICT mTLS" outlines a four-step process to enable mutual TLS in Istio. Steps: enable sidecar injection (label namespace istio-injection=enabled), start with PeerAuthentication in PERMISSIVE mode, monitor traffic with Kiali/istioctl to ensure sidecars and mTLS, then switch to STRICT to reject plaintext.](https://mintcdn.com/kodekloud-c4ac6d9a/HODaDxDN1KDeTnSr/images/Prep-Course-Certified-Cloud-Native-Platform-Engineering-CNPE/Security-and-Policy-Enforcement/Service-Mesh-Security-Encryption-and-Identity/istio-mtls-permissive-to-strict.jpg?fit=max\&auto=format\&n=HODaDxDN1KDeTnSr\&q=85\&s=2e534d87ad43334e5f9b5b4c2fc966b6)

Summary

* Default cluster traffic is plaintext and vulnerable to eavesdropping and impersonation.
* Istio mTLS provides transparent encryption plus SPIFFE identities via sidecars and certificates.
* Control mTLS with the `PeerAuthentication` resource (`spec.mtls.mode`): use `STRICT` for production, `PERMISSIVE` for migration.
* Enforce service-to-service access using `AuthorizationPolicy` based on SPIFFE identities.
* Verify sidecar injection (2/2 READY) and examine effective policies with `istioctl` and observability tooling before switching a namespace to `STRICT`.

Links and references

* [Istio Service Mesh course — KodeKloud](https://learn.kodekloud.com/user/courses/istio-service-mesh)
* [SPIFFE — Secure Production Identity Framework for Everyone](https://spiffe.io/)
* [Envoy Proxy](https://www.envoyproxy.io/)
* [Istio: istioctl diagnostic tools](https://istio.io/latest/docs/ops/diagnostic-tools/istioctl/)
* [Kiali observability console](https://kiali.io/)

> **[Watch Video](https://learn.kodekloud.com/user/courses/prep-course-certified-cloud-native-platform-engineer-cnpe/module/35a7fadb-02d8-4557-a819-2e4dcfa970cc/lesson/19c3a421-318d-40c7-aeb3-45eebb398056)**


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.