Dr.Who
← blog

CAA records: what they do and whether you need one

· caa · dns · certificates · tls · security

caadnscertificatestlssecurity

A CAA (Certification Authority Authorization) record is a DNS record that lists which certificate authorities are permitted to issue TLS certificates for your domain. Defined in RFC 8659, it exists to shrink the blast radius of mis-issuance: any CA, anywhere, is technically capable of issuing a cert for yourdomain.com, and a CAA record tells all of them except the ones you name to refuse. It is not mandatory, but it is cheap defense-in-depth and worth publishing.

The record format

A CAA record has three parts: a flag, a tag, and a value. The most common form authorizes one CA via the issue tag:

example.com.  CAA  0 issue "letsencrypt.org"

The 0 is the flag (the critical bit; leave it 0 unless you know you need 128). The tag says what the value means, and the value is the CA's identifier domain. The three tags you will use:

  • issue — this CA may issue certificates for the domain.
  • issuewild — this CA may issue wildcard certificates (*.example.com). If absent, issue covers wildcards too; if present, it overrides them.
  • iodef — where to send violation reports, as a mailto: or URL.

A fuller policy looks like this:

example.com.  CAA  0 issue "letsencrypt.org"
example.com.  CAA  0 issue "amazon.com"
example.com.  CAA  0 issuewild "letsencrypt.org"
example.com.  CAA  0 iodef "mailto:[email protected]"

That authorizes Let's Encrypt and Amazon to issue, restricts wildcards to Let's Encrypt, and asks any CA that hits a policy violation to email you.

CAs are required to check it

This is the part that gives CAA teeth. Since 2017, the CA/Browser Forum baseline requirements oblige every publicly trusted CA to look up CAA before issuing. If a record exists and does not name them, a compliant CA must refuse. So unlike a lot of DNS hygiene that only matters if someone bothers to read it, CAA is actively enforced at issuance time by the people doing the issuing.

It is not a runtime control. Browsers do not check CAA when they make a TLS connection — by then the cert already exists. CAA only blocks the creation of new certificates.

How to read your current record

Check what you have published with dig:

dig +short CAA example.com

Empty output means no policy — any CA may issue. Resolvers also walk up the tree: if app.example.com has no CAA, the CA checks example.com, then the parent. So a record at the apex covers subdomains unless a subdomain publishes its own.

The gotcha that locks you out

Because CAA is allow-list and enforced at issuance, the failure mode is locking out a CA you actually depend on. Your CDN, your load balancer, your managed certs, your mail host's ACME client — each may use a different CA. If you publish 0 issue "letsencrypt.org" and your CDN provisions through DigiCert or Google Trust Services, that renewal silently fails the next time it runs.

Before you publish, enumerate every CA in your stack and list all of them. Pair CAA with CT-log monitoring: CAA stops the CAs you named from being bypassed, and CT logs catch anything that slips through anyway.

Look up your domain's CAA record →

Further reading