
What is a CAA record and how does it control SSL issuance?
A CAA (Certification Authority Authorization) record is a DNS record that lists which certificate authorities (CAs) are allowed to issue SSL/TLS certificates for your domain. Before issuing a certificate, every publicly trusted CA is required to look up the domain's CAA records. If records exist and the CA isn't named in them, it must refuse to issue. CAA gives you a simple, DNS-based way to stop the wrong CA, or an attacker using one, from getting a valid certificate for your site.
CAA has been mandatory for CAs to check since September 2017, yet many domains still don't publish it. In this article you'll learn how a CAA record is structured, how CAs look it up and walk up the DNS tree, how to restrict wildcard certificates separately, how to lock issuance to a specific ACME account and validation method, how to set up incident reporting, and how to roll CAA out without blocking your own certificate renewals.
What a CAA Record Looks Like
A CAA record has three parts: a flag, a tag, and a value.
example.com. 3600 IN CAA 0 issue "letsencrypt.org"
- 0: The flags byte.
0is normal.128marks the record as critical, explained below. - issue: The tag, which says what kind of permission this is.
- "letsencrypt.org": The value, here the CA's identifying domain.
The record above means "only Let's Encrypt may issue certificates for example.com". A domain can have several CAA records, and their permissions add up:
example.com. 3600 IN CAA 0 issue "letsencrypt.org"
example.com. 3600 IN CAA 0 issue "digicert.com"
Now both Let's Encrypt and DigiCert may issue, and no other CA may.
The Tags
The current specification, RFC 8659, defines three tags, and later RFCs add more:
| Tag | Meaning |
|---|---|
| issue | Which CAs may issue any certificate, including wildcards unless issuewild is set |
| issuewild | Which CAs may issue wildcard certificates. Overrides issue for wildcards |
| iodef | Where CAs should report requests that violate your policy (an email or URL) |
| issuemail | Which CAs may issue S/MIME email certificates (RFC 9495) |
The Critical Flag
Setting the flags value to 128 marks a record as critical. A CA that doesn't understand the tag in a critical record must refuse to issue. It's meant for future tags that must not be silently ignored. For issue, issuewild and iodef, every CA understands them, so use 0.
How Certificate Authorities Check CAA
When you request a certificate for www.shop.example.com, the CA performs a lookup that climbs the DNS tree until it finds a CAA record set:
- Look up CAA records for
www.shop.example.com. If any exist, use them and stop. - If none exist, look up
shop.example.com. - If none exist, look up
example.com. - If none exist, look up
com. TLDs don't publish CAA records, so the search ends. - If no CAA records were found anywhere, any CA may issue.
Two details matter here:
- The closest record set wins. If
shop.example.comhas its own CAA records, the ones atexample.comare ignored entirely for names undershop. This lets you set a different policy for a subdomain. - CNAMEs are followed. If
www.example.comis a CNAME toexample.cdn.example.net, the CA follows the alias and checks CAA at the target as well, as part of the normal DNS resolution. That's how CDNs and SaaS platforms can affect issuance for names that point at them.
The CA also has to be able to get an answer. If your nameservers time out or return SERVFAIL for the CAA query, the CA must treat that as a failure and refuse to issue. A DNS provider that mishandles the CAA type can therefore block certificates even if you never published one.
Identifying Your Certificate Authority
The value in an issue or issuewild record is a domain chosen by the CA. Always check your CA's documentation for the exact value. Common ones include:
| Certificate authority | CAA value |
|---|---|
| Let's Encrypt | letsencrypt.org |
| DigiCert (including its brands) | digicert.com |
| Sectigo | sectigo.com |
| GlobalSign | globalsign.com |
| Google Trust Services | pki.goog |
| Amazon (ACM) | amazon.com |
| SSL.com | ssl.com |
If you use a managed service that issues certificates for you, such as a CDN, a hosting platform or a load balancer, you must also allow the CA that the service uses. Some services use more than one CA and can switch between them, so allow every CA they list. Cloudflare, for example, adds the CAA records needed for its own certificates automatically when you publish CAA on a zone it serves, so its edge certificates keep renewing.
Building a Good CAA Policy
A Basic Policy
For a site that only uses Let's Encrypt:
example.com. 3600 IN CAA 0 issue "letsencrypt.org"
example.com. 3600 IN CAA 0 iodef "mailto:security@example.com"
Restricting Wildcards
issuewild lets you set a separate policy for wildcard certificates such as *.example.com. A common pattern is to allow normal certificates but forbid wildcards altogether:
example.com. 3600 IN CAA 0 issue "letsencrypt.org"
example.com. 3600 IN CAA 0 issuewild ";"
The value ";" names no CA, so no one may issue wildcards. Wildcard certificates are convenient but riskier, because a single stolen key covers every subdomain. If you don't use them, forbid them.
Forbidding All Issuance
For a domain that should never have certificates, such as a parked domain:
parked.example.net. 3600 IN CAA 0 issue ";"
A Different Policy for a Subdomain
Because the closest record set wins, you can give a subdomain its own rules. Here the main domain uses DigiCert, but a team's labs subdomain uses Let's Encrypt:
example.com. 3600 IN CAA 0 issue "digicert.com"
labs.example.com. 3600 IN CAA 0 issue "letsencrypt.org"
Names under labs.example.com only use the labs policy. DigiCert isn't automatically allowed there, so add it to the labs records too if you need it.
Locking Issuance to Your ACME Account
RFC 8657 adds two parameters to issue and issuewild values for CAs that use the ACME protocol:
- accounturi: Only a specific ACME account may get certificates.
- validationmethods: Only specific challenge types may be used, such as
dns-01orhttp-01.
example.com. 3600 IN CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/123456789"
example.com. 3600 IN CAA 0 issuewild "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/123456789; validationmethods=dns-01"
This is a strong control. Even if an attacker briefly takes over your web server or hijacks traffic to pass an HTTP challenge, Let's Encrypt won't issue to their account. You can find your account URI in your ACME client's account files. With Certbot, it's in the regr.json file under /etc/letsencrypt/accounts/.
Be careful with this one. If you lose the account, rebuild the server, or a teammate uses a different account, renewals will fail until you update the CAA record.
Incident Reporting With iodef
The iodef tag gives CAs a place to report certificate requests that violate your policy:
example.com. 3600 IN CAA 0 iodef "mailto:security@example.com"
example.com. 3600 IN CAA 0 iodef "https://reports.example.com/caa"
Support for sending these reports is optional for CAs, and many don't send them, so treat iodef as a nice-to-have rather than your only monitoring. Certificate Transparency monitoring is a far more reliable way to see every certificate issued for your domains.
Adding CAA Records
In a Zone File
BIND and other modern servers support the CAA type natively:
$ORIGIN example.com.
@ 3600 IN CAA 0 issue "letsencrypt.org"
@ 3600 IN CAA 0 issue "pki.goog"
@ 3600 IN CAA 0 issuewild ";"
@ 3600 IN CAA 0 iodef "mailto:security@example.com"
sudo named-checkzone example.com /etc/bind/zones/db.example.com
sudo rndc reload example.com
With Terraform on Route 53
resource "aws_route53_record" "caa" {
zone_id = aws_route53_zone.main.zone_id
name = "example.com"
type = "CAA"
ttl = 3600
records = [
"0 issue \"letsencrypt.org\"",
"0 issue \"amazon.com\"",
"0 issuewild \";\"",
"0 iodef \"mailto:security@example.com\"",
]
}
All CAA records for a name go into one record set, so list them together in a single resource.
In a Web Dashboard
Most DNS dashboards provide a CAA form with separate fields for flags, tag and value. Enter the value without quotes unless the form says otherwise. Older or simpler control panels may not support CAA at all. If yours doesn't, that's a good reason to consider a different DNS host.
Checking CAA Records
With dig
dig example.com CAA +noall +answer
example.com. 3600 IN CAA 0 issue "letsencrypt.org"
example.com. 3600 IN CAA 0 issuewild ";"
example.com. 3600 IN CAA 0 iodef "mailto:security@example.com"
Very old versions of dig that predate CAA show the type as TYPE257 with raw hex data. Updating your DNS tools fixes that.
Checking What a CA Would See
Because CAs climb the tree, a missing record on a subdomain isn't the whole story. This Bash script walks up from any name and reports which CAA record set applies:
#!/usr/bin/env bash
name="${1%.}"
while [ -n "$name" ]; do
records=$(dig "$name" CAA +short)
if [ -n "$records" ]; then
echo "CAA policy found at: $name"
echo "$records"
exit 0
fi
case "$name" in
*.*) name="${name#*.}" ;;
*) name="" ;;
esac
done
echo "No CAA records found: any CA may issue."
chmod +x caa-check.sh
./caa-check.sh www.shop.example.com
CAA policy found at: example.com
0 issue "letsencrypt.org"
0 issuewild ";"
0 iodef "mailto:security@example.com"
The script doesn't follow CNAMEs separately, but because dig resolves the CAA query through any CNAME at a name, it reflects the target's records when one is in place.
Rolling Out CAA Without Breaking Renewals
A CAA record that forgets one of your CAs will block that CA's next renewal, often weeks after you made the change. To avoid surprises:
- Inventory your certificates: Search Certificate Transparency logs, for example with crt.sh, for every certificate issued for your domain and subdomains in the past year. Note every issuing CA.
- Include managed services: CDNs, load balancers, email security gateways, website builders and SaaS tools with custom domains may all request certificates on your behalf.
- Publish CAA with every CA you found: Start permissive, then remove CAs you no longer need.
- Test a renewal: With Let's Encrypt,
sudo certbot renew --dry-runruns a test issuance against the staging environment, which also checks CAA. - Monitor: Keep an eye on certificate expiry and CT logs after the change.
If a CA refuses because of CAA, the error usually says so directly. Let's Encrypt, for instance, reports that a CAA record prevents issuance.
FAQ: CAA Records
No. If you don't publish one, any publicly trusted CA may issue certificates for your domain, subject to normal validation. Publishing CAA is a recommended hardening step rather than a requirement.
No. CAs check CAA only at the time of issuance. Existing certificates stay valid until they expire or are revoked, but renewals will be checked against the new policy.
No. CAs climb the DNS tree, so a CAA record on your main domain covers all of its subdomains unless a subdomain has its own CAA records.
It means no CA may issue wildcard certificates for that domain. The semicolon is a value that names no certificate authority, so nobody is authorised.
The CA used for renewal, or the CA used by a managed service on your behalf, isn't listed in your CAA records. Check which CA issued the previous certificate and add its CAA identifier.
It stops compliant CAs from issuing against your policy, which covers the vast majority of the risk. It doesn't help if your DNS account itself is compromised, because an attacker could then edit the CAA records too. Pair it with Certificate Transparency monitoring and DNSSEC.
No. CAA tells certificate authorities who may issue. DANE uses TLSA records in DNSSEC-signed zones to tell clients which certificate or key to trust when connecting, which is mainly used for email between mail servers.
Conclusion
A CAA record is a short, public statement of which certificate authorities you trust to issue certificates for your domain. CAs must check it before issuing, walking up the DNS tree to the closest record set, and refuse if they aren't listed. With issuewild, accounturi and validationmethods, you can tighten that policy much further than a simple allow list.
The main risk is blocking yourself, so take an inventory of every CA and managed service that issues for you before publishing, test a renewal, and keep monitoring Certificate Transparency logs. Done carefully, CAA is one of the cheapest and most effective ways to reduce the chance of a fraudulent certificate for your site.


