All Products
Search
Document Center

Alibaba Cloud Service Mesh:Configure authorization policies for access control on workloads

Last Updated:Jun 21, 2026

By default, workloads in a Service Mesh (ASM) instance can communicate with each other. You can create authorization policies to perform access control and permission management on workloads in a cluster. In this case, only requests that meet specific requirements can access the workloads. For example, you can control access to workloads by specifying request paths, request methods, and IP addresses of clients. This improves security and protects the resources of the ASM instance.

Prerequisites

The cluster is added to the ASM instance.

Feature introduction

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.

This topic provides the following four examples to help you quickly understand and configure authorization policies:

Scenario 1: Control access to a specific path of a workload

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

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

  1. Create the default and foo namespaces. For more information, see Create a namespace.

  2. Enable automatic sidecar proxy injection for the default and foo namespaces. For more information, see Enable automatic sidecar proxy injection.

Step 2: Deploy test applications

  1. Deploy the sleep application in the default and foo namespaces.

    1. Create a sleep.yaml file that contains the following content:

      Show the sleep.yaml file

      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:

      Show the httpbin.yaml file

      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. In the left-side navigation pane, choose Service Mesh > Mesh Management.

  2. On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose Mesh Security Center > AuthorizationPolicy. On the page that appears, click Create.

  3. On the Create page, configure the parameters and click Create.

    Parameter

    Description

    Name

    The name of the authorization policy.

    Policy Type

    Set the value to ALLOW.

    Namespaces

    On the Workload Scope tab, set Namespaces to foo.

    Effective Scope

    Select Service.

    Workload

    Select httpbin.

    Request Matching Rules

    1. In the Add Request Source section, enable the Namespaces switch and set the value to foo. This allows all applications in the foo namespace to access the httpbin application.

    2. In the Add Request Target section, enable the Paths switch and set the value to /headers. This allows applications to access only the /headers path of the httpbin application in the foo namespace.

Step 4: Check whether the authorization policy that controls access to the specific 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. In the left navigation pane, click Clusters.

    2. On the Clusters page, click the name of your cluster. In the left navigation pane, click Workloads > Pods.

    3. At the top of the Pods page, set Namespaces to default. Find the sleep pod and click Terminal > sleep in the Actions column.

    4. Run the following command in the Terminal section of the sleep container to access the /headers path of the HTTPBin application:

      curl httpbin.foo.svc.cluster.local:8000/headers

      The 403 code is returned, which indicates that the request is rejected.

    5. Run the following command in the Terminal section of the sleep container to access the /ip path of the HTTPBin application:

      curl httpbin.foo.svc.cluster.local:8000/ip

      The 403 code 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 navigation pane of the cluster management page, choose Workload > Pods.

    2. At the top of the Pods page, set Namespaces to foo. Find the sleep pod and click Terminal > sleep in the Actions column.

    3. Run the following command in the Terminal section 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 in the Terminal section of the sleep container to access the /ip path of the HTTPBin application:

      curl httpbin.foo.svc.cluster.local:8000/ip

      The 403 code is returned, which indicates that the request is rejected.

    The output results indicate that applications in the default namespace cannot access paths of the HTTPBin application in the foo namespace. Applications in the foo namespace can access the /headers path of the HTTPBin application.

Scenario 2: Control the request method and access to a specific path of 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 application and requests that use a request method other than GET fail.

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

  1. Create the default and foo namespaces. For more information, see Create a namespace.

  2. Enable automatic sidecar proxy injection for the default and foo namespaces. For more information, see Enable automatic sidecar proxy injection.

Step 2: Deploy test applications

  1. Deploy the sleep application in the default and foo namespaces.

    1. Create a sleep.yaml file that contains the following content:

      Show the sleep.yaml file

      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:

      Show the httpbin.yaml file

      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. In the left-side navigation pane, choose Service Mesh > Mesh Management.

  2. On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose Mesh Security Center > AuthorizationPolicy. On the page that appears, click Create.

  3. On the Create page, configure the parameters and click Create.

  4. Parameter

    Description

    Name

    The name of the authorization policy.

    Policy Type

    Select ALLOW.

    Namespaces

    On the Workload Scope tab, set Namespaces to foo.

    Effective Scope

    Select Service.

    Workload

    Select httpbin.

    Request Matching Rules

    In the Add Request Target section, configure the following parameters:

    1. Enable the Methods switch and set the value to GET.

    2. Turn on the Paths switch and set the value to /status/*. This allows applications in all namespaces to use only the GET method to access the /status path of the httpbin application in the foo namespace.

Step 4: Check whether the authorization policy that controls the request method and access to the specific path of a workload takes effect

  1. Log on to the ACK console. In the left navigation pane, click Clusters.

  2. On the Clusters page, click the name of your cluster. In the left navigation pane, click Workloads > Pods.

  3. At the top of the Pods page, set Namespaces to default. Find the sleep pod and click Terminal > sleep in the Actions column.

  4. Run the following command in the Terminal section 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"

    The 403 code is returned, which indicates that the request is rejected.

  5. 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"

    The 403 code is returned, which indicates that the request is rejected.

  6. 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 result indicates that applications in the default namespace can access the /status path of the HTTPBin application only by using GET requests. This means that the authorization policy takes effect.

Example 3: Control access to a workload by client IP addresses

You can create an authorization policy that allows requests from only authorized client IP addresses to access the HTTPBin application in the foo namespace.

Step 1: Enable automatic sidecar proxy injection for the foo namespace

  1. Create the foo namespace. For more information, see Manage global namespaces.

  2. Enable automatic sidecar proxy injection for the foo namespace. For more information, see Enable automatic sidecar proxy injection.

Step 2: Deploy an ingress gateway

  1. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

  2. On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose ASM Gateways > Ingress Gateway.

  3. On the Ingress Gateway page, click Create, configure the parameters, and then click Create.

    Parameter

    Description

    Name

    The name of the ingress gateway.

    Cluster

    The cluster in which you want to deploy the ingress gateway.

    SLB

    Select Classic Load Balancer and Public Access. This example uses a Classic Load Balancer, but you can also use a Network Load Balancer.

    Create SLB Instance

    The load balancer instance that you want to use. You can select a load balancer instance by using one of the following methods:

    • Use Existing CLB Instance: Select an existing load balancer from the list.

    • Create SLB Instance: Click Create SLB Instance and select the desired specifications from the drop-down list.

    Port Mapping

    Select a Protocol and enter a Service Port as needed.

    External Traffic Policy

    Click Advanced Options and set External Traffic Policy to Local.

Step 3: Create a virtual service and an Istio gateway

  1. Use the following content to create a virtual service in the foo namespace. For more information, see Manage virtual services.

    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. Use the following content to create an Istio gateway in the foo namespace. For more information, see Manage Istio gateways.

    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. Obtain the IP address of the ingress gateway. For more information, see Create an ingress gateway.

  2. Obtain the IP address of the client.

    Enter http://{ASM Gateway IP}/headers in the address bar of your browser to obtain the IP address for X-Envoy-External-Address. In the returned response, the X-Envoy-External-Address field is the real external IP address of the client.

    {
      "headers": {
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,imag...",
        "Accept-Encoding": "gzip, deflate",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
        "Cache-Control": "max-age=0",
        "Host": "<IP address>",
        "Upgrade-Insecure-Requests": "1",
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.3...",
        "X-Envoy-Attempt-Count": "1",
        "X-Envoy-External-Address": "<Client external IP>",
        "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/foo/sa/httpbin;Hash=e49...service-account"
      }
    }
  3. Create an authorization policy.

    1. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

    2. On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose Mesh Security Center > AuthorizationPolicy. On the page that appears, click Create.

    3. On the Create page, configure the parameters and click Create.

      Parameter

      Description

      Name

      The name of the authorization policy.

      Policy Type

      Select DENY.

      Namespaces

      On the Workload Scope tab, set Namespaces to foo.

      Effective Scope

      Select Service.

      Workload

      Select httpbin.

      Request Matching Rules

      In the Add Request Source section, enable the RemoteIPBlocks switch and set the value to the client IP address that you obtained in the previous step. This prevents the client IP address from accessing the httpbin application.

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

In your browser, navigate to http://{ASM gateway IP}/headers. The message RBAC: access denied is returned, indicating that access to the httpbin application failed. This verifies that the restriction on the client IP address is in effect.

RBAC: access denied

Example 4: Control service access across namespaces

Step 1: Enable automatic sidecar proxy injection for the demo-frontend and demo-server namespaces

  1. Create the demo-frontend and demo-server namespaces. For more information, see Create a namespace.

  2. Enable automatic sidecar proxy injection for the demo-frontend and demo-server namespaces. For more information, see the "Enable automatic sidecar proxy injection" section of the Manage global namespaces topic.

Step 2: Deploy test services

Create a service named sleep in the demo-frontend namespace and a service named httpbin in the demo-server namespace. The sleep service is used to send requests to access the httpbin service.

  1. Create a service named sleep in the demo-frontend namespace.

    1. Create a sleep.yaml file that contains the following content:

      Show the sleep.yaml file

      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. Use kubectl to connect to the Container Service for Kubernetes (ACK) cluster based on the information in the kubeconfig file, and then run the following command to create a sleep service:

      kubectl apply -f sleep.yaml -n demo-frontend
  2. Create a service named httpbin in the demo-server namespace.

    1. Create an httpbin.yaml file that contains the following content:

      Show the httpbin.yaml file

      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. Use kubectl to connect to the ACK cluster based on the information in the kubeconfig file, and then run the following command to create an httpbin service:

      kubectl apply -f httpbin.yaml -n demo-server
  3. Verify that sidecar proxies are injected into the pods where the sleep and httpbin services reside.

    1. Log on to the ACK console. In the left navigation pane, click Clusters.

    2. On the Clusters page, click the name of your cluster. In the left navigation pane, click Workloads > Pods.

    3. At the top of the Pods page, select demo-frontend from the Namespaces drop-down list and click the name of the sleep service's pod.

      On the Containers tab, you can see the istio-proxy container. This indicates that the sidecar injection for the sleep service is complete.

    4. At the top of the Pods page, select demo-server from the Namespaces drop-down list and click the name of the httpbin service's pod.

      On the Containers tab, you can see the istio-proxy container. This indicates that the sidecar injection for the httpbin service is complete.

Step 3: Create an authorization policy to control service access across namespaces

You can create an authorization policy and modify the action parameter in the authorization policy to deny or allow access requests from services in the demo-frontend namespace to services in the demo-server namespace. This way, you can control service access across namespaces.

  1. Create an authorization policy to deny access requests from the demo-frontend namespace to the demo-server namespace.

    1. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

    2. On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose Mesh Security Center > AuthorizationPolicy. On the page that appears, click Create.

    3. Configure the authorization policy parameters and click Create.

      Parameter

      Description

      Name

      The name of the authorization policy.

      Policy Type

      Select DENY.

      Namespaces

      On the Workload Scope tab, set Namespaces to demo-server.

      Effective Scope

      Select Namespace Scope.

      Request Matching Rules

      In the Add Request Source section, enable the Namespaces switch and set the value to demo-frontend.

  2. Access the httpbin service.

    1. Log on to the ACK console. In the left navigation pane, click Clusters.

    2. On the Clusters page, click the name of your cluster. In the left navigation pane, click Workloads > Pods.

    3. At the top of the Pods page, select demo-frontend from the Namespaces drop-down list. Then, find the sleep pod and click Terminal > sleep in the Actions column.

    4. Run the following command on the terminal of the sleep container to access the httpbin service:

      curl -I httpbin.demo-server.svc.cluster.local:8000

      Expected output:

      HTTP/1.1 403 Forbidden
      content-length: 19
      content-type: text/plain
      date: Wed, 11 Oct 2023 08:15:25 GMT
      server: envoy
      x-envoy-upstream-service-time: 4

      The preceding output indicates that the services in the demo-frontend namespace failed to access the services in the demo-server namespace.

  3. Change the value of the action parameter in the authorization policy to ALLOW to allow access requests from the demo-frontend namespace to the demo-server namespace.

    1. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

    2. On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose Mesh Security Center > AuthorizationPolicy.

    3. On the AuthorizationPolicy page, find the target policy and click View YAML in the Actions column.

    4. In the Edit dialog box, change the value of the action parameter to ALLOW and click OK.

  4. Run the following command on the terminal of the sleep container to access the httpbin service:

    curl -I httpbin.demo-server.svc.cluster.local:8000

    Expected output:

    HTTP/1.1 200 OK
    server: envoy
    date: Wed, 11 Oct 2023 08:21:40 GMT
    content-type: text/html; charset=utf-8
    content-length: 9593
    access-control-allow-origin: *
    access-control-allow-credentials: true
    x-envoy-upstream-service-time: 13

    The preceding output indicates that the services in the demo-frontend namespace successfully access the services in the demo-server namespace.

    As you can see, after an authorization policy with the Action set to Deny is created, services in the demo-frontend namespace fail to access services in the demo-server namespace. After the Action of the authorization policy is changed to ALLOW, services in the demo-frontend namespace can successfully access services in the demo-server namespace. This indicates that the authorization policy successfully controls cross-namespace service access.