Skip to main content

How to Set Up Mutual TLS Between Services

Stand up a private CA, issue server and client certificates, and configure a server to require and verify client certificates so service-to-service calls use mutual TLS. Covers verification and rotation.

Difficulty
Advanced
Duration
50 minutes
Steps
6

What and why

Mutual TLS (mTLS) authenticates both ends of a connection: the client verifies the server certificate as usual, and the server also requires and verifies the client certificate. It is a foundation of zero-trust service-to-service communication, ensuring only trusted workloads can talk to each other.

Prerequisites

  • Two services communicating over TLS.
  • OpenSSL (or cfssl/step) installed.
  • Basic understanding of certificates and keys.

Steps

1. Create a private CA

openssl genrsa -out ca.key 4096
openssl req -x509 -new -key ca.key -days 3650 -out ca.crt -subj '/CN=Internal CA'

This CA signs all internal certificates; both services must trust ca.crt.

2. Issue a server certificate

openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj '/CN=orders.internal'
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 365 -out server.crt

Include a Subject Alternative Name matching the service DNS name.

3. Issue a client certificate

Repeat the process with CN=billing.internal to produce client.key and client.crt for the calling service.

4. Require client certificates on the server

With Nginx as the TLS terminator:

server {
  listen 443 ssl;
  ssl_certificate     server.crt;
  ssl_certificate_key server.key;
  ssl_client_certificate ca.crt;
  ssl_verify_client on;
}

ssl_verify_client on rejects connections without a valid client certificate signed by the CA.

5. Present the client certificate

The calling service supplies its certificate on outbound calls:

curl --cacert ca.crt --cert client.crt --key client.key https://orders.internal/api

6. Verify and rotate

Connections without a valid client certificate should be refused. Plan rotation: certificates are short-lived in zero-trust setups, so automate issuance. A service mesh like Istio or a secrets engine like Vault can issue and rotate workload certificates automatically.

Verification

  • A request with a valid client certificate succeeds.
  • A request without a client certificate is rejected.
  • A certificate signed by an untrusted CA is rejected.

Next Steps

Automate certificate lifecycle with a mesh (Istio/Linkerd) or Vault PKI so workloads get short-lived certificates and rotation without manual steps, and enforce mTLS mesh-wide with a strict policy.

Prerequisites

  • Two services that communicate over TLS
  • OpenSSL installed
  • Basic TLS knowledge

Steps

  • 1
    Create a private CA
  • 2
    Issue a server certificate
  • 3
    Issue a client certificate
  • 4
    Require client certificates on the server
  • 5
    Present the client certificate
  • 6
    Verify and rotate

Category

Security