Istio Authentication -Part 1

Abirami T
5 min readApr 21, 2021

--

Introduction

Istio is a service mesh for your microservices, which is designed for observability, routing, and resilience to traffic. It secures both north-south traffic and east-west traffic. North-south traffic is traffic entering (ingress) and exiting (egress) the service mesh. Istio handles north-south traffic through ingress and egress gateways, and traffic routing is managed by virtual services.

East-west traffic is traffic within the mesh, typically service-to-service. Istio’ s Envoy proxy manages east-west traffic, running as a sidecar in the Kubernetes pod of the service it is protecting.

Authentication

There are two types of authentication provided by Istio.

  • Peer Authentication
    For service-to-service authentication.
  • Request Authentication
    For end-user authentication. Using JSON Web Tokens (JWT)

In this article we will be exploring Istio peer authentication .

Pre-requisite

  1. Cluster Environment created with EKS or KOPS
  2. Kubectl installed
  3. Istio installed
  4. Need Public key to access the cluster nodes
Service to Service — Workflow

The above diagram depicts the workflow of our sample microservice.

Deploy application into four different namespaces namely istio-servicea, istio-serviceb, servicec and istio-serviced.
* istio-servicea→ pods with manually injected istio sidecars
* istio-serviceb → pods with manually injected istio sidecars
* servicec → pods with no istio sidecar
* istio-serviced→ pods with manually injected istio sidecars

service-b,service-c,service-d running on different namespaces invoke service-a running on istio-servicea namespace.

Also service-e running on different namespaces invoke welcome-app running on istio-servicea namespace.

Create namespace

kubectl create ns istio-servicea
kubectl create ns istio-serviceb
kubectl create ns servicec
kubectl create ns istio-serviced
kubectl get namespaces

Verify that Namespace is created properly by executing the following command.

Side Car Injection

This will instruct Istio to automatically inject Envoy proxy when we deploy our application in the same namespace.

kubectl label namespace istio-servicea istio-injection=enabled
kubectl label namespace istio-serviceb istio-injection=enabled
kubectl label namespace istio-serviced istio-injection=enabled

Deploy Services

kubectl create -f serviceaccount.yaml
kubectl create -f service-a.yaml
kubectl create -f welcome-app.yaml
kubectl create -f service-b.yaml
kubectl create -f service-c.yaml
kubectl create -f service-d.yaml
kubectl create -f service-e.yaml
kubectl create -f serviced-ns-istio-serviceb.yaml
kubectl create -f servicee-ns-servicec.yaml

Note:
# The YAML files required for this setup is available in the GitHUB repository
#You need to run the kubectl commands from within the folder where YAML files are present.
Or else please do provide the appropriate folder path while running the kubectl commands.

kubectl command — Application service

After deploying the application, we can see that Istio has added a sidecar for every pod created.

kubectl command — Application pods

To get the details of the container run the following command.

kubectl describe pod podname -n namespace
kubectl describe pod service-a-58479bc7bd-vf4mz -n istio-servicea

Now we will be able to see both application container as well as proxy container in our pod.

Before Peer Authentication

Both sidecar enabled and sidecar not enabled services can access all services where sidecar is enabled.

We used ClusterIP which is the simplest type, and default one in kubernetes cluster.
ClusterIP will not enable the application to be accessed from internet. So to run the application we need to login to the particular node where service is being deployed.

Use the public key to connect to the EKS cluster node and access the application using curl command as shown below.

Metrics — Before Peer Authentication

Namespace Level

Policy to allow mTLS traffic for all workloads under namespace istio-servicea.

kubectl create -f mtlspolicy.yaml
kubectl get peerauthentication.security.istio.io/default -n istio-servicea

Note: mTLS STRICT mode is enabled globally, for namespace istio-servicea.
Since servicec namespace has no sidecar, plain text is sent which is rejected by namespace istio-servicea.

Metrics — Istio Namespace Level

Workload Specific

Policies to allow both mTLS & plaintext traffic for all workloads under namespace istio-servicea, but require mTLS for workload service-a.

kubectl create -f peer.yaml
Metrics — Istio Workload Specific

Note: mTLS STRICT mode is enabled globally, for workload service-a running on namespace istio-servicea.
Except service-a all other workload running on this namespace can be accessed by both sidecar enabled and sidecar not enabled services running
on different namespaces.

Authorization Policy

Istio Authorization Policy enables access control on workloads in the mesh.

In our example, we have 2 services namely service-b and service-d running on namespace istio-service-b where side car is injected.
Both services can access service-a running on namespace istio-service-a where side car is enabled. In certain cases, we need particular service can access our workload, but all other services should not.
For that we need to enable Istio Authorization Policy .
In our case we allows requests from
service account “cluster.local/ns/istio-serviceb/sa/auth-test-sa”
to access the workload with “GET” method.

kubectl create -f peer.yaml
kubectl create -f AuthorizationPolicy.yaml
kubectl get authorizationpolicy -n istio-servicea

Specify service account in your deployment yaml file under spec section.

service-b enabled with Service Account
service-d where Service Account not enabled
Metrics — Istio Authorization Policy

Reference

Istio-PeerAuthentication

Istio-Authorization Policy

Conclusion

We have now successfully enabled Istio PeerAuthentication for our application , we will see how to implement Request Authentication for external request in next article.

--

--