By default, workloads within an Alibaba Cloud Service Mesh (ASM) instance can communicate with each other. You can create authorization policies to configure access control on workloads. In this case, only requests that meet the requirements can access the specified workloads. This topic describes how to create authorization policies for workloads. The following scenarios show you how to restrict requests to workloads by specifying the request path, the request method, and the IP address of the client.

Background information

You can specify the CUSTOM, DENY, or ALLOW action in an authorization policy. The authorization policies have different levels of priority when you apply multiple authorization policies to a single workload. To be specific, the system verifies requests based on the CUSTOM, DENY, and ALLOW authorization policies in sequence. If you create multiple authorization policies for a workload, the following rules take effect:
  • If a request matches the condition in a CUSTOM authorization policy that rejects the request, the request is rejected.
  • If a request matches the condition in a DENY authorization policy that rejects the request, the request is rejected.
  • By default, if no ALLOW authorization policy is configured for a workload, the request can access the workload.
  • If an ALLOW authorization policy is configured for a workload and a request matches the condition in the ALLOW authorization policy, the request can access the workload.
  • If a request does not meet all the preceding requirements, the request is rejected.

Scenario 1: Restrict the request path of the request to access a workload

In this example, an authorization policy is created to specify that applications in namespaces other than the foo namespace can access only the /headers path of the httpbin application. The httpbin application resides in the foo namespace. Requests to other paths fail. Applications in the foo namespace can access the httpbin application without restrictions.

Step 1: Enable sidecar injection for the default and foo namespaces

  1. Create the default and foo namespaces. For more information, see Manage namespaces.
  2. Enable 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 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 ASM Instance > Global Namespace in the left-side navigation pane.
    5. On the Global Namespace page, find the default namespace and click Enable Automatic Sidecar Injection in the Automatic Sidecar Injection column.
    6. In the Submit message, click OK.
  3. Enable sidecar injection for the foo namespace by repeating the preceding substep.

Step 2: Deploy a test application

  1. Deploy the sleep application in the default and foo namespaces.
    1. Create a sleep.yaml file that contains the following content:
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: sleep
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: sleep
        labels:
          app: sleep
          service: sleep
      spec:
        ports:
        - port: 80
          name: http
        selector:
          app: sleep
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: sleep
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: sleep
        template:
          metadata:
            labels:
              app: sleep
          spec:
            terminationGracePeriodSeconds: 0
            serviceAccountName: sleep
            containers:
            - name: sleep
              image: curlimages/curl
              command: ["/bin/sleep", "3650d"]
              imagePullPolicy: IfNotPresent
              volumeMounts:
              - mountPath: /etc/sleep/tls
                name: secret-volume
            volumes:
            - name: secret-volume
              secret:
                secretName: sleep-secret
                optional: true
      ---
    2. Run the following command to deploy the sleep application in the default namespace:
      kubectl apply -f sleep.yaml -n default
    3. Run the following command to deploy the sleep application in the foo namespace:
      kubectl apply -f sleep.yaml -n foo
  2. Deploy the httpbin application in the foo namespace.
    1. 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
    2. Run the following command to deploy the httpbin application in the foo namespace:
      kubectl apply -f httpbin.yaml -n foo

Step 3: Create an authorization 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 > 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.
    Parameter Description
    Namespace The namespace in which you want to create the authorization policy. Set this parameter to foo.
    Name The name of the authorization policy.
    Policies The type of the authorization policy that you want to create. Set this parameter to RULES.
    Action The authorization action. Set this parameter to ALLOW.
    Workload Label Selection Turn on Workload Label Selection, click Add Matching Label, and then add a label with the name of app and the value of httpbin.
    Request Source

    Specifies whether to authenticate the sources of requests. Turn on Request Source, click Add Request Source to List, and then click Add Request Source. Then, select namespaces from the Request Source Domain drop-down list and set the Value parameter to foo.

    This setting allows all applications in the foo namespace to access the httpbin application.

    Request Operation

    Turn on Request Operation and click Add Request Operation to List. Click Add Request Operation. Then, set the Request Operation Domain parameter to paths and the Value parameter to /headers.

    This setting allows applications in all namespaces other than the foo namespace to access only the /headers path of the httpbin application in the foo namespace.

    Restrict the request path

Step 4: Check whether the authorization policy that restricts the request path takes effect

  1. Send a request by using the sleep application in the default namespace to access the httpbin application in the foo namespace.
    1. Log on to the ACK console.
    2. In the left-side navigation pane of the ACK console, click Clusters.
    3. On the Clusters page, find the cluster that you want to manage and click the name of the cluster or click Details in the Actions column. The details page of the cluster appears.
    4. In the left-side navigation pane of the details page, choose Workloads > Pods.
    5. In the upper part of the Pods page, select default from the Namespace drop-down list. Click Terminal in the Actions column, and select Container: sleep.
    6. Run the following command on the terminal of the sleep container to access the /headers path of the httpbin application:
      curl httpbin.foo.svc.cluster.local:8000/headers

      Expected output:

      {
        "headers": {
          "Accept": "*/*",
          "Host": "httpbin.foo.svc.cluster.local:8000",
          "User-Agent": "curl/7.82.0-DEV",
          "X-Envoy-Attempt-Count": "1",
          "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/foo/sa/httpbin;Hash=f7ab4985563b5b1986314d5a36c6e46819213e2f38301f534f00afb7cd4b9164;Subject=\"\";URI=spiffe://cluster.local/ns/foo/sa/sleep"
        }
      }
    7. Run the following command on the terminal of the sleep container to access the /ip path of the httpbin application:
      curl httpbin.foo.svc.cluster.local:8000/ip

      A value of 403 is returned, which indicates that the request is rejected.

  2. Send a request by using the sleep application in the foo namespace to access the httpbin application in the foo namespace.
    1. In the left-side navigation pane of the details page, choose Workloads > Pods.
    2. In the upper part of the Pods page, select foo from the Namespace drop-down list. Click Terminal in the Actions column, and select Container: sleep.
    3. Run the following command on the terminal of the sleep container to access the /headers path of the httpbin application:
      curl httpbin.foo.svc.cluster.local:8000/headers

      Expected output:

      {
        "headers": {
          "Accept": "*/*",
          "Host": "httpbin.foo.svc.cluster.local:8000",
          "User-Agent": "curl/7.82.0-DEV",
          "X-Envoy-Attempt-Count": "1",
          "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/foo/sa/httpbin;Hash=f7ab4985563b5b1986314d5a36c6e46819213e2f38301f534f00afb7cd4b9164;Subject=\"\";URI=spiffe://cluster.local/ns/foo/sa/sleep"
        }
      }
    4. Run the following command on the terminal of the sleep container to access the /ip path of the httpbin application:
      curl httpbin.foo.svc.cluster.local:8000/ip

      Expected output:

      {
        "headers": {
          "Accept": "*/*",
          "Host": "httpbin.foo.svc.cluster.local:8000",
          "User-Agent": "curl/7.82.0-DEV",
          "X-Envoy-Attempt-Count": "1",
          "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/foo/sa/httpbin;Hash=f7ab4985563b5b1986314d5a36c6e46819213e2f38301f534f00afb7cd4b9164;Subject=\"\";URI=spiffe://cluster.local/ns/foo/sa/sleep"
        }
      }
    The preceding result indicates that applications in the default namespace can access only the /headers path of the httpbin application in the foo namespace, and requests to a path other than the /headers path of the httpbin application fail. Applications in the foo namespace can access the httpbin application without restrictions.

Scenario 2: Restrict the path and method of the request to access a workload

In this example, an authorization policy is created to specify that applications in namespaces other than the foo namespace can access only the /status path of the httpbin application by using GET requests. The httpbin application resides in the foo namespace. Requests to other paths of the httpbin applications and requests that use a request method other than GET fail.

Step 1: Enable sidecar injection for the default and foo namespaces

  1. Create the default and foo namespaces. For more information, see Manage namespaces.
  2. Enable 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 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 ASM Instance > Global Namespace in the left-side navigation pane.
    5. On the Global Namespace page, find the default namespace and click Enable Automatic Sidecar Injection in the Automatic Sidecar Injection column.
    6. In the Submit message, click OK.
  3. Enable sidecar injection for the foo namespace by repeating the preceding substep.

Step 2: Deploy a test project

  1. Deploy the sleep application in the default and foo namespaces.
    1. Create a sleep.yaml file that contains the following content:
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: sleep
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: sleep
        labels:
          app: sleep
          service: sleep
      spec:
        ports:
        - port: 80
          name: http
        selector:
          app: sleep
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: sleep
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: sleep
        template:
          metadata:
            labels:
              app: sleep
          spec:
            terminationGracePeriodSeconds: 0
            serviceAccountName: sleep
            containers:
            - name: sleep
              image: curlimages/curl
              command: ["/bin/sleep", "3650d"]
              imagePullPolicy: IfNotPresent
              volumeMounts:
              - mountPath: /etc/sleep/tls
                name: secret-volume
            volumes:
            - name: secret-volume
              secret:
                secretName: sleep-secret
                optional: true
      ---
    2. Run the following command to deploy the sleep application in the default namespace:
      kubectl apply -f sleep.yaml -n default
    3. Run the following command to deploy the sleep application in the foo namespace:
      kubectl apply -f sleep.yaml -n foo
  2. Deploy the httpbin application in the foo namespace.
    1. 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
    2. Run the following command to deploy the httpbin application in the foo namespace:
      kubectl apply -f httpbin.yaml -n foo

Step 3: Create an authorization 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 > 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.
    Parameter Description
    Namespace The namespace in which you want to create the authorization policy. Set this parameter to foo.
    Name The name of the authorization policy.
    Policies The type of the authorization policy that you want to create. Set this parameter to RULES.
    Action The authorization action. Set this parameter to ALLOW.
    Workload Label Selection Turn on Workload Label Selection, click Add Matching Label, and then add a label with the name of app and the value of httpbin.
    Request Operation

    Turn on Request Operation and click Add Request Operation to List. Click Add Request Operation. Then, set the Request Operation Domain parameter to paths and the Value parameter to /status/*.

    Click Add Request Operation. Set the Request Operation Domain parameter to methods and the Value parameter to GET.

    This setting allows applications in all namespaces other than the foo namespace to access only the /status path of the httpbin application by using the GET requests. The httpbin application resides in the foo namespace.

    Restrict the request method

Step 4: Check whether the authorization policy that restricts the path and method of the request takes effect

  1. Log on to the ACK console.
  2. In the left-side navigation pane of the ACK console, click Clusters.
  3. On the Clusters page, find the cluster that you want to manage and click the name of the cluster or click Details in the Actions column. The details page of the cluster appears.
  4. In the left-side navigation pane of the details page, choose Workloads > Pods.
  5. In the upper part of the Pods page, select default from the Namespace drop-down list. Click Terminal in the Actions column, and select Container: sleep.
  6. Run the following command on the terminal of the sleep container to access the /status path of the httpbin application by using a POST request:
    curl -I -X POST "httpbin.foo.svc.cluster.local:8000/status/200" -H "accept: text/plain"

    A value of 403 is returned, which indicates that the request is rejected.

  7. Run the following command to access the /IP path of the httpbin application by using a GET request:
    curl -I -X GET "httpbin.foo.svc.cluster.local:8000/IP/200" -H "accept: text/plain"

    A value of 403 is returned, which indicates that the request is rejected.

  8. Run the following command to access the /status path of the httpbin application by using a GET request:
    curl -I -X GET "httpbin.foo.svc.cluster.local:8000/status/200" -H "accept: text/plain"

    Expected output:

    HTTP/1.1 200 OK
    server: envoy
    date: Fri, 29 Apr 2022 03:01:16 GMT
    content-type: text/html; charset=utf-8
    access-control-allow-origin: *
    access-control-allow-credentials: true
    content-length: 0
    x-envoy-upstream-service-time: 5

    The preceding result shows that applications in the default namespace can access the /status path of the httpbin application only by using GET requests. This indicates that the authorization policy takes effect.

Scenario 3: Restrict the IP address of the client from which requests are sent to access a workload

You can create an authorization policy that restricts the IP address of the client from which requests are sent to access the httpbin application in the foo namespace.

Step 1: Enable sidecar injection for the foo namespace

  1. Create the foo namespace. For more information, see Manage namespaces.
  2. Enable sidecar injection for the foo namespace.
    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 ASM Instance > Global Namespace in the left-side navigation pane.
    5. On the Global Namespace page, find the default namespace and click Enable Automatic Sidecar Injection in the Automatic Sidecar Injection column.
    6. In the Submit message, click OK.

Step 2: Deploy an ingress gateway service

  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, click ASM Gateways in the left-side navigation pane. On the ASM Gateways page, click Create.
  5. Configure the basic information of the ingress gateway service. The following table describes the major parameters. You can use the default settings for other parameters.
    Parameter Description
    Name The name of the ingress gateway service.
    Cluster The cluster in which you want to deploy the ingress gateway service.
    Gateway types The type of the gateway service. Set the value to North-South IngressGateway.
    SLB Instance Type The access type of the Server Load Balancer (SLB) instance that you want to use. Set the value to Internet Access.
    Create SLB Instance The SLB instance that you want to use. You can select an SLB instance by using one of the following methods:
    • Use Existing SLB Instance: Select an existing SLB instance from the drop-down list.
    • Create SLB Instance: Click Create SLB Instance and select an SLB instance type from the drop-down list.
    Port Mapping The port mappings. Click Add Port. In the row that appears, select the protocol type and specify a service port.
  6. Click Advanced Options, set the External Traffic Policy parameter to Local, and then click Create.

Step 3: Create a virtual service and an Istio gateway

  1. Create a virtual service.
    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 > VirtualService in the left-side navigation pane. On the VirtualService page, click Create from YAML.
    5. Select foo from the Namespace drop-down list and use the default value of the Template parameter. Enter the following content in the YAML field and click Create.
      apiVersion: networking.istio.io/v1beta1
      kind: VirtualService
      metadata:
        name: httpbin
      spec:
        gateways:
          - httpbin-gateway
        hosts:
          - '*'
        http:
          - match:
              - uri:
                  prefix: /headers
            route:
              - destination:
                  host: httpbin
                  port:
                    number: 8000
  2. Create an Istio gateway.
    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 > Gateway in the left-side navigation pane. On the Gateway page, click Create from YAML.
    5. Select foo from the Namespace drop-down list and use the default value of the Template parameter. Enter the following content in the YAML field and click Create.
      apiVersion: networking.istio.io/v1beta1
      kind: Gateway
      metadata:
        name: httpbin-gateway
      spec:
        selector:
          istio: ingressgateway
        servers:
          - hosts:
              - '*'
            port:
              name: http
              number: 80
              protocol: HTTP

Step 4: Create an authorization policy

  1. The IP address of the specified ingress gateway is obtained. For more information, see Deploy an ingress gateway service.
  2. Obtain the IP address of the client.
    Enter http://{IP address of the ingress gateway}/headers in the address bar of the browser. On the page that appears, save the value of the X-Envoy-External-Address parameter. IP address of the client
  3. Create an authorization 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 > 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.
      Parameter Description
      Namespace The namespace in which you want to create the authorization policy. Set this parameter to foo.
      Name The name of the authorization policy.
      Policies The type of the authorization policy that you want to create. Set this parameter to RULES.
      Action The authorziation policy. Set the value to DENY.
      Workload Label Selection Turn on Workload Label Selection, click Add Matching Label, and then add a label with the name of app and the value of httpbin.
      Request Source

      Turn on Request Source, click Add Request Source to List, and then click Add Request Source. Set the Request Source Domain parameter to remoteipBlocks and the Value parameter to the IP address of the client that you obtain in Subtep 2 of this section.

      This setting specifies that requests sent from the specified IP address of the client are denied access to the httpbin application.

      Restrict the IP address of the client

Step 5: Check whether the authorization policy that restricts requests sent from the specified IP address of the client takes effect

Enter http://{IP address of the ingress gateway}/headers in the address bar of the browser. If the RBAC:access denied message is returned, the request to access the httpbin application fails. This indicates that the authorization policy takes effect. Verify the IP address of the client