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

> Demonstrates configuring Istio mutual TLS by deploying a sample app, enforcing cluster wide PeerAuthentication in STRICT mode, showing non injected pod failures and enabling sidecar injection

In this lesson you will configure authentication on an Istio Service Mesh by:

* Deploying a Hello World application.
* Enforcing peer authentication (mTLS) globally.
* Observing how non-Istio workloads are affected when mTLS is required.
* Enabling sidecar injection to allow pods to communicate using mTLS.

Relevant concepts: Istio sidecar injection, Envoy proxy, PeerAuthentication, mTLS, namespace labeling.

Links and references

* [Istio Service Mesh course](https://learn.kodekloud.com/user/courses/istio-service-mesh)
* [Istio documentation — Authentication](https://istio.io/latest/docs/tasks/security/authentication/)

## Verify namespace sidecar injection

Confirm the `default` namespace has Istio sidecar injection enabled:

```bash theme={null}
root@controlplane ~ ➜  kubectl get ns --show-labels
NAME               STATUS   AGE     LABELS
default            Active   3m4s    istio-injection=enabled,kubernetes.io/metadata.name=default
istio-system       Active   91s     kubernetes.io/metadata.name=istio-system
kube-node-lease    Active   3m4s    kubernetes.io/metadata.name=kube-node-lease
kube-public        Active   3m4s    kubernetes.io/metadata.name=kube-public
kube-system        Active   3m4s    kubernetes.io/metadata.name=kube-system
```

## Deploy the Hello World application

Apply your Hello World manifests (Deployment + Service). Verify the pods in `default` namespace are running and have two containers (app + Envoy sidecar):

```bash theme={null}
root@controlplane ~ ➜  kubectl get pods -n default
NAME                              READY   STATUS    RESTARTS   AGE
helloworld-v1-7459d7b54b-f7cxb    2/2     Running   0          46s
helloworld-v2-654d97458-r84kp     2/2     Running   0          46s
```

Confirm the Hello World Service and its port (5000):

```bash theme={null}
root@controlplane ~ ➜  kubectl get svc -n default
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)     AGE
helloworld   ClusterIP   10.108.92.244    <none>        5000/TCP    62s
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP     4m15s
```

## Create a test namespace and run a plain (non-Istio) pod

Create a new namespace `test` and run an NGINX pod without sidecar injection:

```bash theme={null}
root@controlplane ~ ➜  kubectl create ns test
namespace/test created

root@controlplane ~ ➜  kubectl run test --image=nginx -n test --restart=Never
pod/test created

root@controlplane ~ ➜  kubectl get pods -n test
NAME   READY   STATUS    RESTARTS   AGE
test   1/1     Running   0          10s
```

From the `test` pod (which is NOT Istio-injected), curl the Hello World service in `default`. Plaintext traffic is permitted by default, so this should succeed:

```bash theme={null}
root@controlplane ~ ➜  kubectl exec -ti -n test test -- curl helloworld.default.svc:5000/hello
Hello version: v2, instance: helloworld-v2-654d97458-r84kp
```

## Enforce mTLS cluster-wide using PeerAuthentication

By default, Istio does not enforce mTLS mesh-wide. To require mTLS for all cluster traffic, create a global `PeerAuthentication` resource in the `istio-system` namespace with `STRICT` mode.

Create `peer_auth_global.yaml`:

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

Apply the resource and confirm it exists:

```bash theme={null}
root@controlplane ~ ➜  kubectl apply -f peer_auth_global.yaml
peerauthentication.security.istio.io/default created

root@controlplane ~ ➜  kubectl get peerauthentications.security.istio.io -A
NAMESPACE      NAME      MODE    AGE
istio-system   default   STRICT  10s
```

## Observe effect: non-injected pod cannot communicate

After enabling strict mTLS globally, the non-injected `test` pod (no Envoy sidecar) cannot perform TLS-mutual communication and will be rejected.

Retry the curl from the `test` pod:

```bash theme={null}
root@controlplane ~ ➜  kubectl exec -ti -n test test -- curl --head helloworld.default.svc:5000/hello
curl: (56) Recv failure: Connection reset by peer
command terminated with exit code 56
```

Reason: the global `PeerAuthentication` requires mTLS, but the `test` pod does not have an Envoy sidecar and cannot speak mTLS.

## Enable sidecar injection for the test namespace and recreate the pod

Use `istioctl analyze` to get a recommendation (it will point out that `test` is not injection-enabled):

```bash theme={null}
root@controlplane ~ ➜  istioctl analyze -n test
Info [IST0102] (Namespace test) The namespace is not enabled for Istio injection. Run 'kubectl label namespace test istio-injection=enabled' to enable it, or 'kubectl label namespace test istio-injection=disabled' to explicitly mark it as not needing injection.
```

Label the namespace to enable automatic sidecar injection, then delete and recreate the `test` pod so it receives an Envoy proxy:

```bash theme={null}
root@controlplane ~ ➜  kubectl label namespace test istio-injection=enabled
namespace/test labeled

root@controlplane ~ ➜  kubectl delete pod test -n test
pod "test" deleted

root@controlplane ~ ➜  kubectl run test --image=nginx -n test --restart=Never
pod/test created

root@controlplane ~ ➜  kubectl get pods -n test
NAME   READY   STATUS    RESTARTS   AGE
test   2/2     Running   0          10s
```

Now the `test` pod has two containers (app + Envoy sidecar) and can perform mTLS to the helloworld service.

## Verify successful mTLS communication

Retry the curl; Envoy now handles mTLS and returns a successful HTTP response:

```bash theme={null}
root@controlplane ~ ➜  kubectl exec -ti -n test test -- curl --head helloworld.default.svc:5000/hello
HTTP/1.1 200 OK
server: envoy
date: Tue, 15 Apr 2025 18:12:06 GMT
content-type: text/html; charset=utf-8
content-length: 60
x-envoy-upstream-service-time: 122
```

This confirms the pod with an Envoy sidecar can communicate successfully under a global STRICT mTLS policy.

## Quick reference: common commands and resources

| Task | Command / Resource |
| - | - |
| List namespaces with labels | `kubectl get ns --show-labels` |
| Enable injection on a namespace | `kubectl label namespace <name> istio-injection=enabled` |
| Create namespace | `kubectl create ns <name>` |
| Run one-off pod | `kubectl run <name> --image=<image> -n <ns> --restart=Never` |
| Apply PeerAuthentication | `kubectl apply -f peer_auth_global.yaml` |
| Analyze Istio config | `istioctl analyze -n <namespace>` |
| Check PeerAuthentication resources | `kubectl get peerauthentications.security.istio.io -A` |

Note: when you put JSON or objects in tables, wrap them in backticks, e.g. `[{ "object": "person" }]`.

<Callout icon="lightbulb" color="#1CB2FE">
  Enabling `istio-injection=enabled` on a namespace does not retroactively inject sidecars into existing pods — delete and recreate pods to pick up the Envoy sidecar. Also ensure the `PeerAuthentication` API version (`security.istio.io/v1beta1`) matches your Istio control-plane version; this is commonly used in recent Istio releases.
</Callout>

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/certified-kubernetes-security-specialist-cks/module/7431dd03-f5c2-4ebb-b94a-2d35615bbd8c/lesson/728ca19f-c434-4360-a8b0-81482e5b3668" />

  <Card title="Practice Lab" icon="flask-conical" cta="Learn more" href="https://learn.kodekloud.com/user/courses/certified-kubernetes-security-specialist-cks/module/7431dd03-f5c2-4ebb-b94a-2d35615bbd8c/lesson/28fcbda4-2156-4800-9e94-d2090a4f50ba" />
</CardGroup>


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