--- title: Basic Authentication Policy description: Shows you how to use Istio authentication policy to setup mutual TLS and basic end-user authentication. weight: 10 aliases: - /docs/tasks/security/istio-auth.html --- Through this task, you will learn how to: * Use authentication policy to setup mutual TLS. * Use authentication policy to do end-user authentication. ## Before you begin * Understand Istio [authentication policy](/docs/concepts/security/authn-policy/) and related [mutual TLS authentication](/docs/concepts/security/mutual-tls/) concepts. * Have a Kubernetes cluster with Istio installed, without global mutual TLS enabled (e.g use `install/kubernetes/istio-demo.yaml` as described in [installation steps](/docs/setup/kubernetes/quick-start/#installation-steps), or set `global.mtls.enabled` to false using [Helm](/docs/setup/kubernetes/helm-install/)). * For demo, create two namespaces `foo` and `bar`, and deploy [httpbin](https://github.com/istio/istio/tree/master/samples/httpbin) and [sleep](https://github.com/istio/istio/tree/master/samples/sleep) with sidecar on both of them. Also, run another sleep app without sidecar (to keep it separate, run it in `legacy` namespace) ```command $ kubectl create ns foo $ kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n foo $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n foo $ kubectl create ns bar $ kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n bar $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n bar $ kubectl create ns legacy $ kubectl apply -f samples/sleep/sleep.yaml -n legacy ``` * Verifying setup by sending an http request (using curl command) from any sleep pod (among those in namespace `foo`, `bar` or `legacy`) to either `httpbin.foo` or `httpbin.bar`. All requests should success with HTTP code 200. For example, here is a command to check `sleep.bar` to `httpbin.foo` reachability: ```command $ kubectl exec $(kubectl get pod -l app=sleep -n bar -o jsonpath={.items..metadata.name}) -c sleep -n bar -- curl http://httpbin.foo:8000/ip -s -o /dev/null -w "%{http_code}\n" 200 ``` Conveniently, this one-liner command iterates through all combinations: ```command $ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done sleep.foo to httpbin.foo: 200 sleep.foo to httpbin.bar: 200 sleep.bar to httpbin.foo: 200 sleep.bar to httpbin.bar: 200 sleep.legacy to httpbin.foo: 200 sleep.legacy to httpbin.bar: 200 ``` * Also verify that there are no authentication policy in the system ```command $ kubectl get policies.authentication.istio.io --all-namespaces No resources found. ``` ## Enable mutual TLS for all services in a namespace Run this command to set namespace-level policy for namespace `foo`. ```bash cat < Note: * This rule is based on the assumption that there is no other destination rule in the system. If it's not the case, you need to modify traffic policy in existing rules accordingly. * `*.foo.svc.cluster.local` matches all services in namespace `foo`. * With `ISTIO_MUTUAL` TLS mode, Istio will set the path for key and certificates (e.g `clientCertificate`, `privateKey` and `caCertificates`) according to its internal implementation. Run the same testing command as above. You should see requests from `sleep.legacy` to `httpbin.foo` start to fail, as the result of enabling mutual TLS for `httpbin.foo` but `sleep.legacy` doesn't have a sidecar to support it. On the other hand, for clients with sidecar (`sleep.foo` and `sleep.bar`), Istio automatically configures them to using mTLS where talking to `http.foo`, so they continue to work. Also, requests to `httpbin.bar` are not affected as the policy is only effective on the `foo` namespace. ```command $ for from in "foo" "bar" "legacy"; do for to in "foo" "bar"; do kubectl exec $(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name}) -c sleep -n ${from} -- curl http://httpbin.${to}:8000/ip -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done sleep.foo to httpbin.foo: 200 sleep.foo to httpbin.bar: 200 sleep.bar to httpbin.foo: 200 sleep.bar to httpbin.bar: 200 sleep.legacy to httpbin.foo: 000 command terminated with exit code 56 sleep.legacy to httpbin.bar: 200 ``` > If destination rule above is not created, all requests to `httpbin.foo` will fail as client side are not configured correctly to switch to use mutual TLS. ## Enable mutual TLS for single service `httpbin.bar` Run this command to set another policy only for `httpbin.bar` service. Note in this example, we do **not** specify namespace in metadata but put it in the command line (`-n bar`). They should work the same. ```bash cat < ``` Also, for convenience, expose `httpbin.foo` via ingress (for more details, see [ingress task](/docs/tasks/traffic-management/ingress/)). ```bash cat <