certmagic
Automatic HTTPS for Go programs — the production-grade ACME client library that powers Caddy, obtaining and renewing TLS certificates with zero manual cert management.
Repository Health
Technical Analysis
CertMagic is the automatic-HTTPS library that powers the Caddy web server, giving any Go program the same battle-tested TLS certificate management Caddy uses in production. Add a single call — certmagic.HTTPS(domainNames, mux) — and CertMagic obtains, renews, and serves certificates from Let’s Encrypt or any RFC 8555-compliant ACME CA, handling HTTP, TLS-ALPN, and DNS challenges, OCSP stapling, and automatic replacement of revoked certificates.
Beyond the one-line convenience API, CertMagic exposes a full Config/Cache/Storage architecture for advanced use: pluggable storage backends for clustered deployments, on-demand issuance during the TLS handshake itself, event hooks for observability, and support for multiple issuers (including ZeroSSL) tried in sequence. It’s built to survive real production conditions — retrying failed validations with exponential backoff for up to 30 days and coordinating locks across a fleet of instances sharing the same storage.
What You Get
- One-line HTTPS() convenience API that stands up managed HTTP->HTTPS servers with zero manual certificate handling
- Full ACME challenge support (HTTP-01, TLS-ALPN-01, DNS-01) with all libdns DNS providers working out of the box
- Automatic OCSP stapling with disk-backed staple caching and automatic replacement of revoked certificates
- Pluggable Storage and Cache interfaces for running a coordinated fleet of instances behind a load balancer
- On-demand TLS issuance during the TLS handshake itself, gated by a custom decision function
- Multi-issuer support (Let’s Encrypt, ZeroSSL, or any RFC 8555 ACME CA) tried in sequence for redundancy
Common Use Cases
- Zero-config HTTPS for internal tools - drop certmagic.HTTPS() into a small Go service to get production-grade TLS without a separate cert manager or reverse proxy
- Building a reverse proxy or edge server - use the lower-level Config/Cache API to manage certificates for many domains dynamically, the pattern Caddy itself uses
- Multi-tenant SaaS with customer-owned domains - combine on-demand TLS with a decision function to issue certificates only for verified customer domains as traffic arrives
- Clustered or load-balanced deployments - share a Storage backend across instances so issuance, renewal, and locking stay coordinated across the fleet
- DNS-01 challenge workflows - use a libdns provider to obtain wildcard certificates or certificates for hosts with no public HTTP endpoint
Under The Hood
Architecture
CertMagic is layered around three cooperating abstractions: Config (certmagic.go, config.go), Cache (cache.go), and Storage (storage.go). The high-level HTTPS(), Listen(), and TLS() functions in certmagic.go build on certmagic.Default/certmagic.NewDefault() and are thin conveniences over Config.ManageSync/ManageAsync. A Config holds Issuers (an Issuer interface implemented by ACMEIssuer and ZeroSSLIssuer) and delegates actual certificate acquisition to acmeissuer.go/account.go, which wrap the mholt/acmez ACME client and manage per-CA account state. Issued certificates flow into Cache, an in-memory, mutex-guarded de-duplicating store (cache.go) that backs TLS handshake-time certificate selection and is periodically reconciled against Storage by maintain.go’s maintainAssets/RenewManagedCertificates background loop. Storage is a narrow interface (Load/Store/Delete/List/Stat plus a Locker) implemented by the default FileStorage (filestorage.go) but swappable for any KV/database backend, and it is the seam that lets multiple CertMagic instances share certificate state and coordinate renewal locks across a cluster. This clean separation — network/ACME logic in the issuer layer, in-memory serving state in Cache, and durable/coordinated state in Storage — is what lets the same library serve both the trivial one-line use case and Caddy’s multi-tenant, clustered production deployment.
Tech Stack
Written in Go (module github.com/caddyserver/certmagic, requiring Go 1.25+ per go.mod though the README states 1.21+). Core dependencies: mholt/acmez/v3 for the ACME protocol client, libdns/libdns for a common DNS-provider interface used in DNS-01 challenges, miekg/dns for low-level DNS operations, golang.org/x/crypto and golang.org/x/net for OCSP/idna handling, go.uber.org/zap for structured logging throughout, and zeebo/blake3/klauspost/cpuid for hashing. caddyserver/zerossl provides the ZeroSSL API issuer as an alternative to plain ACME. No external database or ORM — persistence is entirely behind the pluggable Storage interface, with a filesystem implementation shipped by default. CI runs go test -race across Go 1.25/1.26 on Ubuntu, macOS, and Windows via GitHub Actions.
Code Quality
The repository pairs 16 _test.go files with their corresponding source files (account_test.go, config_test.go, cache_test.go, certificates_test.go, handshake_test.go, solvers_test.go, storage_test.go, etc.), giving close to 1:1 test coverage of major components, and CI runs the suite with the race detector enabled across three operating systems. Error handling is consistently explicit — errors are wrapped with fmt.Errorf/%w and returned rather than panicking or being swallowed (179 explicit errors.New/fmt.Errorf call sites across the codebase). Comment density is unusually high, with roughly a third of lines in core files being documentation comments explaining rationale (not just what, but why), and every exported type/function carries a doc comment suitable for pkg.go.dev. Naming is consistent and Go-idiomatic (KeyBuilder, ConfigGetter, SubjectIssuer), and internal packages (internal/atomicfile, internal/filedescriptor, internal/testutil) are used to keep low-level concerns out of the public API surface.
What Makes It Unique CertMagic’s differentiator is that it isn’t a toy ACME client — it’s the literal library Caddy uses in production to serve automatic HTTPS for large, multi-tenant, load-balanced deployments, extracted for reuse. Distinguishing technical choices include on-demand issuance during the TLS handshake itself (obtaining a cert lazily the first time a hostname is seen, rather than requiring pre-registration), coordinated distributed locking so a fleet of instances sharing Storage doesn’t race to issue duplicate certificates for the same name, challenge randomization/rotation specifically designed to route around network blockages of individual challenge types, and first-class support for RFC 9773 ACME Renewal Information (ARI) so renewal timing can be dictated by the CA rather than a fixed local window. Multi-issuer fallback (trying Let’s Encrypt, then ZeroSSL, or any other configured ACME-compliant CA) is also uncommon among Go ACME libraries, most of which hard-code a single CA.
Used by 6 apps in this directory
Caddy
Devops · Security
The only web server that obtains and renews TLS certificates automatically, with HTTP/1-2-3 support and zero dependency on external runtimes.
Gitea
Devops · Developer Tools · Project Management
Self-hosted DevOps in a single Go binary — Git hosting, GitHub Actions-compatible CI/CD, and 30+ package registries without any SaaS dependency.
NetBird
Security
Replace your VPN with a zero-trust WireGuard overlay network that auto-connects devices, enforces SSO and posture checks, and deploys in under 5 minutes.
Space Cloud
Devops · Authentication
Kubernetes-native serverless platform that generates instant GraphQL and REST APIs for any database with built-in auth and real-time subscriptions
Statusnook
Monitoring
Deploy a self-hosted status page with endpoint monitoring and automatic HTTPS in minutes, with no external dependencies required.
Stormkit
Devops · Hosting Control Panel
Self-hostable platform for deploying and hosting modern web apps with automated CI/CD, custom domains, and a built-in serverless runtime — a true open-source alternative to Vercel and Netlify.