Certificates expire — an expired cert is a self-inflicted outage. Automate issuance and renewal with ACME, plan for revocation and rotation, and use mutual TLS so services authenticate each other.
Short-lived certificates are more secure but only workable if renewal is automated — the biggest real-world PKI failure is an expired certificate taking down a service because someone forgot to renew it manually. ACME (used by Let's Encrypt) automates the whole flow: prove you control the domain, get a cert, and renew well before expiry, unattended.
Automate renewal required — Manual certificate renewal is a leading cause of outages. Always automate issuance and renewal, and alert well before expiry as a backstop.# Let's Encrypt via certbot — issue + auto-renew, no human in the loop
certbot certonly --nginx -d app.example.com
# certbot installs a timer that renews when < 30 days remain:
certbot renew --dry-run # test the renewal path
# how ACME proves you own the domain (the "challenge"):
# HTTP-01 serve a token at http://app.example.com/.well-known/acme-challenge/
# DNS-01 publish a TXT record (works for wildcards + private hosts)
# then the CA issues a 90-day cert; automation renews it forever.Rotation is replacing a certificate (and ideally its key) before it expires or if it may be compromised. Rotate on a schedule, generate a fresh key pair rather than reusing the old key, and keep private keys off disk where possible (in an HSM or KMS). Automated short lifetimes make rotation a non-event instead of an annual fire drill.
Rotation done right:
- short lifetimes (90 days or less) so rotation is routine + automated
- generate a NEW key pair on rotation (don't reuse the old private key)
- store private keys in an HSM/KMS where they can't be exfiltrated;
if that's not possible, tight file perms (0600) + never in git
- overlap old + new during cutover so there's no downtime
- MONITOR expiry and alert at 30/14/7 days as a backstop to automation
An expired cert is an outage you scheduled for yourself. Automate it away.If a private key is compromised, the certificate must be distrusted before its natural expiry — that is revocation. It has historically been the weak part of PKI (CRLs are large, OCSP has privacy and reliability issues), which is a major reason the industry moved to short-lived certificates: a 90-day cert limits the damage window even if revocation fails. Know the mechanisms, but lean on short lifetimes.
If a private key leaks, you must revoke BEFORE the cert expires:
CRL Certificate Revocation List — a (large) list of revoked serials
OCSP Online Cert Status Protocol — ask the CA "is serial X still valid?"
(OCSP stapling has the server attach a fresh signed status)
Both are imperfect (size, latency, privacy, soft-fail). So the modern
answer is: SHORT-LIVED certs. A 90-day (or hours-long) cert bounds the
damage window even if revocation doesn't propagate. Revocation is the
backstop; short lifetimes are the strategy.Ordinary TLS authenticates only the server to the client. Mutual TLS (mTLS) adds a client certificate so each side proves its identity to the other — the standard for service-to-service authentication in zero-trust and service-mesh architectures. Instead of trusting network location, each service presents a cert from an internal CA, and connections from unidentified peers are refused.
# generate a client cert from your internal CA (same flow as lesson 5)
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr -subj "/CN=payments-svc"
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -days 30 -out client.crt
# server requires + verifies a client cert (nginx):
# ssl_client_certificate /etc/nginx/ca.crt;
# ssl_verify_client on;
# now ONLY services holding a cert signed by our CA can connect.
# test the mTLS connection:
curl --cert client.crt --key client.key https://internal-api.local/
# in Kubernetes, a service mesh (Istio/Linkerd) automates mTLS + rotation
# between every pod — identity replaces network trust (zero trust).