All Products
Search
Document Center

Alibaba Cloud Service Mesh:Layer 7 authentication and authorization

Last Updated:Sep 21, 2023

The configuration model of authentication and authorization in Ambient Mesh mode is different from that in the original Sidecar mode due to the separation between Layer 4 and Layer 7. This topic describes how to use Layer 7 authorization policies in Service Mesh (ASM) instances of v1.18.

Prerequisites

An ingress gateway and related applications are deployed, and basic features are verified. For more information, see Prerequisites and Step 1 in Getting started.

Limits

  • The following limits are applicable to authorization policies in a waypoint proxy:

    • The action field cannot be set to CUSTOM, which indicates that a waypoint proxy does not support custom authorization services.

    • ipBlocks is not supported in the source field.

  • If a waypoint proxy is deployed, a corresponding ztunnel allows all requests from the waypoint proxy to pass through. In this case, authorization policies must be bound to the waypoint proxy.

Preparations

  1. Run the following command to deploy a waypoint proxy for the productpage service:

    istioctl x waypoint apply --service-account bookinfo-productpage
  2. Run the following command to view the pod of the waypoint proxy:

    kubectl get pod --show-labels | grep waypoint

    Expected output:

    bookinfo-productpage-istio-waypoint-6c579dd48d-l****   1/1     Running   0          91s    gateway.istio.io/managed=istio.io-mesh-controller,istio.io/gateway-name=bookinfo-productpage,pod-template-hash=6c579dd48d,service.istio.io/canonical-name=bookinfo-productpage-istio-waypoint,service.istio.io/canonical-revision=latest,sidecar.istio.io/inject=false

Example 1: If a waypoint proxy is deployed for the productpage service, the authorization policy on ztunnels does not take effect.

If a waypoint proxy is deployed for the productpage service, the corresponding ztunnels allow all traffic from the waypoint proxy of the productpage service to pass through. In this case, if an authorization policy is applied to a ztunnel (an application pod is selected by the selector of the authorization policy), the authorization policy does not take effect.

  1. Use the following content to create a productpage-viewer.yaml file.

    The following authorization policy applies to the corresponding ztunnel and prohibits access to port 9080 of the productpage service.

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
     name: productpage-viewer
     namespace: default
    spec:
     selector:
       matchLabels:
         app: productpage
     action: DENY
     rules:
     - to:
       - operation:
           ports:
           - "9080"
  2. Use kubectl to connect to the ASM instance based on the information in the kubeconfig file, and then run the following command to create an authorization policy:

    kubectl apply -f productpage-viewer.yaml
  3. Run the following commands to perform access tests:

    # You can see from the following four tests that the rule to deny access to port 9080 does not work at all. 
    
    kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage" | grep -o "<title>.*</title>"
    # Expected output:
    <title>Simple Bookstore App</title>
    
    kubectl exec deploy/notsleep -- curl -s "http://$GATEWAY_HOST/productpage" | grep -o "<title>.*</title>"
    # Expected output:
    <title>Simple Bookstore App</title>
    
    kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
    # Expected output:
    <title>Simple Bookstore App</title>
    
    kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
    # Expected output:
    <title>Simple Bookstore App</title>

    The preceding tests and the tests in Example 2: Prohibit access to port 9080 of the productpage service (no waypoint proxy is deployed) use the same authorization policy. However, all accesses to port 9080 of the productpage service were successful in the preceding tests.

    The preceding results show that after you deploy a waypoint proxy, all authorization policies on the ztunnel become invalid. You must change the configuration of the selector field to the waypoint proxy for the productpage service.

  4. Change the productpage-viewer.yaml file to the following content and run the kubectl apply -f productpage-viewer.yaml command to deploy the authorization policy.

    The following YAML file changes the configuration of the selector field.

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
     name: productpage-viewer
     namespace: default
    spec:
     selector:
       matchLabels:
         istio.io/gateway-name: bookinfo-productpage
     action: DENY
     rules:
     - to:
       - operation:
           ports:
           - "9080"
  5. Run the following commands to perform access tests:

    # The rule to deny access to port 9080 takes effect. 
    kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage"
    # Expected output:
    RBAC: access denied%
    
    kubectl exec deploy/notsleep -- curl -s "http://$GATEWAY_HOST/productpage"
    # Expected output:
    RBAC: access denied%
    
    kubectl exec deploy/sleep -- curl -s http://productpage:9080/
    # Expected output:
    RBAC: access denied%
    
    kubectl exec deploy/notsleep -- curl -s http://productpage:9080/
    # Expected output:
    RBAC: access denied%

    The error message returned here is RBAC: access denied%, which is different from that in Example 2: Prohibit access to port 9080 of the productpage service in the "Layer 4 authentication and authorization" topic. This error is actually returned by the waypoint proxy of the productpage service. When the waypoint proxy finds that access to port 9080 is refused, it returns an HTTP RBAC error with the HTTP 403 status code.

  6. Run the following command to remove the authorization policy:

    kubectl delete authorizationpolicy productpage-viewer

Example 2: Prohibit the IP address of the sleep pod from accessing the productpage service directly or indirectly through the gateway

Currently, authorization policies configured on a waypoint proxy do not support the ipBlocks field, and only support the remoteIpBlocks field. You can configure the remoteIpBlocks field to match requests only if the requests pass through the gateway. Therefore, you can only prohibit the IP address of the sleep pod from accessing the productpage service through the gateway. You cannot prohibit the IP address of the sleep pod from accessing the productpage service directly.

  1. Create a productpage-viewer.yaml file with the following content to prohibit the sleep pod from accessing the productpage service through the gateway:

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
     name: productpage-viewer
     namespace: default
    spec:
     selector:
       matchLabels:
         istio.io/gateway-name: bookinfo-productpage
     action: DENY
     rules:
     - from:
       - source:
           remoteIpBlocks:
           - "${sleep Pod IP}"
  2. Use kubectl to connect to the ASM instance based on the information in the kubeconfig file, and then run the following command to create an authorization policy:

    kubectl apply -f productpage-viewer.yaml
  3. Run the following commands to perform access tests:

    # The sleep pod is prohibited from accessing the productpage service through the gateway. 
    kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage"
    # Expected output:
    RBAC: access denied%
    
    kubectl exec deploy/sleep -- curl -s http://productpage:9080/ -I
    # Expected output:
    HTTP/1.1 200 OK
    content-type: text/html; charset=utf-8
    content-length: 1683
    server: istio-envoy
    date: Tue, 15 Aug 2023 02:11:30 GMT
    x-envoy-upstream-service-time: 3

    The expected output indicates that the sleep pod can directly access the productpage service and cannot access it through the gateway.

  4. Run the following command to remove the authorization policy:

    kubectl delete authorizationpolicy productpage-viewer

Example 3: Prohibit access to the productpage service from the pods in the istio-system namespace

  1. Use the following content to create a productpage-viewer.yaml file that prohibits the pods in the istio-system namespace from accessing the productpage service:

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
     name: productpage-viewer
     namespace: default
    spec:
     selector:
       matchLabels:
         istio.io/gateway-name: bookinfo-productpage
     action: DENY
     rules:
     - from:
       - source:
           namespaces:
           - istio-system
  2. Use kubectl to connect to the ASM instance based on the information in the kubeconfig file, and then run the following command to create an authorization policy:

    kubectl apply -f productpage-viewer.yaml
  3. Run the following commands to perform access tests:

    # The gateway cannot access the productpage service. 
    kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage"
    # Expected output:
    RBAC: access denied%
    
    kubectl exec deploy/notsleep -- curl -s "http://$GATEWAY_HOST/productpage"
    # Expected output:
    RBAC: access denied%
    
    kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
    # Expected output:
    <title>Simple Bookstore App</title>
    
    kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
    # Expected output:
    <title>Simple Bookstore App</title>

    The expected output indicates that neither the sleep application nor the notsleep application can access the productpage service through the gateway, but they can directly access the productpage service. This is because the gateway is in the istio-system namespace.

  4. Run the following command to remove the authorization policy:

    kubectl delete authorizationpolicy productpage-viewer

Example 4: Implement authentication and authorization based on the JWT that is carried in a request

To implement authentication and authorization based on the JSON Web Token (JWT) carried in a request, you must configure both a request authentication policy and an authorization policy. In this example, requests from the istio-system namespace must carry a valid JWT, and requests from the default namespace do not need to carry a valid JWT. After the configuration is complete, requests that pass through the gateway must carry a valid JWT. The sleep and notsleep applications do not need to carry a valid JWT if they directly access the productpage service.

  1. Create a request authentication policy.

    1. Use the following content to create a jwt-example.yaml file:

      apiVersion: security.istio.io/v1beta1
      kind: RequestAuthentication
      metadata:
        name: jwt-example
        namespace: default
      spec:
        selector:
          matchLabels:
            istio.io/gateway-name: bookinfo-productpage
        jwtRules:
        - issuer: "testing@secure.istio.io"
          jwks: '{ "keys":[ {"e":"AQAB","kid":"DHFbpoIUqrY8t2zpA2qXfCmr5VO5ZEr4RzHU_-envvQ","kty":"RSA","n":"xAE7eB6qugXyCAG3yhh7pkDkT65pHymX-P7KfIupjf59vsdo91bSP9C8H07pSAGQO1MV_xFj9VswgsCg4R6otmg5PV2He95lZdHtOcU5DXIg_pbhLdKXbi66GlVeK6ABZOUW3WYtnNHD-91gVuoeJT_DwtGGcp4ignkgXfkiEm4sw-4sfb4qdt5oLbyVpmW6x9cfa7vs2WTfURiCrBoUqgBo_-4WTiULmmHSGZHOjzwa8WtrtOQGsAFjIbno85jp6MnGGGZPYZbDAa_b3y5u-YpW7ypZrvD8BgtKVjgtQgZhLAGezMt0ua3DRrWnKqTZ0BJ_EyxOGuHJrLsn00fnMQ"}]}'
    2. Use kubectl to connect to the ASM instance based on the information in the kubeconfig file, and then run the following command to create a request authentication policy:

      kubectl apply -f jwt-example.yaml
  2. Create an authorization policy.

    1. Use the following content to create a productpage-viewer.yaml file:

      apiVersion: security.istio.io/v1beta1
      kind: AuthorizationPolicy
      metadata:
        name: productpage-viewer
        namespace: default
      spec:
        selector:
          matchLabels:
            istio.io/gateway-name: bookinfo-productpage
        action: ALLOW
        rules:
        - from:
          - source:
              requestPrincipals: ["testing@secure.istio.io/testing@secure.istio.io"]
              namespaces: ["istio-system"]
          - source:
              namespaces: ["default"]
    2. Use kubectl to connect to the ASM instance based on the information in the kubeconfig file, and then run the following command to create an authorization policy:

      kubectl apply -f productpage-viewer.yaml
  3. Run the following command to register the token as an environment variable:

    export TOKEN=eyJhbGciOiJSUzI1NiIsImtpZCI6IkRIRmJwb0lVcXJZOHQyenBBMnFYZkNtcjVWTzVaRXI0UnpIVV8tZW52dlEiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjQ2ODU5ODk3MDAsImZvbyI6ImJhciIsImlhdCI6MTUzMjM4OTcwMCwiaXNzIjoidGVzdGluZ0BzZWN1cmUuaXN0aW8uaW8iLCJzdWIiOiJ0ZXN0aW5nQHNlY3VyZS5pc3Rpby5pbyJ9.CfNnxWP2tcnR9q0vxyxweaF3ovQYHYZl82hAUsn21bwQd9zP7c-LS9qd_vpdLG4Tn1A15NxfCjp5f7QNBUo-KC9PJqYpgGbaXhaGx7bEdFWjcwv3nZzvc7M__ZpaCERdwU7igUmJqYGBYQ51vr2njU9ZimyKkfDe3axcyiBZde7G6dabliUosJvvKOPcKIWPccCgefSj_GNfwIip3-SsFdlR7BtbVUcqR-yv-XOxJ3Uc1MI0tz3uMiiZcyPV7sNCU4KRnemRIMHVOfuvHsU60_GhGbiSFzgPTAa9WTltbnarTbxudb_YEOx12JiwYToeX0DCPb43W1tzIBxgm8NxUg
  4. Run the following commands to perform access tests:

    # Access to the productpage service through the gateway without a JWT is prohibited. 
    kubectl exec deploy/sleep -- curl -s http://$GATEWAY_HOST/productpage
    # Expected output:
    RBAC: access denied%
    
    # Direct access to the productpage service without carrying a JWT is allowed. 
    kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
    # Expected output:
    <title>Simple Bookstore App</title>
    
    # Carry the valid JWT and access the productpage service through the gateway. 
    kubectl exec deploy/sleep -- curl -s http://$GATEWAY_HOST/productpage -H "Authorization: Bearer $TOKEN" -I
    # Expected output:
    HTTP/1.1 200 OK
    content-type: text/html; charset=utf-8
    content-length: 5290
    server: istio-envoy
    date: Tue, 15 Aug 2023 03:16:21 GMT
    x-envoy-upstream-service-time: 21
    
    # Carry an invalid JWT and access the productpage service through the gateway. 
    kubectl exec deploy/sleep -- curl -s http://$GATEWAY_HOST/productpage -H "Authorization: Bearer wrongtoken" -I
    # Expected output:
    HTTP/1.1 401 Unauthorized
    www-authenticate: Bearer realm="http://istio-ingressgateway.istio-system/productpage", error="invalid_token"
    content-length: 79
    content-type: text/plain
    date: Tue, 15 Aug 2023 03:17:26 GMT
    server: istio-envoy
    x-envoy-upstream-service-time: 0
  5. Run the following commands to remove the authorization policy and request authentication policy:

    kubectl delete authorizationpolicy productpage-viewer
    kubectl delete requestauthentication jwt-example

Example 5: Prohibit requests whose host is test.com to access port 9080 of the productpage service

Port 9080 of the productpage service is exposed for access. In this example configuration, requests whose host field is test.com are not allowed to access port 9080 of the productpage service, and other requests are allowed to access this port.

  1. Use the following content to create a productpage-viewer.yaml file:

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: productpage-viewer
      namespace: default
    spec:
      selector:
        matchLabels:
          istio.io/gateway-name: bookinfo-productpage
      action: DENY
      rules:
      - to:
        - operation:
            hosts: ["test.com"]
            ports: ["9080"]
  2. Use kubectl to connect to the ASM instance based on the information in the kubeconfig file, and then run the following command to create an authorization policy:

    kubectl apply -f productpage-viewer.yaml
  3. Run the following commands to perform access tests:

    # Use test.com as the host to access the productpage service. The access fails. 
    kubectl exec deploy/sleep -- curl -s http://$GATEWAY_HOST/productpage -H "Host: test.com"
    # Expected output:
    RBAC: access denied%
    
    # Use test1.com as the host to access the productpage service. The access is successful. 
    kubectl exec deploy/sleep -- curl -s http://$GATEWAY_HOST/productpage -H "Host: test1.com" -I
    # Expected output:
    HTTP/1.1 200 OK
    content-type: text/html; charset=utf-8
    content-length: 5290
    server: istio-envoy
    date: Tue, 15 Aug 2023 03:39:29 GMT
    x-envoy-upstream-service-time: 18
  4. Run the following command to remove the authorization policy:

    kubectl delete authorizationpolicy productpage-viewer

Example 6: Prohibit the use of the HEAD method to access the /productpage path

  1. Use the following content to create a productpage-viewer.yaml file:

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: productpage-viewer
      namespace: default
    spec:
      selector:
        matchLabels:
          istio.io/gateway-name: bookinfo-productpage
      action: DENY
      rules:
      - to:
        - operation:
            methods: ["HEAD"]
            paths: ["/productpage"]
  2. Use kubectl to connect to the ASM instance based on the information in the kubeconfig file, and then run the following command to create an authorization policy:

    kubectl apply -f productpage-viewer.yaml
  3. Run the following commands to perform access tests:

    # Use the HEAD method to access the /productpage path. The default method for the -I option is the HEAD method. 
    kubectl exec deploy/sleep -- curl -s http://$GATEWAY_HOST/productpage -I
    # Expected output:
    HTTP/1.1 403 Forbidden
    content-length: 19
    content-type: text/plain
    date: Tue, 15 Aug 2023 03:59:37 GMT
    server: istio-envoy
    x-envoy-upstream-service-time: 0
    
    # Use the GET method to access the /productpage path. 
    kubectl exec deploy/sleep -- curl -s http://$GATEWAY_HOST/productpage -XGET -I
    # Expected output:
    HTTP/1.1 200 OK
    content-type: text/html; charset=utf-8
    content-length: 5290
    server: istio-envoy
    date: Tue, 15 Aug 2023 04:00:48 GMT
    x-envoy-upstream-service-time: 20
    
    # Use the HEAD method to access the /api/v1/products path. 
    kubectl exec deploy/sleep -- curl -s http://$GATEWAY_HOST/api/v1/products -I
    # Expected output:
    HTTP/1.1 200 OK
    content-type: application/json
    content-length: 395
    server: istio-envoy
    date: Tue, 15 Aug 2023 04:02:39 GMT
    x-envoy-upstream-service-time: 2
  4. Run the following command to remove the authorization policy:

    kubectl delete authorizationpolicy productpage-viewer