Authentication JWT

- By: Thomas Jungbauer ( Lastmod: 2021-08-14 )

Welcome to tutorial 10 of OpenShift 4 and Service Mesh, where we will discuss authentication with JWT. JSON Web Token (JWT) is an open standard that allows to transmit information between two parties securely as a JSON object. It is an authentication token, which is verified and signed and therefore trusted. The signing can be achieved by using a secret or a public/private key pair.

Service Mesh can be used to configure a policy which enables JWT for your services.

Preparation

Be sure that you have at least the Gateway and VirtualService configured:

oc get istio-io -n tutorial

Which should return the following:

NAME                                                     AGE
gateway.networking.istio.io/ingress-gateway-exampleapp   45h

NAME                                                 HOST             AGE
destinationrule.networking.istio.io/recommendation   recommendation   29h

NAME                                                            GATEWAYS                       HOSTS   AGE
virtualservice.networking.istio.io/ingress-gateway-exampleapp   [ingress-gateway-exampleapp]   [*]     45h

Run some texample traffic, to be sure that our application is still working as expected

export GATEWAY_URL=$(oc -n istio-system get route istio-ingressgateway -o jsonpath='{.spec.host}')
sh ~/run.sh 1000 $GATEWAY_URL
# 0: customer => preference => recommendation v2 from '3cbba7a9cde5': 31622
# 1: customer => preference => recommendation v1 from 'f11b097f1dd0': 33056
# 2: customer => preference => recommendation v2 from '3cbba7a9cde5': 31623
# 3: customer => preference => recommendation v1 from 'f11b097f1dd0': 33057
# 4: customer => preference => recommendation v2 from '3cbba7a9cde5': 31624
# 5: customer => preference => recommendation v1 from 'f11b097f1dd0': 33058

Enabling End-User Authentication

To test this feature we will need a valid token (JWT). More details can be found at the Istio example

All we need to create a Policy object

apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
  name: "jwt-example"
spec:
  targets:
  - name: customer
  origins:
  - jwt:
      issuer: "testing@secure.istio.io"
      jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.2/security/tools/jwt/samples/jwks.json" (1)
  principalBinding: USE_ORIGIN
1 Path to test a public key

After a few seconds the requests will fail with an "authentication failed" error:

sh ~/run.sh 1000 $GATEWAY_URL
# 0: Origin authentication failed.
# 1: Origin authentication failed.
# 2: Origin authentication failed.
# 3: Origin authentication failed.
# 4: Origin authentication failed.
# 5: Origin authentication failed.

In Kiali we see a 100% failure rate.

Kiali JWT
Figure 1. Kiali: failing because of authentication error.

To be able to connect to our application we first need to fetch a valid token and put this into the header while sending curl.

export GATEWAY_URL=$(oc -n istio-system get route istio-ingressgateway -o jsonpath='{.spec.host}')
export TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/release-1.1/security/tools/jwt/samples/demo.jwt -s)

for x in $(seq 1 1000);
  do curl --header "Authorization: Bearer $TOKEN" $GATEWAY_URL -s;
done

In Kiali the traffic is now working again and authenticated.

Kiali JWT2
Figure 2. Kiali: Traffic authenticated.

Clean Up

Remove the policy again, to be ready for the next tutorial.

oc delete policy jwt-example -n tutorial