Say you have a large monolithic application that you have decided to re-implement as microservices, and you have zeroed in on Istio as your Service Mesh platform.
Istio is a Service Mesh that allows managing and securing microservices. It has a policy-driven Control Plane and an Envoy-proxy based data plane.
Your monolithic application may have had its own traditional security infrastructure that supported end-user authentication and authorization. But how do you implement the same behavior with Istio in a modern, declarative, and cloud-native way? This blog will help you with that, specifically uncovering the authentication strategies.
To be concrete, say we have an internet-facing helloworld microservice deployed in Istio, how do we secure the API using Cloud Identity services such as Oracle IDCS, or Okta?
To demonstrate this, we will do the following :
istioctl verify-install -f $HOME/generated-manifest.yaml
kubectl create secret docker-registry oci-registry-secret --docker-server=iad.ocir.io\ --docker-username='[TENANCY_NAME]/oracleidentitycloudservice/[USERNAME]'\ --docker-password='<PASSWORD>' #single quotes are required. #Output : Secret oci-registry-secret created. Username above is your IDCS-originated and OCI-synced username
cd <ROOT_DIRECTORY>/helidon-quickstart-se kubectl apply -f app.yaml
kubectl get svc -n istio-system -l istio=ingressgateway\ export EXTERNAL_IP=$(kubectl get svc -n istio-system\ -l app=istio-ingressgateway -o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')
kubectl apply -f istio-http-gateway.yaml
, thus enabling traffic on port 80.
kubectl apply -f istio-virtualservice.yaml
curl -X GET http://$EXTERNAL_IP/greet
With this, our basic setup is complete. We created and Istio Mesh, deployed a microservice on it, and exposed it to the internet.
The next task, and the crux of this blog, is to secure the service.
There are two ways of enabling authentication in Istio so that only known users have access:
Istio uses Envoy Proxy as a sidecar, and delegates all the network, security, load-balancing work to Envoy.
So much so that #1 above actually ends up as an Envoy configuration in the sidecar attached to the Istio Ingress Gateway.
kubectl apply -f istio-authn-policy.yaml
, if you invoke the /greet endpoint again you’ll receive a 401 unauthorized error. The API is not open anymore.In order to access the API, now you’ll have to generate a JWT Bearer token from IDCS, and pass it as Authorization header when invoking the API :
export TOKEN=<IDCS_JWT_TOKEN> curl -X GET -H "Authorization: Bearer $TOKEN" http://$EXTERNAL_IP/greet
Exactly the same behavior as above can be reached by using Envoy Filter to setup JWT Authentication. This option allows much more configuration flexibility(as listed in the Envoy documentation here), such as fully offline JWKS URI. A sample Envoy Filter configuration is provided below.
For most of the scenarios though, using the Istio End User Authentication Policy suffices.
In this blog we described how to enable authentication in Istio microservices . In the next blog we will discuss enabling authorization as well.
Next Post