Alibaba Cloud Service Mesh (ASM) allows you to configure a JSON Web Token (JWT) authorization policy to authenticate the source of requests. This method is also called end-user authentication. After you configure a JWT authorization policy, the system checks whether the header of a received request contains a valid JWT. Only requests that contain valid JWTs can access services. This topic shows how to configure a JWT authorization policy to control service access for requests from the ingress gateway in ASM. This ensures that only requests with valid JWTs can access services by using the ingress gateway.

Prerequisites

Background information

The following example shows how to use a request authentication policy to control access to the httpbin service for requests from the ingress gateway. This ensures that only requests with valid JWTs can access the service. However, in this case, the requests without JWTs can also access the service. In view of this, you can use an authorization policy to further control service access for requests. This involves the following two scenarios:
  • Use an authorization policy to specify that a request can access the service by using the ingress gateway only if the request contains a JWT.
  • Use an authorization policy to specify that a request can access the service by using the ingress gateway only if the request contains a JWT issued by a specific issuer.

Step 1: Deploy a sample service

  1. Enable automatic sidecar injection for the default namespace.
    1. Log on to the ASM console.
    2. In the left-side navigation pane, choose Service Mesh > Mesh Management.
    3. On the details page of the ASM instance, choose ASM Instance > Global Namespace in the left-side navigation pane.
    4. On the Global Namespace page, find the default namespace and click Enable Automatic Sidecar Injection in the Automatic Sidecar Injection column.
    5. In the Submit message, click OK.
  2. Deploy the sample service.
    1. Connect to your Container Service for Kubernetes (ACK) cluster by using kubectl.
    2. Create an httpbin.yaml file that contains the following content:
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: httpbin
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: httpbin
        labels:
          app: httpbin
          service: httpbin
      spec:
        ports:
        - name: http
          port: 8000
          targetPort: 80
        selector:
          app: httpbin
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: httpbin
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: httpbin
            version: v1
        template:
          metadata:
            labels:
              app: httpbin
              version: v1
          spec:
            serviceAccountName: httpbin
            containers:
            - image: docker.io/kennethreitz/httpbin
              imagePullPolicy: IfNotPresent
              name: httpbin
              ports:
              - containerPort: 80
    3. Run the following command to create the httpbin application:
      kubectl apply -f httpbin.yaml -n default

Step 2: Create a gateway rule and a virtual service

  1. Create a gateway rule.
    1. Log on to the ASM console.
    2. In the left-side navigation pane, choose Service Mesh > Mesh Management.
    3. 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.
    4. On the details page of the ASM instance, choose Traffic Management > DestinationRule in the left-side navigation pane. On the DestinationRule page, click Create from YAML.
    5. On the Create page, select default from the Namespace drop-down list and copy the following content to the code editor. Then, click Create.
      apiVersion: networking.istio.io/v1beta1
      kind: Gateway
      metadata:
        name: httpbin-gateway
        namespace: default
      spec:
        selector:
          istio: ingressgateway
        servers:
          - hosts:
              - '*'
            port:
              name: http
              number: 80
              protocol: HTTP
  2. Create a virtual service.
    1. On the details page of the ASM instance, choose Traffic Management > VirtualService in the left-side navigation pane. On the VirtualService page, click Create from YAML.
    2. On the Create page, select default from the Namespace drop-down list and copy the following content to the code editor. Then, click Create.
      apiVersion: networking.istio.io/v1beta1
      kind: VirtualService
      metadata:
        name: httpbin
        namespace: default
      spec:
        gateways:
          - httpbin-gateway
        hosts:
          - '*'
        http:
          - route:
              - destination:
                  host: httpbin
                  port:
                    number: 8000

Step 3: Create a request authentication policy

  1. Create a JWK.
    1. Run the following command in OpenSSL to generate a 2048-bit Rivest-Shamir-Adleman (RSA) private key:
      openssl genrsa -out rsa-private-key.pem 2048
    2. Run the following command to generate a public key based on the private key:
      openssl rsa -in rsa-private-key.pem -pubout -out rsa-public-key.pem
    3. In the JWK to PEM Convertor online tool, select PEM-to-JWK (RSA Only), enter the public key in the Input field, and then click submit to convert the public key to a JWK.
      null
  2. Create a request authentication policy.
    1. Log on to the ASM console.
    2. In the left-side navigation pane, choose Service Mesh > Mesh Management.
    3. 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.
    4. On the details page of the ASM instance, choose Zero Trust Security > RequestAuthentication in the left-side navigation pane. On the RequestAuthentication page, click Create.
    5. On the Create page, set the parameters that are described in the following table and click Create.
      Request authentication policy
      Parameter Description
      Namespace The namespace in which you want to create the request authentication policy. Set this parameter to istio-system.
      Name The name of the request authentication policy.
      Matching Label

      The label that is used to specify the service to which the request authentication policy applies.

      Click Add Matching Label. Set the Name parameter to istio and the Value parameter to ingressgateway.

      JWT Rule Set The JWT rules. Click Add next to JWT Rule Set and set the following parameters:
      • issuer: the issuer of the JWT. Set this parameter to testing@asm.test.io.
      • audiences: the audiences of the JWT. This parameter specifies the services that can use the JWT to access the destination service. If you do not set this parameter, all services can access the destination service.
      • jwks: the information about the JWT, in the {"keys":[JWK created in Step 1]} format. For example, if the JWK that you created in Step 1 is {"kty":"RSA","e":"AQAB","kid":"59399e22-7a9a-45ed-8c76-7add786****"}, set this parameter to {"keys":[{"kty":"RSA","e":"AQAB","kid":"59399e22-7a9a-45ed-8c76-7add786****"}]}.

Step 4: Check whether the request authentication policy that you created takes effect

  1. Use the JWT tool to encode JWT request information into a JWT.
    In the Decoded section, enter the following JWT request information. Then, the JWT request information is automatically converted to a JWT in the Encode section.
    • HEADRE: Set the alg parameter to RS256, the kid parameter to the key ID of the JWK that you created, and the typ parameter to JWT.
    • PAYLOAD: Set the iss parameter to testing@asm.test.io. You can add other information based on your business requirements.
    • VERIFY SIGNATURE: Enter the public key and private key that are generated in Step 1.
    JWT
  2. Access the service by using the ingress gateway.
    1. Run the following command to access the service by using a request that contains the JWT created in Step 1:
      curl -I -H "Authorization: Bearer $TOKEN" http://{IP address of your ingress gateway}/

      Expected output:

      HTTP/1.1 200 OK
      server: istio-envoy
      date: Fri, 18 Mar 2022 07:27:54 GMT
    2. Run the following command to access the service by using a request that contains an invalid JWT:
      curl -I  -H "Authorization: Bearer invalidToken" http://{IP address of your ingress gateway}/

      Expected output:

      HTTP/1.1 401 Unauthorized
      www-authenticate: Bearer realm="http://47.98.25*.***/", error="invalid_token"
      content-length: 79
      content-type: text/plain
      date: Fri, 18 Mar 2022 07:59:00 GMT
      server: istio-envoy
    3. Run the following command to access the service by using a request that does not contain a JWT:
      curl -I http://{IP address of your ingress gateway}/

      Expected output:

      HTTP/1.1 200 OK
      server: istio-envoy
      date: Fri, 18 Mar 2022 07:27:54 GMT
    The preceding results show that a request can access the service if the request contains a valid JWT or does not contain a JWT. The preceding results also show that a request cannot access the service if the request contains an invalid JWT. This indicates that the request authentication policy takes effect as expected.

Step 5: Create an authorization policy

Scenario 1: Use an authorization policy to specify the requests that can access the service

Create an authorization policy to specify that a request can access the service by using the ingress gateway only if the request contains a JWT.

  1. Log on to the ASM console.
  2. In the left-side navigation pane, choose Service Mesh > Mesh Management.
  3. 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.
  4. On the details page of the ASM instance, choose Zero Trust Security > AuthorizationPolicy in the left-side navigation pane. On the AuthorizationPolicy page, click Create.
  5. On the Create page, set the parameters that are described in the following table and click Create.
    Authorization policy
    Parameter Description
    Namespace The namespace in which you want to create the authorization policy. Set this parameter to istio-system.
    Name The name of the authorization policy.
    Policies The type of the authorization policy. Set this parameter to RULES.
    Action The authorization action. Set this parameter to ALLOW.
    Request Source The source of requests. Turn on Request Source and click Add Request Source to List. Click Add Request Source. Then, set the Request Source Domain parameter to requestPrincipals and the Value parameter to an asterisk (*).
  6. Check whether the authorization policy that you created takes effect.
    1. Run the following command to access the service by using a request that does not contain a JWT:
      curl -I http://{IP address of your ingress gateway}/

      Expected output:

      HTTP/1.1 401 Unauthorized
      www-authenticate: Bearer realm="http://47.98.25*.***/", error="invalid_token"
      content-length: 79
      content-type: text/plain
      date: Fri, 18 Mar 2022 07:59:00 GMT
      server: istio-envoy
    2. Run the following command to access the service by using a request that contains a JWT:
      curl -I -H "Authorization: Bearer $TOKEN" http://{IP address of your ingress gateway}/

      Expected output:

      HTTP/1.1 200 OK
      server: istio-envoy
      date: Fri, 18 Mar 2022 07:27:54 GMT
    The preceding results show that a request cannot access the service if the request does not contain a JWT. The preceding results also show that a request can access the service if the request contains a JWT. This indicates that the authorization policy takes effect as expected.

Scenario 2: Use an authorization policy to specify the issuer of the JWT with which a request can access the service

Create an authorization policy to specify that a request can access the service by using the ingress gateway only if the request contains a JWT whose issuer is testing@asm.istio.io.

  1. Log on to the ASM console.
  2. In the left-side navigation pane, choose Service Mesh > Mesh Management.
  3. 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.
  4. On the details page of the ASM instance, choose Zero Trust Security > AuthorizationPolicy in the left-side navigation pane. On the AuthorizationPolicy page, click Create.
  5. On the Create page, set the parameters that are described in the following table and click Create.
    Authorization policy 2
    Parameter Description
    Namespace The namespace in which you want to create the authorization policy. Set this parameter to istio-system.
    Name The name of the authorization policy.
    Policies The type of the authorization policy. Set this parameter to RULES.
    Action The authorization action. Set this parameter to ALLOW.
    Request Source The source of requests. Turn on Request Source and click Add Request Source to List. Click Add Request Source. Then, set the Request Source Domain parameter to requestPrincipals and the Value parameter to testing@asm.test.io/demo@asm.test.io.
  6. Check whether the authorization policy that you created takes effect.
    1. Run the following command to access the service by using a request that contains a JWT:
      curl -I -H "Authorization: Bearer $TOKEN" http://{IP address of your ingress gateway}/

      Expected output:

      HTTP/1.1 401 Unauthorized
      www-authenticate: Bearer realm="http://47.98.25*.***/", error="invalid_token"
      content-length: 79
      content-type: text/plain
      date: Fri, 18 Mar 2022 07:59:00 GMT
      server: istio-envoy

      The authorization policy specifies that a request can access the service only if the request contains a JWT whose issuer is testing@asm.test.io/demo@asm.test.io. Therefore, a request that contains a JWT whose issuer is testing@asm.test.io cannot access the service.

    2. Change the issuer of the JWT to testing@asm.test.io/demo@asm.test.io.
      In the JWT tool, set the iss parameter in the PAYLOAD section to testing@asm.test.io and the sub parameter to demo@asm.test.io. Set other parameters to the same values as those you specified in Step 1. jwt2
    3. Run the following command to access the service by sending a request that contains the generated JWT:
      curl -I -H "Authorization: Bearer $TOKEN" http://{IP address of your ingress gateway}/

      Expected output:

      HTTP/1.1 200 OK
      server: istio-envoy
      date: Fri, 18 Mar 2022 07:27:54 GMT

      The preceding result shows that a request with a JWT whose issuer is testing@asm.test.io/demo@asm.test.io can access the service. This indicates that the authorization policy takes effect as expected.