All Products
Search
Document Center

Alibaba Cloud Service Mesh:Configure authorization policies for TCP requests

Last Updated:Mar 11, 2026

Authorization policies control which services can communicate over TCP in your mesh. By restricting access to specific ports, you make sure that only authorized traffic reaches a service -- reducing your attack surface without changing application code.

This walkthrough covers deploying sample TCP services, creating an ALLOW authorization policy that permits traffic on a single port, and verifying the result.

How it works

An AuthorizationPolicy resource defines access rules at the namespace or workload level. For TCP traffic, the policy matches on Layer 4 (L4) attributes only. HTTP-specific fields (Layer 7) are not supported.

Important

HTTP-only fields such as methods, paths, and headers do not apply to TCP traffic. If an ALLOW rule includes HTTP-only fields, ASM ignores that rule. Because no valid ALLOW rule remains, all TCP traffic to the workload is denied.

Do not mix HTTP-specific fields into TCP authorization policies.

Prerequisites

Before you begin, make sure that you have:

Deploy sample applications

Deploy two applications in the foo namespace: tcp-echo (receives TCP requests) and sleep (sends TCP requests).

Deploy tcp-echo

The tcp-echo service listens on ports 9000 and 9001. When it receives a message, it prepends hello and returns the result. For example, sending world returns hello world.

  1. Create a file named tcp-echo.yaml with the following content:

    tcp-echo.yaml

       apiVersion: v1
       kind: Service
       metadata:
         name: tcp-echo
         labels:
           app: tcp-echo
           service: tcp-echo
       spec:
         ports:
         - name: tcp
           port: 9000
         - name: tcp-other
           port: 9001
         selector:
           app: tcp-echo
       ---
       apiVersion: apps/v1
       kind: Deployment
       metadata:
         name: tcp-echo
       spec:
         replicas: 1
         selector:
           matchLabels:
             app: tcp-echo
             version: v1
         template:
           metadata:
             labels:
               app: tcp-echo
               version: v1
           spec:
             containers:
             - name: tcp-echo
               image: docker.io/istio/tcp-echo-server:1.2
               imagePullPolicy: IfNotPresent
               args: [ "9000,9001,9002", "hello" ]
               ports:
               - containerPort: 9000
               - containerPort: 9001
  2. Apply the manifest:

       kubectl apply -f tcp-echo.yaml -n foo

Deploy sleep

The sleep service acts as the TCP client for testing.

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

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

       kubectl apply -f sleep.yaml -n foo

Verify connectivity before the policy

Before creating the authorization policy, confirm that sleep can reach tcp-echo on both ports.

Test port 9000:

kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" \
  -c sleep -n foo -- sh -c 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" \
  && echo 'connection succeeded' || echo 'connection rejected'

Expected output:

hello port 9000
connection succeeded

Test port 9001:

kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" \
  -c sleep -n foo -- sh -c 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" \
  && echo 'connection succeeded' || echo 'connection rejected'

Expected output:

hello port 9001
connection succeeded

Both connections succeed because no authorization policy is in place.

Create an authorization policy

Create an ALLOW policy that permits TCP traffic to tcp-echo only on port 9000. Traffic on all other ports is denied.

Note

To test a policy before enforcing it, use trial mode. Trial mode logs policy decisions without blocking traffic, so you can verify expected behavior first.

Use one of the following methods.

Use kubectl

Apply the authorization policy directly from the command line:

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: demo
  namespace: foo
spec:
  action: ALLOW
  rules:
  - to:
    - operation:
        ports:
        - "9000"
EOF

Use the ASM console (YAML)

  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, click the name of the ASM instance.

  4. In the left-side navigation pane, choose Mesh Security Center > AuthorizationPolicy.

  5. Click Create from YAML.

  6. Select foo from the Namespace drop-down list, paste the following YAML into the editor, and click Create:

       kind: AuthorizationPolicy
       apiVersion: security.istio.io/v1beta1
       metadata:
         name: demo
         namespace: foo
       spec:
         action: ALLOW
         rules:
         - to:
           - operation:
               ports:
               - "9000"

Use the ASM console (GUI)

  1. Follow steps 1-4 in the YAML method above to navigate to the AuthorizationPolicy page.

  2. Click Create.

  3. Set the following parameters, then click Create:

    ParameterValue
    Namedemo
    Policy TypeALLOW
    Namespace (on the Workload Scope tab)foo
    Effective ScopeNamespace Scope
    Request Matching RulesTurn on Ports in the Add Request Target section and enter 9000
Important

Do not turn on the Methods switch in the Add Request Target section. The Methods field applies only to HTTP requests. For TCP requests, an ALLOW rule that includes Methods is invalid and silently ignored by ASM. With no valid ALLOW rule remaining, all TCP traffic to the workload is denied.

Verify the authorization policy

After the policy is created, test connectivity again to confirm that only port 9000 is accessible.

Test port 9001 (expected: denied):

kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" \
  -c sleep -n foo -- sh -c 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" \
  && echo 'connection succeeded' || echo 'connection rejected'

Expected output:

connection rejected

Port 9001 is now blocked because the ALLOW policy only permits port 9000.

Test port 9000 (expected: allowed):

kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" \
  -c sleep -n foo -- sh -c 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" \
  && echo 'connection succeeded' || echo 'connection rejected'

Expected output:

hello port 9000
connection succeeded

Port 9000 remains accessible as specified in the policy.

What's next