---
title: Validate mTLS Certificates Before Auth
impact: CRITICAL
impactDescription: ensures mutual authentication between services, preventing unauthorized service impersonation
tags: mtls, certificates, authentication, service-mesh, security, kotlin
---

## Validate mTLS Certificates Before Auth

In a microservices architecture, Mutual TLS (mTLS) ensures that both the client and the server verify each other's certificates. This prevents unauthorized services from connecting to internal APIs even if they are within the same network.

**Incorrect (not enforcing client certificates):**

```kotlin
// Server accepts any connection without requiring a valid client certificate
// or doesn't validate the client's identity.
val server = Netty.createServer(8443) {
    ssl {
        // Only server-side SSL configured
        keyStore = myKeyStore
    }
}
```

**Correct (proper mTLS configuration and validation):**

```kotlin
// 1. Ktor/Netty configuration for mTLS
install(HttpsRedirect)
val server = embeddedServer(Netty, port = 8443) {
    install(Authentication) {
        // Some frameworks support X509 authentication directly
    }
}

// 2. Manual certificate validation in an Interceptor/Filter
fun validateClientCert(request: HttpServletRequest) {
    val certs = request.getAttribute("javax.servlet.request.X509Certificate") as? Array<X509Certificate>
    
    if (certs == null || certs.isEmpty()) {
        throw BadCredentialsException("Client certificate required")
    }

    val clientCert = certs[0]
    val subjectDN = clientCert.subjectX500Principal.name
    
    // Validate the Subject Common Name (CN) against an authorized list
    val authorizedServices = listOf("CN=payment-service", "CN=order-service")
    if (!authorizedServices.any { subjectDN.contains(it) }) {
        throw AccessDeniedException("Service $subjectDN is not authorized")
    }
}
```

**Implementation Steps:**
- **Trust Store:** Configure your server with a trust store containing the CA certificates that are allowed to sign client certificates.
- **Client Auth Mode:** Set SSL engine to `REQUIRE` client authentication (not just `WANT`).
- **Authorization:** Certificate validation (the "m" in mTLS) only handles *authentication*. You still need to *authorize* based on the certificate's subject (e.g., matching the CN to a known service name).

**Tools:** Istio/Linkerd (Service Mesh), OpenSSL, Spring Security X.509, Cloudflare mTLS
