All Products
Search
Document Center

Alibaba Cloud Service Mesh:Implement custom authorization by using the HTTP protocol

Last Updated:Mar 11, 2026

Service Mesh (ASM) supports external authorization through the Envoy ext_authz filter. Instead of embedding authorization logic in each microservice, you delegate access decisions to a centralized external authorization service. This decouples authorization from application code and lets you enforce consistent access control across your mesh.

This tutorial walks through the full setup: deploy a sample external authorization service, register it with ASM, create an authorization policy, and verify the end-to-end behavior. The sample service approves only requests that include the x-ext-authz: allow header.

How it works

When a client sends a request to a protected service, the Envoy sidecar intercepts the request and forwards it to the external authorization service. The authorization service inspects request attributes -- headers, path, and method -- and returns an allow or deny decision. Envoy then either forwards the request to the upstream service or returns an error to the caller.

Client  -->  Envoy sidecar  -->  ext-authz service
                  |                      |
                  |<-- allow/deny -------+
                  |
         allow --> upstream service
         deny  --> 403 Forbidden to caller

Behavior details:

  • Authorization checks trigger only for requests that match the rules in the authorization policy. For example, you can limit checks to specific paths.

  • Requests that do not match any rule pass through without authorization checks.

  • If the external authorization service is unavailable, ASM denies all matching requests by default (fail-closed). You can configure fail-open behavior if needed.

Prerequisites

Before you begin, make sure that you have:

Step 1: Deploy the external authorization service

Deploy the ext-authz service in the ACK cluster. This service complies with the Istio external authorization API specification and supports both HTTP and gRPC.

Note

You can use the following sample service or build your own based on the source code on GitHub.

  1. Create a file named ext-authz.yaml with the following content:

    View ext-authz.yaml

       apiVersion: v1
       kind: Service
       metadata:
         name: ext-authz
         labels:
           app: ext-authz
       spec:
         ports:
         - name: http
           port: 8000
           targetPort: 8000
         - name: grpc
           port: 9000
           targetPort: 9000
         selector:
           app: ext-authz
       ---
       apiVersion: apps/v1
       kind: Deployment
       metadata:
         name: ext-authz
       spec:
         replicas: 1
         selector:
           matchLabels:
             app: ext-authz
         template:
           metadata:
             labels:
               app: ext-authz
           spec:
             containers:
             - image: istio/ext-authz:0.6
               imagePullPolicy: IfNotPresent
               name: ext-authz
               ports:
               - containerPort: 8000
               - containerPort: 9000
  2. Apply the manifest:

       kubectl apply -f ext-authz.yaml
  3. Verify that the Pod is running: Expected output:

       kubectl get pod -l app=ext-authz
       NAME                         READY   STATUS    RESTARTS   AGE
       ext-authz-6b5db88f86-2m7c6   2/2     Running   0          79m
  4. Confirm that the authorization service started successfully: Expected output:

       kubectl logs "$(kubectl get pod -l app=ext-authz -n default -o jsonpath={.items..metadata.name})" -n default -c ext-authz
       2023/12/20 08:15:39 Starting gRPC server at [::]:9000
       2023/12/20 08:15:39 Starting HTTP server at [::]:8000
  5. Note the HTTP endpoint: ext-authz.default.svc.cluster.local:8000. You need this value when registering the service with ASM in the next step. To confirm the port, go to the ACK console. Navigate to Clusters > *your cluster* > Network > Services, click ext-authz, and check the Endpoint section.

Step 2: Deploy sample applications

Deploy the httpbin and sleep applications to test authorization behavior.

  1. Create a file named httpbin.yaml with the following content:

    View httpbin.yaml

       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. Apply the manifest:

       kubectl apply -f httpbin.yaml
  3. Create a file named sleep.yaml with the following content:

    View sleep.yaml

       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
  4. Apply the manifest:

       kubectl apply -f sleep.yaml

Step 3: Register the authorization service with ASM

Register the ext-authz service so that ASM can route authorization checks to it.

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

  2. Click the name of your ASM instance. In the left-side navigation pane, choose Mesh Security Center > Custom Authorization Service, then click Define Custom Authorization Service.

  3. On the Register Custom Authorization Service page, click the Custom authorization service (HTTP or gRPC protocol) implemented based on envoy.ext_authz tab. Configure the following parameters and click Create.

Required parameters

ParameterValue for this tutorialDescription
ProtocolHTTPThe protocol used by the authorization service.
Nametest4httpA name to identify the authorization service in ASM.
Service Addressext-authz.default.svc.cluster.localThe fully qualified domain name of the authorization service. Format: <Service name>.<Namespace>.svc.<Cluster domain>.
Port(1 - 65535)8000The HTTP port of the authorization service.
Timeout(second)10Maximum time in seconds for the authorization service to respond. Requests that exceed this timeout are treated as failures.

Optional parameters

ParameterDescription
Skip authentication while authorization service is unavailableControls fail-open or fail-closed behavior. When turned on, ASM allows requests if the authorization service is unreachable (fail-open). When turned off (default), ASM denies requests (fail-closed). Evaluate the security implications before enabling fail-open in production.
Error code returned by asm proxy while Auth-Service is not availableA custom HTTP error code to return when the authorization service is unavailable. Available only when Skip authentication while authorization service is unavailable is turned off.
Carry origin header within auth requestForward specified client request headers to the authorization service. Specify one or more header keys. ASM includes matching headers from the client request in the authorization check. HTTP protocol only.
Add a header in the authentication requestAttach additional headers (key-value pairs) to the authorization request. If a header key already exists in the client request, ASM overwrites the original value. HTTP protocol only.
Overwrite Header when authentication passesAfter a successful authorization check, overwrite specified headers in the client request with headers from the authorization response before forwarding to the upstream service. HTTP protocol only.
Overwrite Header when authentication failsAfter a failed authorization check, overwrite specified headers in the response sent to the caller with headers from the authorization response. HTTP protocol only.
Carry origin request body within auth requestInclude the client request body in the authorization request, up to a specified maximum length. If Allow send incomplete message to Auth-Service is also enabled, ASM truncates the body to the specified length.

Configuration for this tutorial

Configure the following optional parameters for this tutorial. Leave all other optional parameters turned off.

  • Carry origin header within auth request: Turn on and add x-ext-authz.

    Note

    The x-ext-authz header is forwarded to the authorization service so it can inspect the value and make an allow or deny decision.

    Carry headers within an authentication request

  • Overwrite Header when authentication passes: Turn on and add x-ext-authz-check-result.

    Overwrite headers when authentication passes

  • Overwrite Header when authentication fails: Turn on and add x-ext-authz-check-result.

    Overwrite headers when authentication fails

Step 4: Create an authorization policy

Create an authorization policy that defines which requests require authorization checks.

  1. In the ASM console, navigate to your ASM instance and choose Mesh Security Center > AuthorizationPolicy. Click Create.

  2. Configure the following parameters and click Create.

    ParameterValue for this tutorialDescription
    Nametest1A name to identify the authorization policy.
    Policy TypeCustom Authorization ServiceDelegates authorization to the external authorization service registered in Step 3.
    Custom Authorization Servicehttpextauth-test4http(HTTP)The authorization service registered in Step 3.
    NamespacedefaultOn the Workload Scope tab, select the namespace where the target workload runs.
    Effective ScopeServiceApply the policy at the service level.
    WorkloadhttpbinThe workload to protect with authorization checks.
    Request Matching RulesPaths: /headersUnder Add Request Target, turn on Paths and set the value to /headers. Only requests to this path trigger authorization.

Step 5: Verify the authorization behavior

Run three test cases from the sleep Pod to confirm that authorization works as expected.

Test 1: Request to a non-protected path

kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" \
  -c sleep -n default -- \
  curl "http://httpbin.default:8000/ip" -s -o /dev/null -w "%{http_code}\n"

Expected result: 200

The /ip path does not match the /headers rule in the authorization policy, so the request passes through without an authorization check.

Test 2: Request to a protected path with a deny header

kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" \
  -c sleep -n default -- \
  curl "http://httpbin.default:8000/headers" -H "x-ext-authz: deny" -s -i

Expected result: 403 Forbidden

HTTP/1.1 403 Forbidden
x-ext-authz-check-result: denied
...
denied by ext_authz for not found header `x-ext-authz: allow` in the request

The /headers path matches the authorization policy, so the request is forwarded to the ext-authz service. Because the header value is deny instead of allow, authorization fails. The x-ext-authz-check-result: denied header confirms the denial, as configured in Step 3.

Test 3: Request to a protected path with an allow header

kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" \
  -c sleep -n default -- \
  curl "http://httpbin.default:8000/headers" -H "x-ext-authz: allow" -s

Expected result: 200 with a JSON response

{
  "headers": {
    "Accept": "*/*",
    "Host": "httpbin.default:8000",
    "User-Agent": "curl/8.5.0",
    "X-Ext-Authz": "allow",
    "X-Ext-Authz-Check-Result": "allowed",
    ...
  }
}

The authorization check succeeds. The X-Ext-Authz-Check-Result: allowed header confirms that the ext-authz service approved the request.

Security and operational considerations

  • Fail-open vs. fail-closed: By default, ASM denies requests when the authorization service is unavailable (fail-closed). To switch to fail-open mode, enable Skip authentication while authorization service is unavailable in the authorization service configuration. Evaluate the security impact before enabling fail-open in production -- a fail-open configuration allows unauthenticated requests when the authorization service is down.

  • Filter ordering: Place authorization checks early in the request processing pipeline. If other filters (such as Lua filters) modify routing after the authorization check, requests could bypass authorization. For more information about this risk, see the Envoy ext_authz documentation.

  • Timeout tuning: Set the authorization timeout based on the expected latency of your authorization service. A timeout that is too short may cause false denials under load.

Clean up

Remove the resources created in this tutorial:

kubectl delete -f ext-authz.yaml
kubectl delete -f httpbin.yaml
kubectl delete -f sleep.yaml

Also delete the authorization service and policy from the ASM console:

  1. Navigate to Mesh Security Center > AuthorizationPolicy, select the test1 policy, and delete it.

  2. Navigate to Mesh Security Center > Custom Authorization Service, select test4http, and delete it.

What's next