This topic provides answers to some frequently asked questions (FAQs) about JSON Web Token (JWT).
What JWT algorithms does ASM support?
A Service Mesh (ASM) instance of a version earlier than V1.13 only supports the RSA algorithm.
An ASM instance of V1.13 or later supports ES256, ES384, ES512, HS256, HS384, HS512, RS256, RS384, RS512, PS256, PS384, PS512, and EdDSA algorithms.
How do I use the jwksUri parameter in ASM?
You can use the jwksUri parameter only in an ASM instance of V1.13 or later. The method varies depending on the scenario:
When you want to specify the address of a service in the Container Service for Kubernetes (ACK) cluster managed by ASM, you can use the jwksUri parameter directly.
When you want to specify the address of a service that is not deployed in the ACK cluster managed by ASM, you must configure the corresponding service entry.
In this example, the official JWT and JSON Web Key Set (JWKS) of Istio are used. For more information, see the sample JWT and JWKS of Istio.
jwksUri specifies the address of a service in the ACK cluster managed by ASM
In this example, jwksUri specifies the address of the nginx-proxy service in a cluster managed by ASM. You can obtain the public keys of jwks over port 80 from the address/get_jwks
. The jwksUri
is http://nginx-proxy.{Namespace}.svc.cluster.local:80/get_jwks
.
Run the following command to check whether get_jwks of the cluster is usable:
curl nginx-proxy/get_jwks
Expected output:
{ "keys":[ {"e":"AQAB","kid":"DHFbpoIUqrY8t2zpA2qXfCmr5VO5ZEr4RzHU_-e****","kty":"RSA","n":"xAE7eB6qugXyCAG3yhh7pkDkT65p****-P7KfIupjf59vsdo91bSP9C8H07pSAGQ****_xFj9VswgsCg4R6otmg5PV2He95lZdHtOcU5****_pbhLdKXbi66GlVeK6ABZOUW3WYt****-91gVuoeJT_DwtGGcp4ignkgXfkiE****-4sfb4qdt5oLbyVpmW6x9cfa7vs2WTfURiCrBoU****_-4WTiULmmHSGZHOjzwa8WtrtOQGsAFjIbno85jp6MnGGGZPYZ****_b3y5u-YpW7ypZrvD8BgtKVjgtQgZhLAGezMt0ua3DRrWnKqT****_EyxOGuHJrLsn00****"}]}
The preceding output indicates that get_jwks is usable.
Create a request authentication policy.
Log on to the ASM console.
In the left-side navigation pane, choose .
On the Mesh Management page, find the ASM instance that you want to configure. Click the name of the ASM instance or click Manage in the Actions column.
In the left-side navigation pane, choose .
On the RequestAuthentication page, click Create from YAML. On the page that appears, select the Namespace where you want to create the request authentication policy and a Template, copy the following content to the YAML editor, and then click Create.
apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: jwt-example namespace: foo spec: jwtRules: - issuer: testing@secure.istio.io jwksUri: 'http://nginx-proxy/get_jwks' selector: matchLabels: app: httpbin
Use kubectl to connect to the data plane based on the information in the kubeconfig file, and run the following command to access the HTTPBin application:
# Set the Token environment variable. TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/release-1.14/security/tools/jwt/samples/demo.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode - # Access the httpbin application from the pod where the sleep application resides by using a request with a JWT. kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/headers" -sS -o /dev/null -H "Authorization: Bearer $TOKEN" -w "%{http_code}\n"
If status code
200
is returned, the operation succeeds.
jwksUri specifies the address of a service that is not deployed in the ACK cluster managed by ASM
In this example, the HTTP protocol is used. To use HTTPS to obtain JWKS, configure a destination rule for the service entry.
Create a service entry for the service.
Create a file named service-entry.yaml and copy the following content to the file:
apiVersion: networking.istio.io/v1beta1 kind: ServiceEntry metadata: name: external-svc-https namespace: foo spec: addresses: - 11.11.XX.XX # Replace this variable with your jwksUri. endpoints: - address: 11.11.XX.XX # Replace this variable with your jwksUri. hosts: - 11.11.XX.XX # Replace this variable with your jwksUri. location: MESH_EXTERNAL ports: - name: http number: 80 protocol: HTTP - name: https number: 443 protocol: HTTPS resolution: STATIC
Run the following command to create the service entry:
kubectl apply -f service-entry.yaml
(Optional) To use HTTPS to obtain JWKS, configure a destination rule for the service entry.
apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: external-svc-https namespace: foo spec: host: ${The host where ServiceEntry resides} trafficPolicy: loadBalancer: simple: ROUND_ROBIN portLevelSettings: - port: number: 443 tls: mode: SIMPLE
Create a request authentication policy.
Log on to the ASM console.
In the left-side navigation pane, choose .
On the Mesh Management page, find the ASM instance that you want to configure. Click the name of the ASM instance or click Manage in the Actions column.
In the left-side navigation pane, choose .
On the RequestAuthentication page, click Create from YAML. On the page that appears, select the Namespace where you want to create the request authentication policy and a Template, copy the following content to the YAML editor, and then click Create.
apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: jwt-example namespace: foo spec: jwtRules: - issuer: tes****@secure.istio.io jwksUri: '${Your jwksUri}' selector: matchLabels: app: httpbin
Run the following command to access the httpbin application in the pod where the sleep application resides:
# Access the httpbin application from the pod where the sleep application resides by using a request with a JWT. kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/headers" -sS -o /dev/null -H "Authorization: Bearer $TOKEN" -w "%{http_code}\n"
If status code
200
is returned, the operation succeeds.
How do I configure JWT authentication when I do not want to authenticate requests bound for specific paths?
You can set the action parameter to DENY and specify the paths when you configure the YAML file of an authorization policy in the ASM console.
Deploy a sample application and access the application.
Deploy the Bookinfo application in the ACK cluster that is added to the ASM instance. For more information, see Deploy an application in an ACK cluster that is added to an ASM instance.
Run the following commands to access the three services to ensure that all paths are accessible:
curl "http://${IP address of the ingress gateway}/productpage" -sS -o /dev/null -w "%{http_code}\n" curl "http://${IP address of the ingress gateway}/api/v1/products/0" -sS -o /dev/null -w "%{http_code}\n" curl "http://${IP address of the ingress gateway}/api/v1/products/1" -sS -o /dev/null -w "%{http_code}\n"
If status code
200
is returned in every command output, the operation succeeds.
Create a request authentication policy.
Log on to the ASM console.
In the left-side navigation pane, choose .
On the Mesh Management page, find the ASM instance that you want to configure. Click the name of the ASM instance or click Manage in the Actions column.
In the left-side navigation pane, choose .
On the RequestAuthentication page, click Create from YAML. On the page that appears, select the Namespace where you want to create the request authentication policy and a Template, copy the following content to the YAML editor, and then click Create.
apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: jwt-example namespace: istio-system spec: jwtRules: - issuer: testing@secure.istio.io jwks: >- { "keys":[ {"e":"AQAB","kid":"DHFbpoIUqrY8t2zpA2qXfCmr5VO5ZEr4RzHU_-e****","kty":"RSA","n":"xAE7eB6qugXyCAG3yhh7pkDkT65pHymX-P7KfIupjf59vsdo91bSP9C8H07pSAGQ****_xFj9VswgsCg4R6otmg5PV2He95lZdHtOcU5****_pbhLdKXbi66GlVeK6ABZOUW3WYtnNHD-91gVu****_DwtGGcp4ignkgXfkiEm4sw-4sfb4qdt5oLbyVpmW6x9cfa7vs2WTfURiCrBoU****_-4WTiULmmHSGZHOjzwa8WtrtOQGsAFjIbno85jp6MnGGGZPYZ****_b3y5u-YpW7ypZrvD8BgtKVjgtQgZhLAGezMt0ua3DRrWnKqT****_EyxOGuHJrLsn00****"}]} selector: matchLabels: app: istio-ingressgateway
This request authentication policy applies to the ingress gateway, and all the requests that pass through the gateway need to be authenticated. Requests with valid JWTs or without JWTs are allowed whereas requests with invalid JWTs are rejected.
Create an authorization policy that allows requests without JWTs to access certain paths.
You can create an authorization policy to specify that requests bound for a specific path do not need to pass JWT authentication whereas requests bound for the other paths must carry valid JWTs. In this example, requests bound for the /productpage path do not need to pass JWT authentication whereas requests bound for the other two paths must carry valid JWTs.
Log on to the ASM console.
In the left-side navigation pane, choose .
On the Mesh Management page, find the ASM instance that you want to configure. Click the name of the ASM instance or click Manage in the Actions column.
In the left-side navigation pane, choose .
On the AuthorizationPolicy page, click Create from YAML. On the page that appears, select the Namespace where you want to create the authorization policy and a Template, copy the following content to the YAML editor, and then click Create.
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: test-exclude namespace: istio-system spec: action: DENY rules: - from: - source: notRequestPrincipals: - '*' to: - operation: notPaths: - /productpage selector: matchLabels: app: istio-ingressgateway
This authorization policy also applies to the ingress gateway. A DENY rule is configured to reject all the requests without valid JWTs bound for paths except the /productpage path.
Perform an access test.
Run the following command to set the JWT to the Token environment variable:
export TOKEN=eyJhbGciOiJSUzI1NiIsImtpZCI6IkRIRmJwb0lVcXJZOHQyenBBMnFYZkNtcjVWTzVaRXI0UnpIVV8tZW52dlEiLCJ0eXAiOiJKV1****.eyJleHAiOjQ2ODU5ODk3MDAsImZvbyI6ImJhciIsImlhdCI6MTUzMjM4OTcwMCwiaXNzIjoidGVzdGluZ0BzZWN1cmUuaXN0aW8uaW8iLCJzdWIiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5p****.CfNnxWP2tcnR9q0vxyxweaF3ovQYHYZl82hAUsn21bwQd9****-LS9qd_vpdLG4Tn1A15NxfCjp5f7Q****-KC9PJqYpgGbaXhaGx7bEdFWjcwv3nZz****__ZpaCERdwU7igUmJqYGBYQ51vr2njU9ZimyKkfDe3axcyiBZde7G6dabliUosJvvKOPcKIWPccCg****_GNfwIip3-SsFdlR7BtbVUcqR-yv-XOxJ3Uc1MI0tz3uMiiZcyPV7sNCU4KRnemRIMHVOfuvH****_GhGbiSFzgPTAa9WTltbnarTbxudb_YEOx12JiwYToeX0DCPb43W1tzIBxgm8****
Run the following commands to access the three services:
Every request does not carry a JWT:
curl "http://${IP address of the ingress gateway}/productpage" -sS -o /dev/null -w "%{http_code}\n" 200 curl "http://${IP address of the ingress gateway}/api/v1/products/0" -sS -o /dev/null -w "%{http_code}\n" 403 curl "http://${IP address of the ingress gateway}/api/v1/products/1" -sS -o /dev/null -w "%{http_code}\n" 403
The output shows that only the /productpage path is accessible whereas the other two paths cannot be accessed and status code
403
is returned.Every request carries a JWT:
curl "http://${IP address of the ingress gateway}/productpage" -H "Authorization: Bearer $TOKEN" -sS -o /dev/null -w "%{http_code}\n" 200 curl "http://${IP address of the ingress gateway}/api/v1/products/0" -H "Authorization: Bearer $TOKEN" -sS -o /dev/null -w "%{http_code}\n" 200 curl "http://${IP address of the ingress gateway}/api/v1/products/1" -H "Authorization: Bearer $TOKEN" -sS -o /dev/null -w "%{http_code}\n" 200
Status code
200
is returned for each operation, indicating that all the three paths are accessible.