How to Automate SSL/TLS Certificate Renewal with ACME
ACME lets a certificate authority verify domain control and reissue certificates over an API — so renewals happen on a schedule with no human in the loop. Here is the full setup, plus the step teams forget.
ACME (RFC 8555) is the protocol that lets a certificate authority verify you control a domain and then issue or renew a certificate over an API — no manual CSR, no portal, no human. Point an ACME client (certbot, cert-manager, Caddy, acme.sh) at your CA, prove control once via an HTTP-01 or DNS-01 challenge, and it renews on a schedule automatically. The step teams forget: verify the renewed certificate is actually deployed and serving, not just issued.
Why automate renewal at all
Manual renewal was survivable when certificates lasted a year. It isn't any more. The maximum lifetime of a publicly trusted TLS certificate is now 200 days, dropping to 100 in 2027 and 47 in 2029. CA/B Forum At 47 days, every certificate needs replacing roughly eight times a year — a cadence no calendar reminder survives. ACME is how you take the human out of the loop before that math catches up with you.
How ACME works, in four steps
An ACME client talks to a certificate authority's API. The exchange is always the same shape: request, prove control, get issued, deploy — then repeat on a timer. The hero diagram above shows the loop; the key idea is that proving control is automated, so renewal needs no human once it's set up.
Set it up
Pick a client and point it at your CA. The two most common:
certbot (single hosts, Let's Encrypt):
# issue + install for nginx, with auto-renewal wired into a systemd timer
sudo certbot --nginx -d example.com -d www.example.com
# certbot installs a renewal timer automatically; confirm it:
systemctl list-timers | grep certbot
sudo certbot renew --dry-runcert-manager (Kubernetes):
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-com
spec:
secretName: example-com-tls
duration: 2160h # 90d — renew well inside the 200-day cap
renewBefore: 720h # start renewing 30 days out
dnsNames:
- example.com
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuercert-manager watches the certificate and reissues before renewBefore — no cron, no human.
Choose the right challenge
The step teams forget: verify deployment
Issuance is not the finish line. A certificate that renews on schedule but never gets deployed to the endpoint serving traffic still expires and still causes an outage. Wire a post-renewal hook that reloads the service, then confirm the certificate actually being served is the new one:
echo | openssl s_client -connect example.com:443 2>/dev/null \
| openssl x509 -noout -serial -enddate
# the serial + notAfter here must match the certificate you just issuedRenewal automation checklist
- ACME client installed and pointed at a production CA (not staging) for real certs
- Challenge type chosen: DNS-01 for wildcards / internal hosts, HTTP-01 for simple public hosts
renewBefore/ renewal window set to at least 30 days before expiry- Post-renewal hook reloads the serving process (nginx, ingress, load balancer)
- Deployment verified — the served certificate's serial matches the issued one
- Independent expiry monitoring in place, separate from the renewal job
- DNS-provider API token / credentials rotated and scoped to the ACME zone only
Automate all of it and certificate renewal stops being something anyone has to remember — which is the only state that survives the 47-day era.
Frequently asked
What is ACME?
ACME (Automatic Certificate Management Environment, RFC 8555) is an IETF-standard protocol for automating certificate issuance and renewal. A client proves control of a domain to a certificate authority via a challenge, and the CA issues the certificate over the API — the same protocol Let's Encrypt popularised.
HTTP-01 vs DNS-01 — which challenge should I use?
HTTP-01 proves control by serving a token at http://your-domain/.well-known/acme-challenge/ and needs port 80 reachable. DNS-01 proves control by publishing a TXT record and works behind firewalls and for wildcard certificates, but requires API access to your DNS provider. Use DNS-01 for wildcards and internal hosts; HTTP-01 is simplest for public web servers.
Does ACME work behind a firewall or for internal services?
Yes, with DNS-01 — because validation happens through a DNS TXT record rather than an inbound HTTP request, the host itself never needs to be publicly reachable. HTTP-01 requires inbound port 80.
If renewal is automated, do I still need monitoring?
Yes. Automation reduces missed renewals but does not eliminate them — a broken hook, an expired API token, or a certificate issued-but-not-deployed still causes outages. Monitor expiry independently of the renewal job so a silent failure surfaces before it becomes downtime.
- RFC 8555 — Automatic Certificate Management Environment (ACME), IETF.
- CA/Browser Forum — Ballot SC-081v3: maximum public TLS certificate lifetime steps to 200 days (2026-03-15), 100 days (2027), 47 days (2029).