Skip to main content

Enable Mutual TLS

Estimated reading time: 0 min read

Mutual TLS (aka mTLS) asks the client to provide a certificate as its identifier so that the server can verify it in a TLS handshake.

This guide will show you how to enable the mTLS to protect your Applications.


Please read What is Certificate before you go ahead.

Prepare Certificates

To show the mTLS feature, we use openssl to generate three key pairs:

# Generate the CA certificate and private key
openssl req -x509 -nodes -new -keyout ca.key -out ca.crt -days 3650 -subj "/C=/ST=/L=/O=/OU=web/CN=private_ca"

# Generate the server certificate sign request and its private key
openssl req -newkey rsa:2048 -nodes -days 3650 -keyout server.key -out server.req

# Generate the server certificate
openssl x509 -req -days 3650 -set_serial 01 -in server.req -out server.crt -CA ca.crt -CAkey ca.key

# Generate the client certificate sign request and its private key
openssl req -newkey rsa:2048 -nodes -days 3650 -keyout client.key -out client.req -subj "/C=/ST=/L=/O=/OU=web/"

# Generate the client certificate
openssl x509 -req -days 3650 -set_serial 01 -in client.req -out client.crt -CA ca.crt -CAkey ca.key

You can skip the above steps if you already have these certificates.

Create Certificate

Follow the tips in Enable Mutual TLS and upload the server certificate, private key, CA certificate, API7 Cloud creates a Certificate object.

Certificate Entry with mTLS

Create Application and API

We'll create an Application with the following details in this guide.

  • The Application name is mtls-auth-app.
  • The path prefix is /v1.
  • The protocol is HTTPS.
  • The HTTP Host is
  • The upstream URL is

Besides, we'll create an API inside the mtls-auth-app Application.

  • The API name is json.
  • The path is /json (exact match).
  • Accepted HTTP method is GET.

If you don't know how to configure an Application and API, please refer to the Getting Started guides first

Test mTLS

Now let's try to access the JSON API without a client certificate.

curl --resolve '' --cacert ca.crt -i
HTTP/2 400
date: Thu, 09 Jun 2022 02:29:01 GMT
content-type: text/html; charset=utf-8
content-length: 154
server: APISIX/2.15.0

<head><title>400 Bad Request</title></head>
<center><h1>400 Bad Request</h1></center>

You will get a 400 Bad Request response instead of a TLS error to report something like "missing client certificate". This is due to the mTLS mechanism in Apache APISIX.

Now let's take the client certificate and reaccess it.

curl --resolve '' --cert client.crt --key client.key --cacert ca.crt
"slideshow": {
"author": "Yours Truly",
"date": "date of publication",
"slides": [
"title": "Wake up to WonderWidgets!",
"type": "all"
"items": [
"Why <em>WonderWidgets</em> are great",
"Who <em>buys</em> WonderWidgets"
"title": "Overview",
"type": "all"
"title": "Sample Slide Show"

After we take the correct client certificate, the TLS handshake is successful, and the API request returns the correct response.

See Also