mTLS in Microservices
Introduction
Mutual TLS (mTLS) establishes trust between services by requiring both sides to present certificates during the TLS handshake. It is a core building block for Zero Trust service-to-service communication because it binds identity to cryptographic proof.
How mTLS Works
During the TLS handshake, the client validates the server certificate, and the server validates the client certificate. Both sides verify certificate chains and expiry, ensuring that only trusted identities can communicate.
- The client presents its certificate after the server request.
- The server enforces certificate validation against a trusted CA.
- Session keys are negotiated only after mutual verification.
Certificate Management
mTLS succeeds or fails based on certificate lifecycle discipline.
- Use a dedicated internal CA or workload identity provider.
- Rotate certificates frequently and automate renewal.
- Maintain short certificate lifetimes and tight revocation windows.
Policy and Authorization
mTLS authenticates identities, but authorization still requires policy.
- Bind certificate subjects to service identities.
- Enforce allowlists for specific service-to-service paths.
- Combine mTLS with JWT for fine-grained authorization.
C# Example: Kestrel Client Certificate Enforcement
The following ASP.NET Core configuration requires client certificates and maps them to identities.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using Microsoft.AspNetCore.Server.Kestrel.Https;
using System.Security.Cryptography.X509Certificates;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(options =>
{
options.ConfigureHttpsDefaults(httpsOptions =>
{
httpsOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
httpsOptions.ClientCertificateValidation = (cert, chain, errors) =>
errors == System.Net.Security.SslPolicyErrors.None;
});
});
var app = builder.Build();
app.Use(async (context, next) =>
{
X509Certificate2? clientCert = await context.Connection.GetClientCertificateAsync();
if (clientCert is null)
{
context.Response.StatusCode = 401;
return;
}
await next();
});
app.MapGet("/health", () => "ok");
app.Run();
Operational Pitfalls
- Validate certificate chains on every node to avoid implicit trust.
- Monitor certificate expiry and rotate before failures occur.
- Avoid storing private keys in application containers.
Conclusion
mTLS offers strong workload authentication, but its effectiveness depends on certificate lifecycle automation and explicit authorization policies. Use it as part of a layered defense rather than a standalone control.