Beyond basic mutual TLS setup, this guide covers practical Nginx configuration patterns for using client certificates as an authentication mechanism within a real application, including passing identity information to your backend.
Recap: What Client Certificate Authentication Provides
Unlike passwords or API keys, a client certificate provides cryptographic proof of identity that's difficult to steal or phish — see How to Set Up Mutual TLS (mTLS) Authentication for the foundational setup this article builds on.
Requiring Client Certificates for Specific Locations Only
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
ssl_client_certificate /etc/ssl/certs/ca.crt;
location /public {
ssl_verify_client off;
}
location /admin {
ssl_verify_client on;
proxy_pass http://backend;
}
}
Requiring client certificates only for specific sensitive paths, while leaving public-facing paths open to normal browser access.
Passing Client Certificate Details to Your Backend
location /admin {
ssl_verify_client on;
proxy_pass http://backend;
proxy_set_header X-SSL-Client-Verify $ssl_client_verify;
proxy_set_header X-SSL-Client-CN $ssl_client_s_dn_cn;
proxy_set_header X-SSL-Client-Serial $ssl_client_serial;
}
Your backend application can then use these headers for fine-grained authorization logic based on the specific authenticated client.
Verifying the Verification Status in Your Application
if ($_SERVER['HTTP_X_SSL_CLIENT_VERIFY'] !== 'SUCCESS') {
http_response_code(403);
exit('Client certificate required');
}
Always verify the certificate status explicitly in your application logic too, not solely relying on Nginx's enforcement — defense in depth against any potential proxy misconfiguration.
Restricting by Specific Certificate Subject
if ($ssl_client_s_dn_cn != "authorized-client-1") {
return 403;
}
Beyond just requiring any valid client certificate, restrict access to specific expected client identities if you're authenticating a known, limited set of clients.
Handling Certificate Revocation
ssl_crl /etc/ssl/certs/ca-crl.pem;
Reference a Certificate Revocation List so previously-issued but now-revoked client certificates are correctly rejected — important for maintaining security as your set of trusted clients changes over time.
Combining Client Certificates with Other Authentication (Defense in Depth)
Client certificate authentication can be layered with application-level authentication (see How to Set Up API Authentication with JWT) rather than used as the sole authentication mechanism, providing multiple independent security layers for particularly sensitive endpoints.
Testing Your Configuration Thoroughly
# Should succeed
curl --cert client.crt --key client.key https://yourdomain.com/admin
# Should fail
curl https://yourdomain.com/admin
# Should succeed (public path doesn't require client cert)
curl https://yourdomain.com/public
Common Errors
Backend receives verification headers but doesn't check them — a common oversight; Nginx enforcing the TLS handshake requirement doesn't automatically mean your application logic correctly uses the passed identity information for authorization decisions.
Continue Reading
- How to Set Up Mutual TLS (mTLS) Authentication
- How to Set Up API Authentication with JWT
- How to Build and Secure a REST API on a VPS
Browse more articles in SSL/TLS & Certificates.