TLS Certificate Lifecycle
debt(d7/e5/b5/t7)
Closest to 'only careful code review or runtime testing' (d7). The detection_hints list semgrep and testssl.sh as tools — these are specialist/manual tools rather than default linters. Many failure modes (missing intermediate chain, forgotten server reload after renewal, missing expiry alerting, world-readable private key) are not caught during development at all. The expired certificate issue is silent until it fires in production, often during off-hours. Semgrep can catch code patterns like missing deploy hooks, but monitoring gaps and misconfigured OCSP stapling require runtime tooling or manual inspection.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix suggests adding a certbot cron/systemd timer with a --deploy-hook and expiry alerting — this is more than a one-line patch. It involves configuring automation (cron/systemd unit files), web server reload hooks, and monitoring/alerting setup. Common mistakes span key storage, chain installation, SAN configuration, and server reload procedures — correcting all of them touches infrastructure config, web server config, and monitoring in multiple places.
Closest to 'persistent productivity tax' (b5). Applies to all web contexts (applies_to: web), meaning any HTTPS-serving system carries this burden. Certificate management must be revisited on renewal cycles, monitored continuously, and any infrastructure change (new domain, new server, new CA) triggers re-examination. It's not purely load-bearing across the codebase (b7) but it does impose an ongoing operational tax on every team running HTTPS services — especially with multiple domains, wildcard vs. SAN tradeoffs, and chain management.
Closest to 'serious trap (contradicts how a similar concept works elsewhere)' (t7). The misconception is canonical and multi-layered: developers assume a certificate 'just works until it expires,' but certificates can be revoked early (key compromise), intermediate chains can become untrusted, CT log monitoring reveals unexpected certs, and OCSP stapling affects browser latency. Additionally, the common mistake of renewing successfully but forgetting to reload the web server is a classic trap — the renewal 'worked' but the old cert keeps serving. These surprises are not obvious from first principles and contradict the mental model of 'install once, forget until expiry.'
Also Known As
TL;DR
Explanation
A TLS certificate proves a server's identity and enables encrypted connections. The lifecycle: (1) Generate a private key and Certificate Signing Request (CSR) containing the domain and public key. (2) Submit the CSR to a Certificate Authority (CA). (3) CA validates domain control via DNS-01, HTTP-01, or TLS-ALPN-01 challenge. (4) CA signs and issues the certificate (DV, OV, or EV). (5) Install certificate and private key on the server; configure intermediate chain. (6) Monitor expiry with alerting at 30/14/7 days before expiry. (7) Renew before expiry (Let's Encrypt: 90-day certs, renew at 60 days). (8) On compromise: revoke via CRL or OCSP. Let's Encrypt and ACME protocol automate steps 1–5 and 7 via Certbot or acme.php. Certificate Transparency logs (CT logs) record every issued certificate publicly — useful for detecting mis-issuance and shadow certificates for your domain.
Diagram
flowchart TD
A[Generate private key + CSR] --> B[Submit to CA]
B --> C[Domain validation - DNS or HTTP challenge]
C --> D[CA issues certificate]
D --> E[Install cert + chain on server]
E --> F[Reload web server]
F --> G[Monitor expiry - alert at 30d]
G --> H{Expiry approaching?}
H -->|Yes - autorenew| B
H -->|Compromised| I[Revoke via CA + OCSP]
I --> A
style A fill:#1f6feb,color:#fff
style I fill:#f85149,color:#fff
style G fill:#238636,color:#fff
Common Misconception
Why It Matters
Common Mistakes
- Not installing the intermediate certificate chain — browsers show 'certificate not trusted' even though the leaf cert is valid.
- Renewing the certificate but forgetting to reload the web server (nginx/Apache) — the old expired cert keeps serving until the process restarts.
- No expiry monitoring or alerting — the certificate expires silently during a holiday weekend.
- Storing the private key in a world-readable location or committing it to git.
- Using a single certificate for many domains without Subject Alternative Names (SANs) — a wildcard `*.example.com` doesn't cover `example.com` itself.
Code Examples
# Manual renewal — easy to forget, no alerting:
# 1. Remember to check expiry once a year
# 2. Manually run certbot renew
# 3. Remember to reload nginx
# 4. Hope you didn't forget
# Also bad — private key world-readable:
$ chmod 644 /etc/ssl/private/example.com.key
# Automated renewal with Certbot + cron + reload:
# /etc/cron.d/certbot
0 */12 * * * root certbot renew --quiet --deploy-hook 'systemctl reload nginx'
# Or systemd timer (preferred):
# certbot.timer runs certbot.service twice daily automatically on modern systems
# Private key permissions — readable only by root/nginx user:
$ chmod 600 /etc/letsencrypt/live/example.com/privkey.pem
# Monitor expiry — alert at 30 days:
$ echo | openssl s_client -connect example.com:443 2>/dev/null \
| openssl x509 -noout -dates
# Or use: https://github.com/drwetter/testssl.sh
# Check full chain is served:
$ openssl s_client -connect example.com:443 -showcerts 2>/dev/null | grep 'Certificate chain'