Automatic HTTPS

Choose advanced certificate automation

Understand when DNS challenges, wildcard certificates, and on-demand TLS are justified and what new risks they add.

The default challenges cover most sites. Before you reach for the advanced options, make sure you need them. Each one hands Caddy more authority, and authority can be abused.

The DNS challenge

The DNS challenge proves you control a domain by creating a DNS TXT record, instead of answering a request on your server. Caddy needs two things for it: a DNS provider module compiled into the binary, and an API credential for your DNS host.

That module requirement is the main reason custom xcaddy builds exist. Here’s what the configuration looks like with Cloudflare:

*.example.com {
  tls {
    dns cloudflare {env.CLOUDFLARE_API_TOKEN}
  }
  respond "wildcard site"
}

Two situations justify it. Wildcard certificates, which ACME only issues through the DNS challenge. And servers that can’t accept traffic on ports 80 and 443, like a machine behind a strict corporate firewall.

The cost is that API token. Anyone holding it can change your DNS records, which is close to owning your domain. So scope the token to the one zone it needs. Keep it out of the Caddyfile, which is what the {env.…} placeholder does: it reads the value from the environment. And rotate it if you ever suspect a leak.

On-demand TLS

On-demand TLS goes further. Caddy obtains a certificate during the TLS handshake, the first time it sees a hostname. It exists for SaaS platforms that serve customer domains unknown at deploy time.

{
  on_demand_tls {
    ask http://127.0.0.1:5555/check
  }
}

https:// {
  tls {
    on_demand
  }
  respond "customer site"
}

The ask endpoint is the safety control. Before issuing, Caddy calls it with the hostname and proceeds only on a 200 response. Your app answers one question: is this a real customer?

Without that check, anyone who points a DNS name at your server can make you request certificates. They burn your CA rate limits and fill your disk with garbage names. Never enable on-demand issuance without ask.

Write the decision down

My advice is to answer a few questions before touching configuration:

need wildcard: no
ports 80/443 reachable: yes
hostnames known at deploy time: yes
choice: default automatic HTTPS

If your answers look like those, the default setup is right and you’re done. Most sites end here.

If one answer is different, add the smallest advanced feature that changes it. Need a wildcard? DNS challenge. Unknown hostnames? On-demand TLS with ask. Then test against the staging CA first, exactly like we did two lessons ago, so a mistake costs you nothing.

Lesson completed