How to implement mutual TLS (mTLS) with ngrok’s API gateway
When developing services that require mutual TLS (mTLS) with an API gateway, your infrastructure and certificate management challenges start mounting straightaway. It’s hard to set up the proper local environment to test how your API responds to an mTLS implementation, and once you do, that environment rarely carries over to your production infrastructure.
You need to protect the data made available on your API, whether you’re dealing with Internet of Things (IoT) devices or sensitive financial data, but how can you get the job done without implementing an API gateway twice? At least?
Let’s explore how ngrok’s API gateway supports your mTLS-enabled service throughout the API lifecycle, from development to production.
What is mutual TLS?
Mutual TLS is a bidirectional security protocol that builds on the standard Transport Layer Security (TLS). Unlike TLS, where only the client has to authenticate the server before communicating with the server, mTLS requires both the client and the server to authenticate each other—a basic implementation of a zero-trust policy. When your API trusts no one by default, even those already in the network, and they must prove who they claim to be, you have strong guarantees your data only moves toward the right consumers.
Before we discuss how mTLS works with an API gateway, let’s take a 101-level look at TLS’s building blocks.
Public and private keys
Private and public keys are crucial in cryptography, particularly in asymmetric encryption. A public key is a cryptographic key that you can use to encrypt messages or verify digital signatures. As the name suggests, you can share it widely with anyone.
A private key is one you keep secret. You can use a private key to generate digital signatures and decrypt messages signed with the associated public key, so exposing it negates the benefits of encryption entirely.
Certificate authority
A certificate authority (CA) is a widely trusted entity that verifies the identities of various entities and issues digital certificates to facilitate encrypted communications over networks. On top of verification and issuance, CAs also maintain and manage the lifecycles of digital certificates, including renewing and revoking them.
TLS certificate
A TLS certificate (X.509) is a digital document that matches a public key to an entity's identity using a digital signature from a certificate authority. It captures key information, such as the algorithm used to create the certificate’s signature, the entity (usually a CA) that issued and signed the certificate, the certificate’s validity, and the entity identified by the certificate.
Why use mTLS for your API?
With standard TLS and an API gateway, the API consumer sends a request to the gateway and begins a TLS handshake, which returns its certificate to the client. The client contacts the CA to confirm the validity of the server’s certificate. Once that’s done, the client can use the embedded public key to decrypt the response via a secure communication channel.
That’s great, but it only protects the consumer—the API gateway, and your upstream API service, has no way of knowing who the consumer is or whether they should be allowed access to the data.
Mutual TLS starts the same way: The client starts a TLS handshake and verifies the server’s certificate against the CA. Here’s where it diverges—next, the server requests the client’s certificate and performs the same verification, ensuring both sides are identified and authenticated to exchange public keys to decrypt all the securely transmitted messages to come.
When paired with an API gateway, mTLS also:
- Creates a baseline mechanism for authentication that’s more durable than basic username/password.
- Identifies and authenticates clients that can’t log in using other means, such as machine-to-machine (M2M) processes or IoT devices.
- Prevents malicious requests to your API aiming to extract data you need to keep secure.
- Stops many potential attacks, like spoofing, brute force, and even phishing attacks by requiring API consumers to have a TLS certificate and private key in hand to complete the mTLS handshake.
- Establishes non-repudiation in how API consumers interact with your service, in that they can’t deny their involvement in specific requests or actions, because of the certificate-based authentication.
mTLS with ngrok’s API gateway
To get started, you’ll need just two things:
- A ngrok account.
- The ngrok agent installed on your API gateway environment—see our quickstart doc for all your options.
Generate your certificates
First, generate public and private keys for the CA using OpenSSL.
openssl genrsa -aes256 -out ca.key 4096
Next, generate an x509 self-signed certificate for the CA.
openssl req -new -x509 -sha256 -days 365 -key ca.key -out ca.crt
With the CA keys established, you can generate a certificate for your client. First, generate a new key with OpenSSL, but with a different name: client.key
.
openssl genrsa -out client.key 4096
Then generate the client's certificate signing request (CSR).
openssl req -new -key client.key -out client.csr
Sign the client’s request using the CA’s certificate and generate an x509 certificate.
openssl \
x509 -req -days 365 -sha256 -in client.csr \
-CA ca.crt -CAkey ca.key -set_serial 0x"$(openssl rand -hex 16)" -out client.crt
Configure your ngrok API gateway for mTLS
Start the ngrok agent to create an endpoint for your API service under an automatically-assigned static ngrok domain. Use the mutual-tls-cas
option and pass the CA certificate you created earlier, which configures ngrok to terminate TLS on the to and reject all requests missing a certificate signed by your CA.
ngrok http 80 --mutual-tls-cas /path/to/ca.crt
Remember: you can always bring your own domain to ngrok!
Verify mTLS is configured correctly
To ensure you’ve correctly configured mTLS, send a request via curl to the endpoint without passing your client’s certificate. You’ll get back not a HTTP error response or an ngrok error code, but a TLS error triggered before your request even reaches your ngrok endpoint.
curl https://<YOUR-NGROK-DOMAIN>
curl: (56) OpenSSL SSL_read: OpenSSL/3.0.13: error:0A00045C:SSL routines::tlsv13 alert certificate required, errno 0
When you pass the client certificate in your request, you can access your API—proof you’ve successfully implemented mTLS with ngrok’s API gateway!successfully implemented mTLS with ngrok’s API gateway!
curl –-cert client.crt –-key client.key https://<YOUR-NGROK-DOMAIN>
Want a quick mTLS + API gateway demo using a sample repo?
We have a very simple Go-based API you can play around with to validate how enabling mTLS works on ngrok’s API gateway.
git clone git@github.com:ngrok-samples/example-api-go.git
cd example-api-go
go run main.go
By default, this API runs locally on port 5000
. Next, fire up your ngrok agent to create a new endpoint, which acts as your gateway between this API and the public internet—you can use the same certificates you created just above.
ngrok http 5000 --mutual-tls-cas /path/to/ca.crt
Finally, you can use curl
to request a new fact about a desert tortoise—entirely secured using mTLS.
curl --cert client.crt --key client.key https://<YOUR-NGROK-DOMAIN>/api/fact/
{"id":"DT029","fact":"Desert tortoises have a specialized nose that filters out sand and dust as they breathe."}
What’s next after mutual TLS and your API gateway?
Deploy your first API gateway with mTLS in just a few minutes—start by grabbing yourself a free ngrok account to help you meet security best practices, whether you’re working in a highly regulated industry or want peace of mind for your API project.
While deploying an API gateway with ngrok, you’re also saving yourself the hassle of configuring web servers, deploying service meshes on Kubernetes, or rolling out custom DNS. Are those on your critical path to going live with your API? ngrok removes all barriers to entry enabling mTLS on any API gateway project, getting you to production without complex reverse proxies or wrestling with your ops team for weeks.
Once you have mTLS enabled, you can extend your API gateway goodness with additional policies and a developer-first configuration workflow:
- API gateway gallery: Drop-in API policy management examples
- Redirect vs URL rewrite in an API gateway
- Traffic Policy Engine - What are CEL variables?
- ngrok blog: Secure your API with JWTs and ngrok’s API Gateway
Have some strong thoughts about ngrok’s API gateway? We’d love to see them in our Community Repo—the home for all discussions, bug reports, and feedback about your mTLS and API gateway experience.