Skip to content

ACME in depth · 18.4

CAA records

This section is DNS background. TLSPilot does not create or check CAA records, but a CAA record that does not fit makes the CA refuse the certificate, and TLSPilot then shows the error of the CA. With CAA (Certification Authority Authorization, RFC 8659), the owner of a domain defines in DNS which CAs may issue certificates for it. Every public CA checks CAA before it issues. If no CAA record exists, any CA may issue.

A CAA record has the form CAA <flags> <tag> <value>. The flags are usually 0. The value 128 marks the record as critical: a CA that does not understand the tag must not issue. The CA looks for CAA records at the name in the certificate first, then at each parent domain, and uses the first records it finds. A record on example.com therefore also applies to www.example.com, unless the subdomain has CAA records of its own. The CA checks every name in the certificate, so a single restricted name blocks the whole certificate.

CAA tags and ACME parameters
Tag or parameterMeaning
Tags (RFC 8659)
issueAllows the named CA to issue certificates for the domain and its subdomains. It also applies to wildcard certificates as long as there is no issuewild record. issue ";" allows no CA.
issuewildOnly for wildcard certificates (*.example.com). If present, it replaces issue for wildcards.
iodefAddress for reports about requests that violate the CAA records, as mailto: or https: URL. Not every CA sends such reports; Google Trust Services, for example, does not act on iodef.
ACME parameters (RFC 8657), appended to the CA name with ;
accounturiOnly this ACME account may order certificates. At Let’s Encrypt, the account URL looks like https://acme-v02.api.letsencrypt.org/acme/acct/1234567890.
validationmethodsOnly these challenge types may be used, for example dns-01, http-01 or tls-alpn-01.

Example records

In this example, Let’s Encrypt (letsencrypt.org) and Google Trust Services (pki.goog) may issue for example.com and its subdomains. Wildcard certificates may only come from Let’s Encrypt with DNS-01, and reports go to the security team:

example.com.  CAA 0 issue     "letsencrypt.org"
example.com.  CAA 0 issue     "pki.goog"
example.com.  CAA 0 issuewild "letsencrypt.org;validationmethods=dns-01"
example.com.  CAA 0 iodef     "mailto:security@example.com"

To bind Let’s Encrypt to the ACME account of TLSPilot, add the account URL: example.com. CAA 0 issue "letsencrypt.org;accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/1234567890".

Typical errors

  • CNAME chain: CAA lookups follow CNAME records like any DNS query. If www.example.com is a CNAME to a name of a CDN or hosting provider, the CAA records at that target apply. If the target has none, the CA continues with the parent domains of your own name, for example example.com.
  • Wildcard: A certificate for *.example.com fails although issue allows the CA, because an issuewild record does not name it, for example issuewild ";".
  • ACME parameters: With accounturi, the record must name the current ACME account; after Reset Account, TLSPilot registers a new account. With validationmethods, the challenge type of the certificate must be listed.
  • DNS errors: If the CAA lookup fails, for example with SERVFAIL or a timeout, the CA cannot tell whether it may issue and usually refuses. Common causes are a broken DNSSEC signature or nameservers that do not answer queries for unknown record types correctly.

Check the records

dig +short CAA example.com
dig @8.8.8.8 CAA www.example.com

An empty answer means that there is no CAA record at exactly this name. Then check the parent domains as well.