Skip to content
← All articles
PKI10 min read

CAA Records: Telling Certificate Authorities Who May Issue for Your Domain

How DNS Certification Authority Authorization records work under RFC 8659, what the issue, issuewild, and iodef tags mean, and how to publish and verify them without locking out your own renewals.

By CertIntel
  • PKI
  • TLS
  • DNS
  • CAA
  • Certificate Authorities
  • ACME

Any publicly trusted certificate authority can, in principle, issue a certificate for any domain name. The CA's job is to check that the applicant controls the name before doing so. That check is where things go wrong: a misconfigured validation method, a compromised CA, a hijacked web server, or a social-engineered support ticket can all produce a certificate you never asked for.

Certification Authority Authorization, or CAA, gives domain owners a way to narrow that exposure. A CAA record is a DNS record that says which CAs are allowed to issue for a name. Publicly trusted CAs are required to check it before issuing. This article explains the record format defined in RFC 8659, how CAs look it up, what it does and does not protect against, and how to publish records without breaking your own renewals.

What a CAA record is

CAA is a DNS resource record type, number 257, with three fields:

Field Meaning
Flags An 8-bit field. Only bit 0, the issuer critical flag with value 128, is currently defined.
Tag The property name, such as issue, issuewild, or iodef.
Value The property value, written as a quoted string in zone-file format.

A minimal zone-file entry looks like this:

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

Read it as: "For example.com, the CA identified by letsencrypt.org may issue certificates." A CA whose identifying domain is not listed must refuse.

A real zone usually carries more than one record. The example below allows a commercial CA for the production apex, a different CA for a development subdomain, and names a reporting address. The later sections explain why the subdomain record replaces the apex policy rather than adding to it.

example.com.      IN  CAA  0 issue "digicert.com"
dev.example.com.  IN  CAA  0 issue "letsencrypt.org"
example.com.      IN  CAA  0 iodef "mailto:security@example.com"

The three defined tags

RFC 8659 defines three property tags. Tags are matched case-insensitively.

issue

issue authorizes one CA to issue certificates for the name. The value is the domain name the CA publishes as its CAA identifier, optionally followed by semicolon-separated parameters.

example.com.    IN  CAA  0 issue "ca.example.net"
example.com.    IN  CAA  0 issue "ca.example.net; account=230123"

Parameters are defined by the CA, not the RFC, and a CA that does not understand a parameter should treat it according to its own policy. RFC 8657 standardizes two for ACME CAs, validationmethods and accounturi, so that you can restrict issuance to a specific ACME account or validation method. Check your CA's documentation before relying on either.

An issue record whose value is only a semicolon authorizes nobody:

example.com.    IN  CAA  0 issue ";"

This is the record to publish for a name that should never receive a certificate, such as a domain used only for email.

issuewild

issuewild controls wildcard certificates, meaning certificates whose first label is *. If any issuewild record exists in the relevant record set, it alone governs wildcard issuance and issue records are ignored for that purpose. If no issuewild record exists, issue records govern wildcards too.

example.com.    IN  CAA  0 issue     "letsencrypt.org"
example.com.    IN  CAA  0 issuewild ";"

Those two records allow ordinary certificates from one CA and forbid wildcards from everyone. A common mistake is adding issuewild for a single CA and expecting it to be additive. It is not. It replaces the issue set for wildcard requests.

iodef

iodef names a reporting channel. If a CA receives a request it must refuse because of CAA, it may send a report there. The value is a mailto:, http:, or https: URL. The RFC says the report uses the Incident Object Description Exchange Format, and support is optional on the CA side.

example.com.    IN  CAA  0 iodef "mailto:security@example.com"

Treat iodef as a bonus rather than a control. Many CAs do not send reports at all. Certificate Transparency logs remain the more reliable way to find out what was actually issued for your names.

How a CA finds the relevant record set

The lookup algorithm matters because it decides which records apply to a given name. For a certificate request naming www.example.com, the CA checks, in order:

The CAA lookup order for www.example.com under RFC 8659
  1. www.example.com
  2. example.com
  3. com (the search stops at the first name with CAA records)

The CA queries the exact name first. If that name has a CAA record set, that set is the answer and the search stops. If it has none, the CA removes the leftmost label and tries again, continuing until it reaches the DNS root. The first non-empty set wins, which means a record at the apex applies to every subdomain that does not publish its own.

Two consequences follow:

  • A subdomain record overrides the parent, it does not add to it. If dev.example.com lists only letsencrypt.org, DigiCert cannot issue for dev.example.com, even though the apex allows it.
  • A name with no CAA records anywhere in its chain allows every CA. CAA is opt-in. Absence of records is permission, not denial.

RFC 8659 obsoleted the original specification, RFC 6844, and one of its substantive changes is here. The original algorithm also followed CNAME and DNAME aliases during the climb, which caused confusing results. The new algorithm resolves the name normally, which means a CNAME at the queried name is followed as any DNS client would, but the climb itself walks the plain parent labels. If a CA says a CAA lookup failed, this is a useful place to begin.

The issuer critical flag

The flags field with value 128 marks a record as critical. A CA that does not understand a critical record's tag must refuse to issue. For the three standard tags, every conforming CA understands them, so the flag mostly matters if a future specification adds a tag you want enforced strictly. A record with flags 0 and an unknown tag is simply ignored.

Most published records use flags 0. Using 128 on an issue record is harmless and makes your intent unambiguous, but it provides no additional restriction over flags 0 today.

Why this matters

Several things push CAA from a nice-to-have toward a baseline control.

CAs are required to check it. The CA/Browser Forum Baseline Requirements have mandated CAA checking by publicly trusted CAs since September 2017. A CA that issues in violation of a published CAA record has committed a misissuance and is expected to revoke and report it. Your record is enforced by policy across the whole public ecosystem, not just by a vendor you contracted with.

It limits blast radius. If a validation flaw or operational mistake lets someone obtain a certificate from a CA you never use, a CAA record listing only your real CAs blocks it. The same applies to a well-meaning colleague clicking through a web host's one-click SSL button with a CA you did not intend to use.

It documents intent. A CAA record is a machine-readable, publicly visible statement of which CAs should appear in your certificate inventory. Anything in CT logs or on your endpoints from a different CA is immediately suspicious.

It is cheap. CAA adds a DNS record. It requires no software, no agent, and no change to the certificate itself.

What it does not do

CAA is a control on issuance, not on trust. Be clear about its limits before relying on it.

  • Browsers and clients ignore it. A certificate issued in violation of CAA validates like any other. CAA stops the CA from issuing; it does not stop a client from trusting a certificate that was issued anyway.
  • It is only as strong as your DNS. CAs query DNS over the public internet. An attacker who controls your zone or can spoof answers to the CA's resolver can rewrite the CAA record. DNSSEC closes that gap. RFC 8659 states that CAs should use DNSSEC validation where available, and that a signed zone with a bogus response must be treated as a lookup failure rather than as permission.
  • It only applies to publicly trusted CAs. Your internal enterprise CA is not bound by the Baseline Requirements and will issue whatever your policy says.
  • It is checked at issuance time. A CA checks CAA when it validates a request, and the Baseline Requirements let it reuse that result for a limited window. Changing the record afterwards does not revoke anything already issued.
  • It does not prove your certificates came from the listed CA. That still requires inspecting what endpoints actually serve.

Publishing CAA without breaking renewals

The most common CAA-related outage is self-inflicted. Someone publishes a strict record, and the next renewal fails because the CA that actually issues the certificate is not on the list, or because a managed service renews on the organization's behalf through a CA nobody remembered.

Before adding records, build an inventory of who issues for your names today. Sources worth checking:

  • The issuer field on every certificate currently installed on your endpoints.
  • Certificate Transparency logs, which show every publicly trusted certificate issued for your names, including ones a cloud provider or CDN obtained for you.
  • Vendor documentation for any managed service terminating TLS for your domain. Cloud load balancers, CDNs, and email providers often obtain their own certificates and publish the CAA identifier you need to allow.

Then use the CA's documented CAA identifier, not a guess. Identifiers are not always the CA's marketing name. Let's Encrypt uses letsencrypt.org. Larger CAs often publish several, one per brand or intermediate they operate. A CA's CAA identifier page or its Certification Practice Statement is the authoritative source.

A reasonable rollout:

  1. Publish issue records for every CA found in the inventory, with flags 0.
  2. Add an iodef record so that CAs which support reporting can tell you about refusals.
  3. Trigger a test issuance or renewal with each CA, and watch for CAA errors in the ACME client or CA portal logs.
  4. Only then consider issuewild ";" if you do not use wildcards, or per-subdomain restrictions.

If you use ACME, the client reports CAA failures explicitly. Let's Encrypt, for example, returns an error naming the CAA record that blocked the request. Those errors are much easier to read than a silent renewal gap, which is one reason to test deliberately rather than waiting for the next scheduled renewal.

Verifying what is published

Query the record directly with dig:

$ dig example.com CAA +short
0 issue "letsencrypt.org"
0 iodef "mailto:security@example.com"

Query a subdomain too, since the answer may be empty there even though a parent has records. The CA will climb to the parent; dig will not. Query the authoritative nameservers rather than a caching resolver when you have just made a change, so that stale answers do not mislead you.

If you would rather not reach for dig, the CAA record checker performs the same lookup from your browser over DNS-over-HTTPS, walks up the parent names the way a CA does, and translates the result into a plain-English list of which CAs may issue. The same tool has a generator that builds a correct record set from a list of CAs, which is an easy way to avoid the quoting and tag mistakes that hand-written records attract.

If your DNS provider's interface does not offer a CAA record type, check whether it accepts generic TYPE257 records. Providers that cannot serve CAA at all are rare now, but if you encounter one, the fallback is to move the zone or at least delegate the relevant name to a provider that can.

What this means for monitoring

CAA makes the question "which CA should have issued this?" answerable. That is useful on its own. It becomes more useful when you compare the published policy against what is actually observed.

A monitoring process that pairs well with CAA checks three things separately:

  1. Published policy: the CAA records on the apex and any subdomains that override it.
  2. Issued certificates: what Certificate Transparency logs show for the names, including the issuing CA of each entry.
  3. Served certificates: what each endpoint presents during a TLS handshake, and the issuer of that certificate.

A certificate in CT from a CA not listed in CAA is either a misissuance, a CA identifier you forgot to allow, or evidence that the record was changed or spoofed. All three deserve attention. CertIntel's Certificate Transparency discovery and endpoint observations provide the second and third inputs; the CAA checker shows the first input for any domain, and the other certificate tools can decode an issuer from any certificate you have on hand. The CAA record itself remains yours to publish and keep accurate.

Further reading

  • RFC 8659: the current CAA specification, including the lookup algorithm, record syntax, and security considerations.
  • RFC 8657: the validationmethods and accounturi parameters for ACME CAs.
  • RFC 6844: the original, now obsoleted, specification, useful when reading older CA documentation.
  • CA/Browser Forum Baseline Requirements: the policy that requires publicly trusted CAs to check CAA.
  • Let's Encrypt CAA documentation: an example of a CA publishing its identifier and its handling of CAA errors.