# Runbook: Public TLS Certificate Renewal If using Caddy's built-in Let's Encrypt (the default in `infra/docker/platform/Caddyfile.j2`): **nothing to do** — Caddy renews automatically well before expiry, as long as port 80 stays reachable for the ACME HTTP-01 challenge (`infra/firewall/rn-platform-01.rules` already allows it). `infra/scripts/production-smoke-test.sh` checks the live expiry date on every run as an early warning if auto-renewal ever silently breaks. If using Cloudflare origin certs instead (see `docs/PRODUCTION_NETWORK_SECURITY.md` §8 for that decision): Cloudflare-issued origin certs are typically 15-year validity — this is a once-per-network-topology-change concern, not a recurring one. Re-issue from the Cloudflare dashboard (SSL/TLS -> Origin Server) and redeploy the cert/key via the `platform` Ansible role if it ever needs replacing (domain change, suspected compromise). **Manual check:** ```bash echo | openssl s_client -connect academy.example.com:443 -servername academy.example.com 2>/dev/null \ | openssl x509 -noout -enddate ```