All Products
Search
Document Center

Alibaba Cloud Service Mesh:Configure authorization policies for an application

Last Updated:Mar 11, 2026

Service Mesh (ASM) Ambient mode enforces authorization at two layers. Layer 4 policies, handled by ztunnel, control access based on workload identity at the transport layer. Layer 7 policies, handled by a waypoint proxy, add HTTP-level controls such as method and path restrictions. Use Layer 4 policies when identity-based access control is sufficient. Add a waypoint proxy and Layer 7 policies when you need fine-grained HTTP request filtering.

This walkthrough covers both layers using the Bookinfo sample application: first restricting access at Layer 4, then deploying a waypoint proxy to enforce Layer 7 rules.

How it works

ASM Ambient mode separates authorization enforcement into two layers:

  • Layer 4 (ztunnel): A Rust-based per-node proxy deployed as a DaemonSet. Ztunnel handles Layer 3 and Layer 4 traffic, including mTLS, identity verification, Layer 4 authorization, and observability for all pods on the node. Policies at this layer match on source identity, namespace, and IP, but not on HTTP attributes.

  • Layer 7 (waypoint proxy): An optional Envoy-based proxy that processes HTTP traffic. Deploy a waypoint when you need to enforce rules based on HTTP methods, paths, or headers.

When both layers are active, traffic flows through ztunnel first, then through the waypoint. The Layer 4 policy must explicitly allow the waypoint's ServiceAccount -- otherwise ztunnel blocks the waypoint's traffic before it reaches the target pod.

Supported Layer 4 policy attributes

Ztunnel evaluates only the following attributes. Any attribute outside this set requires a waypoint proxy for Layer 7 enforcement.

TypeAttributePositive matchNegative match
SourcePeer identityprincipalsnotPrincipals
SourceNamespacenamespacesnotNamespaces
SourceIP blockipBlocksnotIpBlocks
OperationDestination portportsnotPorts

Layer 4 vs. Layer 7 policy targeting

AspectLayer 4 (ztunnel)Layer 7 (waypoint)
Targeting mechanismselector with matchLabelstargetRefs pointing to a Service
Enforced byztunnel (per-node DaemonSet)Waypoint proxy (Envoy)
Supported attributesIdentity, namespace, IP, portAll Layer 4 attributes + HTTP method, path, headers
Deployment requirementNone (always active in Ambient mode)Requires a waypoint proxy
Important

If a policy containing Layer 7 attributes (such as methods or paths) is applied at Layer 4 through a workload selector instead of targetRefs, ztunnel cannot evaluate it and fails safe by denying all traffic matched by that policy. Always use targetRefs for policies that include HTTP-level rules.

Prerequisites

Before you begin, make sure that you have:

Deploy the test client

Deploy the Sleep application as a test client in your cluster:

kubectl apply -f - <<EOF
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: registry.cn-hangzhou.aliyuncs.com/acs/curl:8.1.2
        command: ["/bin/sleep", "infinity"]
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - mountPath: /etc/sleep/tls
          name: secret-volume
      volumes:
      - name: secret-volume
        secret:
          secretName: sleep-secret
          optional: true
EOF

Enforce Layer 4 access control

Layer 4 policies are enforced by ztunnel. The following steps restrict access to productpage so that only the ingress gateway's ServiceAccount can reach it.

Step 1: Apply the Layer 4 policy

Create an AuthorizationPolicy that allows only istio-ingressgateway to access pods with the app: productpage label:

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: productpage-ztunnel
  namespace: default
spec:
  selector:
    matchLabels:
      app: productpage
  action: ALLOW
  rules:
  - from:
    - source:
        principals:
        - cluster.local/ns/istio-system/sa/istio-ingressgateway
EOF

Step 2: Verify browser access

Open http://<ingress-gateway-ip>/productpage in a browser. The page loads normally because the request arrives through the ingress gateway, whose ServiceAccount is allowed by the policy.

Step 3: Verify that the Sleep client is blocked

Send a request from the Sleep application:

kubectl exec deployment/sleep -- curl -s "http://productpage:9080/productpage" -I

Expected output:

command terminated with exit code 56

The connection is refused at the transport layer. Because ztunnel operates at Layer 4, no HTTP status code is returned -- the connection is dropped.

Add Layer 7 access control with a waypoint proxy

Layer 7 policies require a waypoint proxy. After deploying the waypoint, you label the namespace so that all service traffic passes through it. This enables HTTP-level authorization rules.

Step 1: Deploy a waypoint proxy

kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: waypoint
spec:
  gatewayClassName: istio-waypoint
  listeners:
  - name: mesh
    port: 15008
    protocol: HBONE
EOF

Step 2: Wait for the waypoint to become ready

kubectl get gtw

Wait until the PROGRAMMED column shows True:

NAME       CLASS            ADDRESS        PROGRAMMED   AGE
waypoint   istio-waypoint   172.16.99.15   True         2m29s

Step 3: Route namespace traffic through the waypoint

Label the default namespace so that all service traffic is routed through the waypoint:

kubectl label namespace default istio.io/use-waypoint=waypoint --overwrite

Step 4: Create the Layer 7 policy

This policy allows only the Sleep application to access productpage, and only with the GET method:

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: productpage-waypoint
  namespace: default
spec:
  targetRefs:
  - kind: Service
    group: ""
    name: productpage
  action: ALLOW
  rules:
  - from:
    - source:
        principals:
        - cluster.local/ns/default/sa/sleep
    to:
    - operation:
        methods: ["GET"]
EOF
Note

Layer 7 policies use targetRefs to attach to a specific service at the waypoint, rather than selector labels used in Layer 4 policies. The to field restricts allowed HTTP methods.

Step 5: Update the Layer 4 policy to allow waypoint traffic

The waypoint proxy now sits between clients and the productpage pods. Ztunnel sees the waypoint -- not the original client -- as the traffic source. Update the Layer 4 policy to include the waypoint's ServiceAccount:

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: productpage-ztunnel
  namespace: default
spec:
  selector:
    matchLabels:
      app: productpage
  action: ALLOW
  rules:
  - from:
    - source:
        principals:
        - cluster.local/ns/istio-system/sa/istio-ingressgateway
        - cluster.local/ns/default/sa/waypoint
EOF

Step 6: Verify the Layer 7 policy

Run three tests to confirm the policy works as expected.

Test 1: DELETE from Sleep (denied -- method not allowed)

kubectl exec deploy/sleep -- curl -s "http://productpage:9080/productpage" -X DELETE

Expected output:

RBAC: access denied

The Sleep ServiceAccount is allowed, but the DELETE method is not.

Test 2: GET from reviews-v1 (denied -- identity not allowed)

kubectl exec deploy/reviews-v1 -- curl -s http://productpage:9080/productpage

Expected output:

RBAC: access denied

The reviews-v1 ServiceAccount is not listed in the policy's principals.

Test 3: GET from Sleep (allowed)

kubectl exec deploy/sleep -- curl -s http://productpage:9080/productpage | grep -o "<title>.*</title>"

Expected output:

<title>Simple Bookstore App</title>

All three results match the policy configuration, confirming that both Layer 4 and Layer 7 authorization policies are working correctly.

What's next