Post

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.

This post is licensed under CC BY 4.0 by the author.