Why automatic HTTPS is a security decision, not a convenience feature
Three years ago, a fintech startup's staging server was exposed to the internet with a self-signed certificate. The dev team kept meaning to set up Let's Encrypt properly. Then a penetration tester found it during a routine audit â an unencrypted admin endpoint, publicly reachable. Nobody had "forgotten" security; they had deprioritized the friction of certificate management. That friction is exactly what Caddy was built to eliminate.
Setting
Caddy is an open-source web server written in Go, maintained by a small core team and a large contributor community, with the repository accumulating nearly 72,000 stars as of mid-2025. It was created by Matt Holt in 2015 with one design principle that sounds modest but has real security implications: TLS should be on by default, not opt-in. Most web servers â Nginx, Apache, HAProxy â treat HTTPS as a configuration task you perform after installation. Caddy inverts that. You configure HTTP explicitly if you want it; HTTPS is the default state.
The project sits at the intersection of the ACME protocol (Automatic Certificate Management Environment â the standard that Let's Encrypt uses to issue and renew certificates without human intervention) and modern HTTP standards (HTTP/1.1, HTTP/2, and HTTP/3 over QUIC). That combination matters for security teams because it removes an entire class of operational failure: expired certificates.
The Story
Here is what Caddy actually does in a concrete deployment. Say you are running a small SaaS product on a single VPS and you want to serve your API over HTTPS. With Nginx, the standard path involves installing certbot, running a challenge verification dance, editing your server block, setting up a cron job for renewals, and hoping the renewal does not fail silently. With Caddy, your entire configuration file â called a Caddyfile â looks like this:
api.yourdomain.com {
reverse_proxy localhost:3000
}
You start Caddy, it detects the domain, contacts Let's Encrypt (or ZeroSSL as a fallback), completes the ACME HTTP-01 or TLS-ALPN-01 challenge automatically, stores the certificate, serves HTTPS, and schedules renewal at roughly two-thirds of the certificate's lifetime â well before expiration. The process takes under thirty seconds on first run. If the renewal fails, Caddy retries with exponential backoff and logs the failure clearly, rather than silently serving an expired certificate.
Under the hood, the certificate storage is abstracted through a pluggable interface called CertMagic (Caddy's certificate management library). By default, certificates are stored on disk. In a distributed or containerized environment, you can swap the storage backend to Redis, Consul, or S3-compatible object storage â which means your certificate state is centralized, auditable, and not tied to a single instance's filesystem. For security engineers who care about secrets hygiene (treating certificates as secrets that should be versioned and access-controlled), this matters.
Caddy also enforces sane TLS defaults out of the box: TLS 1.2 minimum, strong cipher suites, OCSP stapling (a technique that lets the server prove its certificate has not been revoked, without the client having to contact the certificate authority directly), and automatic HTTP-to-HTTPS redirects. None of these require extra configuration. You can harden further â pin specific cipher suites, enforce TLS 1.3-only, configure mutual TLS (mTLS) for service-to-service authentication â but the baseline is already defensible without any of that.
For teams running internal services, Caddy supports acting as its own ACME certificate authority via its pki app. This lets you issue internal TLS certificates for services on private networks â api.internal, metrics.internal â without routing traffic through a public CA. The internal CA's root certificate can be distributed to clients once, and from that point forward, all internal services get valid TLS automatically.
The Insight
The real security argument for Caddy is not that it does something other servers cannot. Nginx with certbot and a well-maintained Ansible playbook can achieve the same endpoint state. The argument is about the attack surface created by operational complexity. Every manual step in certificate management is a place where human error, deferred maintenance, or miscommunication can introduce a vulnerability â expired certs, misconfigured redirects, forgotten HTTP endpoints. Caddy compresses that surface by making the secure path the path of least resistance. Security through good defaults is not glamorous, but it is what actually holds in production under time pressure.
This makes Caddy particularly relevant for small engineering teams (where there is no dedicated infra engineer watching certificate expiry), for startups deploying fast, and for any organization that wants compliance with standards like PCI-DSS or SOC 2 â both of which require encrypted data in transit â without building a certificate management runbook from scratch.
If you run more than a handful of public-facing services and certificate management is still a manual calendar reminder, Caddy is worth a weekend evaluation. It is not a security silver bullet, but it is a solid, well-maintained tool that removes one persistent, unglamorous source of TLS failures.
More security tooling worth your time is at teum.io/stories.
íęľě´ ěě˝
Caddyë GoëĄ ěěąë ě¤íěě¤ ěš ěë˛ëĄ, TLS ě¸ěŚě ë°ę¸ęłź ę°ąě ě ěëěźëĄ ě˛ëŚŹíŠëë¤. Nginxě˛ëź certbotęłź croně ëłëëĄ ě¤ě í íě ěě´, ëëŠě¸ë§ ě§ě í늴 Let's Encrypt ě°ëě´ ěŚě ěëŁëŠëë¤. ę¸°ëł¸ę° ěě˛´ę° TLS 1.2 ě´ě, OCSP ě¤í ě´íë§, HTTPâHTTPS ę°ě 댏ë¤ě´ë í¸ëĄ ě¤ě ëě´ ěě´ ëł´ě ě¤ě ě¤ě뼟 ě¤ě´ë ë° ě¤ě§ě ěźëĄ í¨ęłźě ě ëë¤. ě¸ěŚě ě ěĽ ë°ąěë뼟 Redisë S3ëĄ ęľě˛´í ě ěě´ ëśě° í경ěěë ě¸ěŚě ěí뼟 ě¤ě ę´ëŚŹí ě ěěľëë¤. ěęˇëި íě´ë ě¤íí¸ě ě˛ëź ě¸íëź ě ë´ ě¸ë Ľě´ ěë í경ěě íší ě íŠí ě íě§ě ëë¤.
Security through good defaults is not glamorous, but it is what actually holds in production under time pressure.