About a hundred Certificate Authorities are trusted by default in every modern browser. Any one of them can issue a valid SSL certificate for any domain on the internet — including yours. The CA is supposed to verify that whoever's asking actually controls the domain before signing, but verification varies, mistakes happen, and a compromised or coerced CA can issue whatever it likes. That's the structural risk in the WebPKI: hundreds of trust roots, any of which can speak for your domain.
CAA records are how you talk back. A single DNS record — just a TXT-shaped entry in your domain's zone — that lists which CAs are allowed to issue for you. Every conformant CA on earth has been required since September 2017 to read your CAA record before issuing, and to refuse the request if they're not on the list. The record is free, it takes thirty seconds to add, and most domains still don't have one.
What CAA does
The CAA DNS record type was published as RFC 8659 (originally 6844, revised in 2019). It tells CAs which of them you've authorised to issue certificates for your domain. The mechanics are simple:
- You publish one or more
CAArecords at your apex domain. - Each record names one CA (by their official identifier domain) and what they're allowed to do.
- Before issuing a certificate, every publicly trusted CA must query your CAA records. If your domain has any CAA records at all, the CA's own identifier must be present — otherwise they're obliged to refuse.
- If you publish no CAA records, any CA is allowed to issue. That's the default, and it's a defaultly bad one.
The CAA check happens at certificate issuance time, not at validation. That's important. Browsers don't check CAA — only CAs do, when someone asks them for a new cert. A certificate already in the wild keeps working. CAA's job is to stop unauthorised future issuance, not to invalidate certificates the past has already produced.
The three tags
Every CAA record has three meaningful parts: a flag byte, a tag, and a value. There are three defined tags, and they cover almost everything you'd ever want to express:
issue— names a CA that's allowed to issue non-wildcard certificates. The value is the CA's identifier domain (e.g.,letsencrypt.org,pki.goog,digicert.com,sectigo.com).issuewild— same idea, but for wildcard certificates (the*.example.comkind). Ifissuewildis absent, wildcard issuance falls back to whateverissueallows. Ifissuewildis present, it completely overridesissuefor wildcards.iodef— names a contact for violation reports. The value is amailto:address or anhttps://URL. A well-behaved CA that receives a refused request will send a report there explaining what happened, which is useful evidence that someone tried to issue a cert they shouldn't have.
The flag byte is almost always 0. The high bit (value 128) marks a record as critical, meaning CAs that don't understand the tag are required to refuse. Almost no real-world record sets the critical flag — it's mostly there for future tag extensions.
Reading a real CAA record
Here's a typical published CAA set for a domain that uses Let's Encrypt and Google Trust Services, with reports going to a security mailbox:
example.com. CAA 0 issue "letsencrypt.org"
example.com. CAA 0 issue "pki.goog"
example.com. CAA 0 issuewild "letsencrypt.org"
example.com. CAA 0 iodef "mailto:security@example.com"
Reading those four lines:
- Let's Encrypt and Google Trust Services may both issue ordinary certificates for any name under
example.com. - Only Let's Encrypt may issue wildcard certificates. Google is implicitly blocked from issuing
*.example.combecause there's a non-emptyissuewildthat doesn't include them. - Any CA that receives an issuance request it has to refuse will email
security@example.coma report. - Every other CA in the world — DigiCert, Sectigo, Entrust, Microsoft, all the rest — is implicitly blocked from issuing for this domain. They're required to refuse.
The CAA lookup tool reads any domain's records and decodes them in this same shape: which CAs are authorised, whether wildcards are restricted, where reports go, and what the analysis says about the configuration overall.
How the hierarchy walk works
CAA is checked at the exact domain being requested, but if no records are present there, the CA walks up the DNS tree looking for an ancestor that does have CAA. The algorithm (RFC 8659 §3) is essentially:
- Query CAA at the target name. If records exist, use them. Done.
- If no records, query CAA at the parent. Repeat.
- Stop at the public suffix (one label before the TLD for typical domains — so the walk for
a.b.example.comproceedsa.b.example.com → b.example.com → example.comand stops there; it never queriescom).
The practical consequence is huge: one CAA record set at the apex covers every subdomain. You don't need to publish CAA for each host you care about. Add it once at example.com and every foo.bar.baz.example.com below inherits the policy.
If you do need a tighter or looser policy for a specific subdomain, publish CAA records at that subdomain and they'll take precedence — the walk stops at the first ancestor with records. Common pattern: tight policy at the apex (just your production CA), looser at dev.example.com if developers need to provision certs via a different provider.
Why every domain should have CAA
The case is essentially defence-in-depth. CAs are supposed to verify the requester before issuing. They usually do. Sometimes — through compromise, coercion, social engineering, or simple error — they don't. Certificate Transparency means you find out within hours when a CA issues a cert you didn't authorise; CAA means the issuance doesn't happen in the first place, because the CA itself refuses.
The two together form the standard certificate-security posture: CAA on the front (prevents unauthorised issuance) and CT in the back (detects it if it happens anyway). The cost of adding CAA is one DNS record. The cost of not adding it is that any of the hundred-or-so trusted CAs can decide, for any reason, to sign a cert for your name and you'd have no recourse short of revocation after the fact.
There's no operational downside as long as your CAA list includes every CA you actually use. The 30-second cost is one-time: add the record once, never think about it again until you change CAs.
CAA + CT — the two halves of cert security
It's worth being explicit about why both protocols exist:
- CAA is proactive. Published in your DNS, consumed by CAs at issuance time. Stops bad certs from being created in the first place. Failure mode: a non-compliant CA that ignores CAA (vanishingly rare, but theoretically possible).
- CT is reactive. Every issued cert ends up in a public log within hours. You read the log (or have our CT search read it for you) and find out about every cert ever signed for your name. Failure mode: by the time you see the entry, the cert exists; you have to scramble to get it revoked.
Belt and braces. CAA stops the issuance you can stop. CT catches the issuance that happens despite CAA, plus the long tail of "we forgot the CDN was set up to issue from a different CA last year." If you have one and not the other, you have half the protection.
Common configurations
A handful of patterns cover most real-world deployments:
- Single-CA setup (most common). One CA, no wildcards, no reporting:
example.com. CAA 0 issue "letsencrypt.org" - Multi-CA with explicit wildcard rules. Production uses Let's Encrypt for ordinary certs and Google for wildcards:
example.com. CAA 0 issue "letsencrypt.org"
example.com. CAA 0 issuewild "pki.goog" - Deny everyone (for a domain that should never have a cert):
example.com. CAA 0 issue ";"
Useful for parked domains, internal-only domains, or anywhere a cert appearing would itself be the signal of a problem. - With reporting on top:
example.com. CAA 0 issue "letsencrypt.org"
example.com. CAA 0 iodef "mailto:security@example.com"
Reports of refused issuance attempts land in the inbox — actively useful telemetry.
Mistakes that bite
The failures the CAA lookup tool flags most often:
- Forgetting the CDN's CA. Cloudflare provisions certs through Let's Encrypt or Google Trust Services depending on the plan; Fastly uses GlobalSign; AWS uses Amazon Trust Services. If you set CAA to your own preferred CA and forget the CDN's, your CDN cert renewals start failing the next time they're attempted.
- CAA on a subdomain but not the apex. The hierarchy walk works upward, but the apex still controls policy for itself. Publishing only at
www.example.commeans the apex (and any other subdomain) inherits nothing — anyone can still issue for them. - Not setting
issuewildwhen you don't want wildcards. With onlyissuepresent, wildcards fall back to whateverissueallows. If you don't want wildcards at all, publishissuewild ";"to deny them explicitly. - Multiple records that don't agree. CAA records are additive — multiple
issueentries are combined into a list. A common gotcha is publishingissue "letsencrypt.org"and forgetting to remove an olderissue "digicert.com"that nobody uses any more. Cleanup matters. - Adding CAA without testing it. If your CAA list is wrong, the next certificate renewal silently fails — and you don't notice until the existing cert expires. Test renewals in the days after adding CAA, or after any change.
Run a CAA check against your apex domain right now with the CAA lookup tool — it walks the hierarchy, lists every authorised CA, decodes the iodef and contact tags, and flags configurations that don't make sense. If your domain has no CAA, this is the post that fixes it. Add one record at your registrar's DNS panel, list the CAs you actually use, and you've added a meaningful security layer at zero ongoing cost.
Check your CAA records
Paste any domain to see its CAA policy — which CAs are authorised, whether wildcards are allowed, where violation reports go, and what the analysis flags as missing or inconsistent. Walks parent domains per RFC 8659.
Check your CAA records →