← Recipes

阅读中文版本

Require mTLS for Service-to-Service Calls

Issue client certificates, configure the server to require and verify them, and validate the chain and identity so only trusted services can connect.

~45 minsecuritymtlstls

Task

Enforce mutual TLS on an internal service so callers must present a trusted client certificate.

When to use this

An internal API trusts anything on the network, so lateral movement inside the cluster grants access without any credential.

Prerequisites

  • A certificate authority for internal certs
  • A server that can require client certificates

Steps

1. Issue client certificates from an internal CA with meaningful subject or SAN identities.

Expected output: Each service has a verifiable identity.

2. Configure the server to require and verify client certificates against the CA.

Expected output: Untrusted clients are rejected during the handshake.

3. Map the certificate identity to an authorization principal.

Expected output: Access control works on real identities, not IPs.

4. Rotate client certificates and reject expired or revoked ones.

openssl s_client -connect api.internal:443 -cert client.crt -key client.key -CAfile ca.crt

Expected output: Compromise and expiry are handled.

Troubleshooting

Problem

Handshake failures only

Solution

Log the certificate verification error explicitly; generic TLS errors hide the real cause.

Problem

Certificates used as the only authz

Solution

mTLS proves identity, not permission; still enforce authorization based on the identity.

Limitations

  • mTLS requires certificate lifecycle management, which is heavier than static credentials.
  • It does not protect against a compromised service that legitimately holds a valid certificate.

Context

Enforce mutual TLS on an internal service so callers must present a trusted client certificate. An internal API trusts anything on the network, so lateral movement inside the cluster grants access without any credential.

Steps

  1. Issue client certificates from an internal CA with meaningful subject or SAN identities. Expected: Each service has a verifiable identity.
  2. Configure the server to require and verify client certificates against the CA. Expected: Untrusted clients are rejected during the handshake.
  3. Map the certificate identity to an authorization principal. Expected: Access control works on real identities, not IPs.
  4. Rotate client certificates and reject expired or revoked ones. Expected: Compromise and expiry are handled.
openssl verify -CAfile ca.crt client.crt
# nginx
ssl_client_certificate /etc/ssl/ca.crt;
ssl_verify_client on;

Verify

  • Each service has a verifiable identity.
  • Untrusted clients are rejected during the handshake.
  • Access control works on real identities, not IPs.
  • Compromise and expiry are handled.

Limits

  • mTLS requires certificate lifecycle management, which is heavier than static credentials.
  • It does not protect against a compromised service that legitimately holds a valid certificate.