CAA records are a surprisingly blunt instrument for controlling certificate issuance, acting less like a precise whitelist and more like a broad "no" to unauthorized Certificate Authorities.

Let’s see this in action. Imagine you want to ensure only Let’s Encrypt can issue certificates for example.com. You’d add a CAA record to your DNS.

Here’s a typical DNS zone file snippet:

$TTL 3600
@       IN  CAA   0 issue "letsencrypt.org"

This record, 0 issue "letsencrypt.org", tells any Certificate Authority (CA) checking your DNS that only letsencrypt.org is authorized to issue certificates for this domain. The 0 is the priority (lower is more important, though for a single record it’s moot), issue is the type of action being authorized (issuance of certificates), and "letsencrypt.org" is the specific CA domain name.

When a CA like DigiCert or Sectigo tries to issue a certificate for example.com, they’ll query DNS for CAA records. If they find one that doesn’t explicitly authorize them, they must refuse the issuance. This is the core mechanism: it’s a denial-of-service for unauthorized CAs, not a permission slip for authorized ones.

The mental model here is that DNS becomes a public ledger of trust for certificate issuance. Every CA, by protocol, is obligated to check this ledger before issuing a certificate. This prevents rogue CAs or compromised CAs from issuing fraudulent certificates for your domain. You control the ledger by managing your DNS records.

The key levers you control are:

  • The issue tag: This is the primary authorization for issuing certificates.
  • The issuewild tag: This specifically authorizes the issuance of wildcard certificates (*.example.com). You’d use this if you have a separate policy for wildcards, e.g., 0s issuewild "letsencrypt.org". The s here means "self" and is often used with issuewild to indicate the CA can issue for itself.
  • The iodef tag: This specifies a URL (using mailto: or http(s):) where policy violations or issuance requests should be reported. This is crucial for monitoring. For example: 0 iodef "mailto:security@example.com".
  • The CA Domain Name: This must be the exact domain name of the CA as registered with the CA/Browser Forum. Using a subdomain like www.letsencrypt.org instead of letsencrypt.org would be invalid.

You can have multiple CAA records, and the CA will evaluate them based on the tag and the CA domain. For instance, you could allow both Let’s Encrypt and Google (for their Alphabet CA, pki.goog) to issue certificates:

@       IN  CAA   0 issue "letsencrypt.org"
@       IN  CAA   1 issue "pki.goog"

Here, Let’s Encrypt has priority 0, and Google has priority 1. If a CA is listed in any CAA record with an issue or issuewild tag that permits them, they are allowed to issue. The absence of a record means any CA can issue.

The most surprising part is how permissive the default is: if there are no CAA records for a domain, then any CA on the internet is authorized to issue certificates for it. This means implementing CAA isn’t about granting permission; it’s about revoking it from everyone except those you explicitly list. Many organizations overlook this and assume the absence of CAA records means "no one can issue," when in reality, it means "everyone can issue."

The next step in controlling certificate issuance is understanding how DNSSEC interacts with CAA records and the implications for validation.

Want structured learning?

Take the full Dns course →