← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

TLS Certificate Lifecycle

Cryptography Intermediate
debt(d7/e5/b5/t7)
d7 Detectability Operational debt — how invisible misuse is to your safety net

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.

e5 Effort Remediation debt — work required to fix once spotted

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.

b5 Burden Structural debt — long-term weight of choosing wrong

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.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

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.'

About DEBT scoring →

Also Known As

TLS cert lifecycle SSL certificate lifecycle certificate management cert rotation ACME protocol

TL;DR

The end-to-end process of generating, validating, issuing, deploying, monitoring, and renewing a TLS certificate — and what breaks at each stage when it goes wrong.

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

Once installed, a certificate just works until it expires — certificates can be revoked by the CA before expiry (on key compromise), intermediate chains can become untrusted, CT log monitoring can reveal unexpected certificates for your domain, and OCSP stapling must be configured correctly to avoid browser latency on revocation checks.

Why It Matters

An expired certificate takes down HTTPS for all users instantly. A mis-issued or stolen certificate can be used to impersonate your domain. Automating renewal and monitoring expiry are non-negotiable for production systems — manual renewal inevitably fails.

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

💡 Note
The `--deploy-hook` ensures nginx reloads atomically after renewal — without it, the new cert sits on disk while the old one keeps serving.
✗ Vulnerable
# 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
✓ Fixed
# 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'

Added 24 Mar 2026
Views 61
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping W 2 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 2 pings F 0 pings S 2 pings S 0 pings M 0 pings T 0 pings W 1 ping T 1 ping F 0 pings S 0 pings S 0 pings M 1 ping T 0 pings W 0 pings T 2 pings F 0 pings S 0 pings S 0 pings M 1 ping T 0 pings W
No pings yet today
Sogou 1
Amazonbot 16 Google 7 Ahrefs 5 ChatGPT 4 Perplexity 4 Unknown AI 3 SEMrush 3 Scrapy 3 Bing 2 Claude 1 Meta AI 1 Sogou 1
crawler 47 crawler_json 3
DEV INTEL Tools & Severity
🔴 Critical ⚙ Fix effort: Low
⚡ Quick Fix
Automate renewal with `certbot renew` on a cron/systemd timer with a `--deploy-hook` to reload the web server; alert at 30 days before expiry
📦 Applies To
web
🔗 Prerequisites
🔍 Detection Hints
Manual certificate renewal process; missing cron/systemd timer for certbot; private key with 644 permissions
Auto-detectable: ✓ Yes semgrep testssl.sh
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Low ✗ Manual fix Fix: Medium Context: File
CWE-295 CWE-326


✓ schema.org compliant