> ## 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.

# Demo mTLS with Istio

> Guide to enabling and enforcing mutual TLS and authorization in an Istio service mesh, injecting Envoy sidecars, applying PeerAuthentication and AuthorizationPolicy, and validating with istioctl and tests.

RBAC controls who can interact with the Kubernetes API. But traffic between services inside the cluster is a different surface: by default pod-to-pod communication is unauthenticated and unencrypted. A compromised service can freely talk to any other service.

Mutual TLS (mTLS) solves both problems: both sides of a connection verify each other's identity using certificates, and all traffic is encrypted in transit. Istio implements mTLS transparently with Envoy sidecars so your application code does not need to change.

In this lesson you'll:

* Inspect the cluster and Istio control plane.
* Enable automatic sidecar injection for the `mesh-demo` namespace.
* Enforce STRICT mTLS using a PeerAuthentication.
* Use an AuthorizationPolicy to restrict which services can call the Payment API.
* Validate behavior with `istioctl analyze` and simple curl tests.

***

## 1. Verify cluster and workloads

Check Istio control-plane pods and workloads in the `mesh-demo` namespace:

```bash theme={null}
kubectl get pods -n istio-system
kubectl get pods -n mesh-demo
```

Example output:

```bash theme={null}
# control plane
NAME                                         READY   STATUS    RESTARTS   AGE
istio-egressgateway-8455f4dc86-9xm62         1/1     Running   0          2m50s
istio-ingressgateway-767bc4d85b-t6x9k        1/1     Running   0          2m50s
istiod-659d96fcdd-xrr5n                      1/1     Running   0          3m

# mesh-demo workloads (initially single-container pods)
NAME                                         READY   STATUS    RESTARTS   AGE
order-api-764df948dc-7xztj                   1/1     Running   0          3m14s
payment-api-756c646cc7-dxmx2                 1/1     Running   0          3m14s
web-frontend-8588697ccf-xvbfm                1/1     Running   0          3m14s
```

Analyze the namespace for Istio configuration suggestions:

```bash theme={null}
istioctl analyze -n mesh-demo
```

You may see messages like:

```text theme={null}
Info [IST0102] (Namespace mesh-demo) The namespace is not enabled for Istio injection. Run 'kubectl label namespace mesh-demo istio-injection=enabled' to enable it...
Info [IST0118] (Service mesh-demo/order-api) Port name  (port: 80, targetPort: 80) doesn't follow the naming convention of Istio port.
...
```

These are informational warnings that help harden your mesh configuration.

***

## 2. Enable automatic sidecar injection

Enable automatic sidecar injection for the `mesh-demo` namespace:

```bash theme={null}
kubectl label namespace mesh-demo istio-injection=enabled
```

Note: The label affects newly created or restarted pods. Restart existing deployments to inject sidecars:

```bash theme={null}
kubectl rollout restart deployment/web-frontend deployment/payment-api deployment/order-api -n mesh-demo
```

After the restart the pods should show 2/2 READY indicating Envoy sidecars are present:

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

Example output:

```bash theme={null}
NAME                                       READY   STATUS    RESTARTS   AGE
order-api-796cf8d48-znsvn                  2/2     Running   0          1m
payment-api-85f848f4b0-tnvdm               2/2     Running   0          1m
web-frontend-6ff7969d9b-dv5rr              2/2     Running   0          1m
```

The sidecar transparently intercepts inbound and outbound traffic for the pod without modifying application code.

***

## 3. Inspect the effective mTLS mode for a pod

Use `istioctl x describe pod` to see the effective PeerAuthentication mode for a workload. Provide the pod name:

```bash theme={null}
istioctl x describe pod -n mesh-demo web-frontend-6ff7969d9b-dv5rr
```

Example output before changing policy:

```text theme={null}
Pod: web-frontend-6ff7969d9b-dv5rr
  Pod Revision: default
  Pod Ports: 80 (app)
  -----------
Service: web-frontend
  Port: 80/auto-detect targets pod port 80
  -----------
Effective PeerAuthentication:
  Workload mTLS mode: PERMISSIVE
```

Permissive mode allows both mTLS and plaintext connections. To enforce mTLS for all traffic in a namespace, apply a PeerAuthentication resource with `mode: STRICT`.

***

## 4. Enforce STRICT mTLS in the namespace

Create a PeerAuthentication that sets mTLS to STRICT for the `mesh-demo` namespace. Save this as `peer-auth-strict.yaml`:

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

Apply it:

```bash theme={null}
kubectl apply -f peer-auth-strict.yaml
```

Confirm the resource:

```bash theme={null}
kubectl describe peerauthentications.security.istio.io default -n mesh-demo
```

Example output:

```text theme={null}
Name:         default
Namespace:    mesh-demo
API Version:  security.istio.io/v1beta1
Kind:         PeerAuthentication
Spec:
  Mtls:
    Mode:  STRICT
```

Re-check a pod to verify the effective mode:

```bash theme={null}
istioctl x describe pod -n mesh-demo web-frontend-6ff7969d9b-dv5rr
```

You should now see:

```text theme={null}
Effective PeerAuthentication:
  Workload mTLS mode: STRICT
```

Enabling STRICT mTLS immediately will reject plaintext clients. Ensure all clients in the mesh have sidecars and valid identities before applying to production.

***

## 5. AuthorizationPolicy — restrict who can call the Payment API

mTLS handles encryption and identity verification, but not which services may call a particular API. Use Istio's AuthorizationPolicy to control access.

The example below allows only the `web-frontend` service account to call `payment-api` endpoints under `/api/*` using `GET` and `POST`. Save as `authz-policy.yaml`:

```yaml theme={null}
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: payment-api-policy
  namespace: mesh-demo
spec:
  selector:
    matchLabels:
      app: payment-api
  rules:
  - from:
    - source:
        principals:
        - cluster.local/ns/mesh-demo/sa/web-frontend
    to:
    - operation:
        methods: ["GET", "POST"]
        paths: ["/api/*"]
```

Key points:

* `selector.matchLabels` scopes the policy to pods labeled `app: payment-api`.
* `source.principals` uses the Istio/SPIFFE identity format: `cluster.local/ns/<namespace>/sa/<serviceaccount>`. Istio binds the TLS certificate identity to the Kubernetes service account.
* The `operation` block restricts HTTP methods and paths.

Apply the policy:

```bash theme={null}
kubectl apply -f authz-policy.yaml
```

***

## 6. Test the AuthorizationPolicy

From the `order-api` deployment (not authorized), attempt to call the Payment API. This request should be rejected:

```bash theme={null}
kubectl exec -n mesh-demo deployment/order-api -- \
  curl -s -o /dev/null -w "%{http_code}" \
  http://payment-api.mesh-demo.svc.cluster.local/api/pay
```

Expected output:

```text theme={null}
403
```

From the `web-frontend` deployment (authorized), call the same endpoint. The policy will allow the request; the application may return 404 if the path does not exist, but the important part is the policy decision:

```bash theme={null}
kubectl exec -n mesh-demo deployment/web-frontend -- \
  curl -s -o /dev/null -w "%{http_code}" \
  http://payment-api.mesh-demo.svc.cluster.local/api/pay
```

Expected example output:

```text theme={null}
404
```

A 404 means the request passed Istio authorization but the application returned Not Found. The key outcome: request from `web-frontend` is allowed while the same request from `order-api` is rejected with 403. Istio enforces decisions at the sidecar, rejecting unauthorized requests before they reach the application container.

This explicit authentication and authorization model is core to a zero-trust networking approach.

***

## 7. Final validation and troubleshooting

Run `istioctl analyze` as a preflight to catch configuration issues (missing injection label, selector mismatches, port naming conventions, etc.):

```bash theme={null}
istioctl analyze -n mesh-demo
```

Typical informational outputs to address:

```text theme={null}
Info [IST0118] (Service mesh-demo/order-api) Port name (port: 80, targetPort: 80) doesn't follow the naming convention of Istio port.
Info [IST0118] (Service mesh-demo/payment-api) Port name (port: 80, targetPort: 80) doesn't follow the naming convention of Istio port.
Info [IST0118] (Service mesh-demo/web-frontend) Port name (port: 80, targetPort: 80) doesn't follow the naming convention of Istio port.
```

Use these messages to iteratively harden your configuration before promoting changes to production.

***

## Commands and resources (at-a-glance)

| Purpose | Command / Resource |
| - | - |
| List Istio control plane pods | `kubectl get pods -n istio-system` |
| List workloads in namespace | `kubectl get pods -n mesh-demo` |
| Analyze Istio config for namespace | `istioctl analyze -n mesh-demo` |
| Enable sidecar injection | `kubectl label namespace mesh-demo istio-injection=enabled` |
| Restart deployments to inject sidecars | `kubectl rollout restart deployment/... -n mesh-demo` |
| Show effective PeerAuthentication for pod | `istioctl x describe pod -n mesh-demo <pod-name>` |
| Apply PeerAuthentication (STRICT mTLS) | `kubectl apply -f peer-auth-strict.yaml` |
| Apply AuthorizationPolicy | `kubectl apply -f authz-policy.yaml` |

***

## Summary

* Istio sidecars (Envoy) provide transparent mTLS for pod-to-pod traffic.
* Enable automatic injection on a namespace and restart workloads to inject proxies.
* Use `PeerAuthentication` to enforce STRICT mTLS across a namespace or per-workload.
* Use `AuthorizationPolicy` to explicitly control which identities (service accounts) can call particular services and operations.
* Use `istioctl analyze` and `istioctl x describe pod` to validate and troubleshoot your security posture.

Links and references

* Istio documentation: [https://istio.io/](https://istio.io/)
* Istio security concepts (mTLS, PeerAuthentication, AuthorizationPolicy): [https://istio.io/latest/docs/tasks/security/](https://istio.io/latest/docs/tasks/security/)
* Kubernetes documentation: [https://kubernetes.io/docs/](https://kubernetes.io/docs/)

> **[Watch Video](https://learn.kodekloud.com/user/courses/prep-course-certified-cloud-native-platform-engineer-cnpe/module/35a7fadb-02d8-4557-a819-2e4dcfa970cc/lesson/64424caf-3564-4c76-93f1-0d88101072d6)**

> **[Practice Lab](https://learn.kodekloud.com/user/courses/prep-course-certified-cloud-native-platform-engineer-cnpe/module/35a7fadb-02d8-4557-a819-2e4dcfa970cc/lesson/caedb06f-ceb3-4c51-9c37-be0a7855e26b)**


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