6 min read Grounded in docs/dns-providers.md Wildcard Certificates with Domain Alias

Free wildcard certificates with Let's Encrypt

Wildcard certificates from Let's Encrypt are free and automated, but they have rules nobody warns you about. Here's the model Let's Encrypt actually uses, the cases the wildcard covers, the cases it doesn't, and the CertMate configuration that produces one.

A wildcard certificate is a single certificate whose SAN list includes *.example.com. Browsers and standard TLS clients accept it for any name that matches the wildcard. Let's Encrypt issues them at no cost. The catch isn't price — it's the set of rules around what the wildcard actually matches and how you have to prove control to get one.

What the wildcard covers (and what it doesn't)

This is RFC 6125 territory and it trips people up regularly. *.example.com matches a single label at the position of the asterisk. Concretely:

  • api.example.comcovered.
  • admin.example.comcovered.
  • example.com (the apex) — NOT covered. The wildcard is one label; the apex is zero labels.
  • v2.api.example.comNOT covered. Two labels under example.com, the wildcard only matches one.

In practice this means a typical SAN list is example.com, *.example.com — the apex plus the one-deep wildcard. If you also need v2.api.example.com, you need a second wildcard (*.api.example.com) or you add the FQDN as another SAN.

The DNS-01 requirement

Let's Encrypt has had wildcards since 2018 and from day one the policy has been: wildcards are issued only via the DNS-01 challenge. Practically every other CA that issues free wildcards (ZeroSSL, Google Public CA, Buypass) inherits the same constraint.

The reason is mechanical, not arbitrary. HTTP-01 proves control over a specific hostname by serving a file at /.well-known/...; for a wildcard you'd have to serve files at every conceivable subdomain, which doesn't generalize. DNS-01 proves control over the zone by writing a TXT record at _acme-challenge.example.com, and zone control IS the right scope for "any subdomain of example.com."

So: every wildcard renewal is a DNS-01 dance. If you want a wildcard you're committing to API access to your DNS. There is no path around this.

The CertMate request

Once the DNS provider is set up, asking CertMate for a wildcard is one POST. Concretely, with Cloudflare wired in already as the default account:

curl -X POST https://certmate.local/api/certificates/create \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "*.example.com",
    "dns_provider": "cloudflare"
  }'

CertMate runs certbot under the hood with --dns-cloudflare --domain '*.example.com', polls for propagation, retrieves the certificate, and stores it under /app/certificates/_.example.com/ (the leading asterisk gets normalized to an underscore on disk for path safety).

To include the apex on the same certificate, list both names:

curl -X POST https://certmate.local/api/certificates/create \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "example.com",
    "san_domains": ["*.example.com"],
    "dns_provider": "cloudflare"
  }'

The resulting certificate's SAN list is exactly example.com, *.example.com — apex + one-deep wildcard.

The renewal contract

Let's Encrypt certs are valid for 90 days. CertMate's auto-renew fires when a certificate is within 30 days of expiry by default; you can override the window per certificate. Each renewal repeats the DNS-01 dance, so the DNS API credentials need to keep working forever — which is the real cost of going wildcard. Rotate the credentials and CertMate's renewal silently breaks until you update the account.

The fix is operational: monitor the audit log for renewal failures (CertMate writes one audit row per attempt), or wire a deploy hook on the revoked event to page someone.

Security considerations

A wildcard certificate is a higher-value secret than a single-name one. If the private key leaks, the attacker can impersonate any subdomain — including ones you'll create in the future. Two implications:

  • Don't share the wildcard. If three services need TLS at three different subdomains, give them three SAN certificates rather than one wildcard that they all keep on disk. CertMate makes this trivial because issuance is cheap.
  • Reduce file permissions aggressively. CertMate stores cert + key with mode 600 owned by the certmate user, but deploy hooks that push the cert elsewhere need to preserve that discipline. The hook contract passes file paths via env vars (CERTMATE_KEY_PATH, etc.) — never embed the bytes inline in a shell command.

Cross-provider validation

What if your domain's DNS is hosted on a provider CertMate doesn't have a plugin for? You can still get the wildcard, by delegating just the _acme-challenge sub-zone to a provider it does speak. That's the CNAME delegation pattern — and it's also the safest way to scope DNS API credentials when you don't want CertMate's token to be able to edit your main zone.