All Products
Search
Document Center

Alibaba Cloud Service Mesh:Configure an mTLS gRPC service with an ASM gateway

Last Updated:Jun 21, 2026

You can use an ASM Gateway to secure your gRPC services with mutual Transport Layer Security (mTLS). This ensures that only authorized clients can access your services, enforcing end-to-end encryption and two-way authentication to prevent eavesdropping, tampering, and unauthorized access.

Prerequisites

Background

The traffic management feature of Service Mesh allows you to access internal gRPC services through an ingress gateway. Because gRPC is based on the HTTP/2 protocol, you can use Transport Layer Security (TLS) or mutual TLS (mTLS) to encrypt data in transit and ensure data security. ASM Gateway also supports gRPC over TLS/mTLS, which allows the gateway to perform TLS termination for encrypted TCP streams. This eliminates the need for separate TLS configurations in applications within the service mesh.

Procedure

Step 1: Deploy a sample application

  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 > Deployments.

  3. At the top of the Deployments page, select a namespace from the Namespace drop-down list and click Create Resources in YAML.

  4. On the Create page, paste the following YAML into the editor and click Create.

    Expand to view the YAML

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: istio-grpc-server-v1
      labels:
        app: istio-grpc-server
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: istio-grpc-server
          version: v1
      template:
        metadata:
          labels:
            app: istio-grpc-server
            version: v1
        spec:
          containers:
          - args:
            - --address=0.0.0.0:8080
            image: registry.cn-hangzhou.aliyuncs.com/aliacs-app-catalog/istio-grpc-server
            imagePullPolicy: Always
            livenessProbe:
              exec:
                command:
                - /bin/grpc_health_probe
                - -addr=:8080
              initialDelaySeconds: 2
            name: istio-grpc-server
            ports:
            - containerPort: 8080
            readinessProbe:
              exec:
                command:
                - /bin/grpc_health_probe
                - -addr=:8080
              initialDelaySeconds: 2
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: istio-grpc-server
      labels:
        app: istio-grpc-server
    spec:
      ports:
      - name: grpc-backend
        port: 8080
        protocol: TCP
      selector:
        app: istio-grpc-server
      type: ClusterIP
    ---
    Note

    Due to Istio's protocol selection mechanism, the value of the name parameter in the ports field of the Service configuration must start with http2- or grpc-. Otherwise, Istio cannot correctly identify the service protocol.

Step 2: Deploy an ingress gateway

This example uses the default port 443 to expose the service. For more information, see Create an ingress gateway.

Step 3: Configure Service Mesh routing rules

  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 target instance, or click Manage in the Actions column.

  3. Create a Gateway.

    1. On the details page of the ASM instance, choose ASM Gateways > Gateway in the left-side navigation pane.

    2. On the Gateway page, click Create from YAML.

    3. On the Create page, select default from the Namespaces drop-down list, paste the following YAML into the editor, and then click Create.

      apiVersion: networking.istio.io/v1beta1
      kind: Gateway
      metadata:
        name: gw-grpc-443
        namespace: default
      spec:
        selector:
          istio: ingressgateway
        servers:
          - hosts:
              - '*'
            port:
              name: https
              number: 443
              protocol: HTTPS
            tls:
              credentialName: example-credential
              mode: MUTUAL
                                      
  4. Create a VirtualService.

    1. On the details page of the ASM instance, choose Traffic Management Center > VirtualService in the left-side navigation pane.

    2. On the VirtualService page, click Create from YAML.

    3. On the Create page, select default from the Namespaces drop-down list, paste the following YAML into the editor, and then click Create.

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: grpc-vs
      spec:
        hosts:
        - "*"
        gateways:
        - gw-grpc-443
        http:
          - match:
              - port: 443
            route:
              - destination:
                  host: istio-grpc-server

Step 4: Configure certificates

gRPC clients typically require certificates with a Subject Alternative Name (SAN). We recommend that you use the sample certificates from the grpc-go repository. You must configure these certificates in the istio-system namespace of the ACK cluster, as they are used by the ASM Gateway.

  • For ASM instances earlier than v1.17

    Run the following command to create a Secret in the istio-system namespace:

    kubectl create -n istio-system secret generic example-credential --from-file=tls.key=server_key.pem --from-file=tls.crt=server_cert.pem --from-file=ca.crt=client_ca_cert.pem
    Note

    The Secret name must match the credentialName value specified in the Gateway.

  • For ASM instances of v1.17 and later

    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 target instance. In the left-side navigation pane, choose ASM Gateways > Certificate Management.

    3. On the Certificate Management page, click Create. In the Certificate Information panel, configure the parameters and click OK.

Step 5: Run the gRPC client

This tutorial uses the official grpc-go sample as the gRPC mTLS client.

  1. Follow the official grpc-go tutorial to install the gRPC dependencies. For more information, see Quick start for gRPC in Go.

  2. Follow the official grpc-go tutorial to clone the grpc-go code repository. For more information, see the grpc-go repository.

  3. Replace the content of the /grpc-go/examples/helloworld/greeter_client/main.go file with the following code. Change the value of address to ":443".

    Expand to view the code

    /*
     *
     * Copyright 2015 gRPC authors.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     *
     */
    
    // Package main implements a client for Greeter service.
    package main
    
    import (
        "context"
        "crypto/tls"
        "crypto/x509"
        "flag"
        "io/ioutil"
        "log"
        "time"
    
        "google.golang.org/grpc"
        "google.golang.org/grpc/credentials"
        pb "google.golang.org/grpc/examples/helloworld/helloworld"
    )
    
    const (
        defaultName = "world"
    )
    
    var (
        addr       = flag.String("addr", "localhost:50051", "the address to connect to")
        name       = flag.String("name", defaultName, "Name to greet")
        cert       = flag.String("cert", "./data/x509/client_cert.pem", "server cert for mTLS")
        key        = flag.String("key", "./data/x509/client_key.pem", "server key for mTLS")
        cacert     = flag.String("cacert", "./data/x509/ca_cert.pem", "ca cert for mTLS")
        servername = flag.String("servername", "x.test.example.com", "the cert name of server")
    )
    
    func main() {
        flag.Parse()
    
        certPair, err := tls.LoadX509KeyPair(*cert, *key)
        if err != nil {
            log.Fatalf("failed to load client cert: %v", err)
        }
    
        ca := x509.NewCertPool()
        caFilePath := *cacert
        caBytes, err := ioutil.ReadFile(caFilePath)
        if err != nil {
            log.Fatalf("failed to read ca cert %q: %v", caFilePath, err)
        }
        if ok := ca.AppendCertsFromPEM(caBytes); !ok {
            log.Fatalf("failed to parse %q", caFilePath)
        }
    
        tlsConfig := &tls.Config{
            ServerName:   *servername,
            Certificates: []tls.Certificate{certPair},
            RootCAs:      ca,
        }
    
        conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)))
        if err != nil {
            log.Fatalf("did not connect: %v", err)
        }
        defer conn.Close()
        c := pb.NewGreeterClient(conn)
    
        // Contact the server and print out its response.
        ctx, cancel := context.WithTimeout(context.Background(), time.Second)
        defer cancel()
        r, err := c.SayHello(ctx, &pb.HelloRequest{Name: *name})
        if err != nil {
            log.Fatalf("could not greet: %v", err)
        }
        log.Printf("Greeting: %s", r.GetMessage())
    }
                            
  4. After you replace the code, navigate to the examples directory and run the following command.

    go run helloworld/greeter_client/main.go

    Expected output:

    Greeting: Hello world

    If the certificates are not correctly configured, the client returns an error similar to the following. If this occurs, follow the steps in this topic to configure the certificates again.

    2022/09/23 15:44:44 could not greet: rpc error: code = Unavailable desc = connection error: desc = "transport: authentication handshake failed: x509: certificate signed by unknown authority"
    exit status 1