Post

Lets Encrypt Certificates Will No Longer Be Usable For Client Authentication Starting 13 May 2026

Lets Encrypt Certificates Will No Longer Be Usable For Client Authentication Starting 13 May 2026

Introduction

On 14 May 2025, Let’s Encrypt dropped a bombshell announcement that will fundamentally change how we use their certificates: All certificates issued after 13 May 2026 will no longer support TLS client authentication. This isn’t a technical limitation but a compliance requirement from the CA/Browser Forum’s Baseline Requirements v2.0 that mandates separate certificate hierarchies for server and client authentication.

For DevOps engineers and homelab enthusiasts, this represents a critical inflection point. TLS client authentication is widely used in:

  • Kubernetes API server authentication
  • Private service-to-service communication
  • VPN client authentication (OpenVPN, WireGuard)
  • Database access control
  • IoT device authentication

The upcoming change means that after the cutoff date:

  1. Existing certificates will continue working until expiration
  2. New/renewed certificates won’t contain id-kp-clientAuth in Extended Key Usage (EKU)
  3. Client authentication setups using Let’s Encrypt certs will break unless migrated

This guide provides a comprehensive migration path for production systems and homelab environments, covering alternative solutions, configuration changes, and security best practices to maintain secure client authentication beyond 2026.

Understanding TLS Client Authentication

The Technical Foundation

TLS client authentication operates through X.509 certificate validation during the TLS handshake:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Client                                                  Server
------                                                  ------
ClientHello         
                      -------------------------------->
                                                ServerHello
                                          ServerCertificate
                         <--------------------------------
CertificateRequest      
                      -------------------------------->
ClientCertificate
ClientKeyExchange
CertificateVerify
[ChangeCipherSpec]
Finished                -------------------------------->
                                          [ChangeCipherSpec]
                         <--------------------------------
                          Application Data              
                         <------------------------------->

Extended Key Usage (EKU) Explained

EKU extensions (RFC 5280 Section 4.2.1.12) define certificate purposes:

EKU OIDPurposeCurrent LE SupportPost-2026 LE Support
1.3.6.1.5.5.7.3.1Server Authentication
1.3.6.1.5.5.7.3.2Client Authentication
1.3.6.1.5.5.7.3.3Code Signing

Why Let’s Encrypt Is Making This Change

The CA/Browser Forum’s Baseline Requirements v2.0 mandates:

“Certificates containing the id-kp-clientAuth EKU MUST be issued from a separate subordinate CA certificate that does not contain the id-kp-serverAuth EKU”

This eliminates cross-use scenarios where a single certificate could authenticate both clients and servers - a security hardening measure to reduce attack surfaces.

Prerequisites for Migration

Inventory Your Client Auth Usage

Identify systems using Let’s Encrypt certs for client auth:

1
2
3
4
5
6
7
# Find certificates with clientAuth EKU
openssl x509 -noout -ext extendedKeyUsage -in cert.pem | grep -q "TLS Web Client Authentication" && \
  echo "Certificate used for clientAuth"

# Kubernetes API server check
kubectl get --raw / | openssl s_client -connect localhost:6443 -showcerts 2>/dev/null | \
  openssl x509 -noout -text | grep "TLS Web Client Authentication"

System Requirements

  • OpenSSL 1.1.1+ or libssl equivalent
  • Root CA management tooling (cfssl, step-ca, openssl)
  • Certificate expiry monitoring (Prometheus, Nagios)
  • Systems capable of handling PKCS#8/PKCS#12 formats

Security Considerations

  1. Private key storage requirements:
    • Hardware Security Modules (HSMs) for production
    • Encrypted at rest with AES-256+
  2. Certificate revocation strategy:
    • OCSP stapling
    • CRL distribution points
  3. Key rotation policies (90-day recommended)

Migration Options and Setup

Option 1: Private PKI with step-ca

Smallstep’s step-ca provides a modern alternative:

1
2
3
4
5
6
7
8
9
10
11
12
# Install step CLI
wget https://dl.step.sm/gh-release/cli/docs-cli-install/v0.25.0/step-cli_0.25.0_amd64.deb
sudo dpkg -i step-cli_0.25.0_amd64.deb

# Initialize PKI
step ca init --name="Private CA" \
             --dns="ca.example.com" \
             --address=":443" \
             --provisioner="admin@example.com"

# Start CA server
step-ca $(step path)/config/ca.json

Client certificate issuance:

1
2
3
4
5
6
7
8
# Generate client cert
step ca certificate "client.example.com" client.crt client.key \
  --provisioner "admin@example.com" \
  --not-after 2160h # 90-day validity

# Verify EKU
openssl x509 -in client.crt -noout -ext extendedKeyUsage
# Output: TLS Web Client Authentication

Option 2: OpenSSL-Based PKI

Traditional OpenSSL CA setup:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Create CA directory structure
mkdir -p ca/{certs,crl,newcerts,private}
touch ca/index.txt
echo 1000 > ca/serial

# Generate CA key
openssl genpkey -algorithm RSA -out ca/private/ca.key -aes256

# Create CA cert
openssl req -new -x509 -days 3650 -key ca/private/ca.key \
  -out ca/ca.crt -subj "/CN=My Private CA"

# Client cert signing
openssl req -newkey rsa:2048 -nodes -keyout client.key \
  -out client.csr -subj "/CN=client1"
openssl ca -config openssl.cnf -extensions usr_cert \
  -days 90 -notext -md sha256 -in client.csr -out client.crt

Option 3: Cloud-Based Alternatives

ProviderClient Auth SupportACME SupportPricing Model
AWS ACM Private CAPer-certificate
Google CASPer-operation
Azure Key VaultPer-certificate

Configuration Examples

Kubernetes API Server Migration

Before (Let’s Encrypt):

1
2
3
4
5
6
apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority-data: LS0t... # LE ISRG Root X1
    server: https://k8s.example.com:6443

After (Private CA):

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority-data: LS0t... # Private CA cert
    server: https://k8s.example.com:6443
users:
- name: admin
  user:
    client-certificate: /path/to/client.crt
    client-key: /path/to/client.key

Nginx Client Authentication

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server {
    listen 443 ssl;
    server_name secure.example.com;

    # Server certificate (still from LE)
    ssl_certificate /etc/letsencrypt/live/secure.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/secure.example.com/privkey.pem;

    # Client authentication (migrated to private CA)
    ssl_client_certificate /etc/ssl/private/ca.crt;
    ssl_verify_client on;
    ssl_verify_depth 2;

    location / {
        if ($ssl_client_verify != SUCCESS) {
            return 403;
        }
        proxy_pass http://backend;
    }
}

Security Hardening Best Practices

Certificate Policies

  1. Short Validity Periods: 90-day maximum for client certificates
  2. Strong Key Algorithms:
    1
    2
    3
    4
    5
    6
    
    # Ed25519
    openssl genpkey -algorithm ED25519 -out client.key
    
    # ECDSA P-384
    openssl genpkey -algorithm EC -out client.key \
      -pkeyopt ec_paramgen_curve:P-384
    
  3. OCSP Stapling:
    1
    2
    
    # Generate OCSP responder URL
    step ca certificate --include-revoked --ocsp http://ocsp.example.com client.crt
    

Private CA Security

  1. Offline Root CA:
    • Generate root CA on air-gapped system
    • Store private key in HSM or encrypted storage
  2. CRL/OCSP Enforcement:
    1
    2
    3
    
    ssl_crl /etc/ssl/ca/crl.pem;
    ssl_stapling on;
    ssl_stapling_verify on;
    
  3. Certificate Transparency Logs:
    1
    
    step ca ct log-submit --log=https://ct.example.com client.crt
    

Migration Timeline

DateAction ItemImpact Level
Q3 2024Audit existing client auth implementationsCritical
Q4 2024Test private PKI solutionsHigh
Q1 2025Deploy staging environmentMedium
Q3 2025Begin production migrationHigh
Q1 2026Complete migrationCritical
May 13, 2026LE clientAuth support endsBlocking

Troubleshooting Common Issues

Certificate Verification Failures

Error message:

1
SSL_CTX_set0_verify_cert_store: certificate verify error

Diagnosis:

1
2
openssl verify -CAfile ca.crt client.crt
openssl s_client -connect host:port -cert client.crt -key client.key -CAfile ca.crt

Kubernetes API Server Authentication Failure

Check kube-apiserver logs:

1
journalctl -u kube-apiserver -n 100 | grep -i "client certificate"

Verify RBAC binding:

1
2
kubectl get rolebindings,clusterrolebindings -A -o json | \
  jq '.items[] | select(.subjects[].name=="CN=client1")'

Conclusion

The deprecation of client authentication in Let’s Encrypt certificates marks a significant shift in the TLS landscape. While challenging, this change presents an opportunity to implement more secure, purpose-specific authentication mechanisms.

Key takeaways:

  1. Private PKIs are now essential for client authentication
  2. Certificate lifecycle management must be automated
  3. Short-lived certificates improve security posture
  4. Zero-trust architectures benefit from this separation

Migration resources:

Start planning your migration today to ensure uninterrupted service before the May 2026 deadline.

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