CAA Records on 60 Developer Sites: 2026 Data
We checked CAA on 60 developer-infrastructure domains on October 10, 2026: 34 publish it, one binds every allowed CA to an ACME account, and one mismatches.
Ben Ennis
Published October 10, 2026
A CAA record is a short DNS list of the certificate authorities allowed to issue for a domain. Since the CA/Browser Forum made CAA checking mandatory in September 2017, every public CA has to look it up before issuing. It is cheap to publish and easy to forget, and the .gh, .sl and .as registry hijacks reported this week showed its limit. An attacker who controls a domain’s DNS passes domain validation honestly, so an allowlist alone does not stop them. The CAA extensions that would stop them bind issuance to an ACME account or a validation method.
Last week’s recap sampled 15 hosts. This piece widens that to 60 domains that developers depend on daily: code hosts, package registries, language sites, cloud and edge platforms, CNCF projects, observability vendors, and the CAs themselves. For each one we compare what the CAA record allows with the CA actually serving the site and with what Certificate Transparency logs show the domain used over the past year. The full dataset is published as JSON.
Method and dataset date
All data was collected on October 10, 2026 between 11:00 and 11:40 UTC.
- CAA records. We queried each registrable domain through two independent DNS-over-HTTPS resolvers, the Google Public DNS JSON API and Cloudflare’s DNS JSON endpoint. Both returned the same record set for all 60 domains. Under RFC 8659, a CA climbs from the name toward the root until it finds CAA. We also checked the parent TLDs (
.com,.org,.io,.dev,.sh,.tech,.co), and none publish CAA, so the apex record is the relevant set for every domain here. - Serving certificate. A TLS handshake to port 443 with SNI set to the apex, reading the leaf certificate’s issuer and validity dates.
- Issuer history. An exact-name lookup in CertIndex, our Certificate Transparency index, keeping certificates with a
notBeforeon or after October 10, 2025. Treat this as a lower bound. CT coverage for a single name is not always exhaustive, and five domains had no indexed history yet. For those five, only the serving certificate counts as “used.”
Anyone can reproduce the first two steps with standard tools:
# CAA as a CA would see it (repeat for the parent if empty)
dig +short CAA example.com
# Same question over DNS-over-HTTPS
curl -s 'https://dns.google/resolve?name=example.com&type=CAA'
# Issuer of the certificate the site actually serves
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -issuer -dates
You can look up the third in the CT lookup tool or with any CT search engine.
Headline numbers
| Measure | Result |
|---|---|
| Domains checked | 60 |
| Publish any CAA record | 34 (57%) |
CAA actually restricts issuance (issue or issuewild present) |
33 |
Publish iodef (violation reporting) |
20 of 34 |
Publish issuewild |
18 of 34 (2 forbid wildcards entirely) |
| Use the critical flag (128) | 2 |
| Bind any CA to an account | 4 |
| Bind every allowed CA to an account | 1 |
| Restrict validation methods | 1 |
| Serving CA not allowed by current CAA | 1 |
The serving-certificate mix across all 60 domains was Let’s Encrypt 29, Google Trust Services 12, DigiCert 8, GlobalSign 4, Sectigo 3, Amazon 3, and Microsoft 1. Among the 33 domains whose CAA restricts issuance, letsencrypt.org appears in 31 allowlists, digicert.com in 22, pki.goog in 18, at least one Amazon identifier in 18, and at least one Sectigo identifier (sectigo.com, comodoca.com or comodo.com) in 17.
Who publishes nothing
Twenty-six domains publish no CAA record: argoproj.io, bun.sh, cert-manager.io, cncf.io, crates.io, datadoghq.com, deno.com, elastic.co, envoyproxy.io, fly.io, grafana.com, hashicorp.com, helm.sh, heroku.com, hetzner.com, istio.io, jetbrains.com, kernel.org, mongodb.com, nginx.org, nodejs.org, python.org, railway.com, rust-lang.org, supabase.com and terraform.io.
The CNCF cluster stands out. Of the eight CNCF-related domains in the sample, only kubernetes.io and prometheus.io publish CAA. A ninth case is nuget.org, which publishes a single contactemail property and no issue tag. RFC 8659 treats a CAA set with no issue property as placing no restriction on issuance, so nuget.org is effectively open as well.
No CAA is not a vulnerability on its own. It means any publicly trusted CA may issue, and the domain is relying on CT monitoring to catch a bad certificate after the fact.
Allowlists are wider than usage
For each of the 33 restricting domains, we grouped CA identifiers by organization (all four Amazon identifiers count as one, for example). We then compared that with the organizations seen in the serving certificate and the past year of CT history.
- The median domain allows 4 CA organizations and was seen using 1.
- 19 of 33 domains used exactly one CA all year.
- 15 of 33 allow three or more CAs they were not seen using.
- letsencrypt.org itself allows six CA organizations and used only its own.
A spare CA is not automatically a mistake. Let’s Encrypt’s CAA documentation notes that records are additive, and a second CA is a reasonable hedge against an outage or a distrust event. The problem is unexamined width. Nine domains (cloudflare.com, digitalocean.com, gitlab.com, npmjs.com, prometheus.io, render.com, caddyserver.com, traefik.io and neon.tech) carry pki.goog; cansignhttpexchanges=yes entries. That pattern matches the set Cloudflare adds automatically when a Universal SSL zone has any CAA record. Cloudflare also notes that those added records do not show in its dashboard. In practice, many allowlists were written by a platform rather than chosen by the domain owner.
Every allowed CA is another organization whose validation an attacker can try. If you cannot say why a CA is on your list, it should probably come off.
Account binding is nearly absent
RFC 8657 adds two parameters to an issue value. accounturi limits issuance to one ACME account, and validationmethods limits how the CA may check control. Let’s Encrypt’s documentation states the purpose plainly: account binding ensures that “someone who temporarily hijacks your domain, but doesn’t have access to your ACME Account key, can’t issue malicious certificates.” That is precisely the ccTLD hijack scenario.
Four domains bind some issuance to an account, and their setups differ:
- debian.org is the only complete configuration in the sample. It publishes a single
issuevalue with the critical flag:letsencrypt.org;validationmethods=dns-01;accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/346607. It addsissuewild ";"to forbid wildcards and aniodefcontact. One CA, one account and one validation method. - ubuntu.com publishes an account-bound Let’s Encrypt record next to a plain
issue "letsencrypt.org". Because CAA records are additive, the plain record allows any Let’s Encrypt account, so the binding has no effect. The bound record also uses the older ACMEv1acme/reg/URL form. - netlify.com binds DigiCert with a DigiCert-specific
account=parameter and sets the critical flag. It leavesamazon.comunbound. - atlassian.com binds DigiCert the same way but leaves Amazon, GlobalSign, Let’s Encrypt and Google Trust Services open. Its serving certificate and all 233 certificates indexed for the name since October 2025 came from Amazon.
The pattern behind the last three is the main finding. Binding one CA protects nothing while an unbound CA remains on the list, because an attacker simply picks the open one.
One mismatch: openssl.org
openssl.org serves a Google Trust Services certificate issued August 18, 2026, valid until November 17. Its CAA record today allows only letsencrypt.org. CAA is checked at issuance, not afterward, so the likeliest explanation is that the record changed after that date. The site’s nameservers are Google Cloud DNS. Google Cloud’s managed-certificate documentation says that if CAA names only one of pki.goog and letsencrypt.org, “only that CA is used to create and renew your certificate,” and it recommends allowing both. Whatever renews this certificate next must therefore get it from Let’s Encrypt, or the renewal will fail.
This is the most common way CAA breaks production. A record edited for one reason quietly blocks a renewal path months later, and the failure surfaces as an expired certificate rather than a DNS error. We walked through the same failure shape in an ACME renewal that broke.
Every other restricting domain passed both checks. The serving CA was allowed in all 32, and every CA organization seen in CertIndex history since October 2025 was also allowed.
Full CAA table
Rows list the 34 domains with any CAA record. “Binding” means accounturi, DigiCert’s account= or validationmethods appears on at least one value.
| Domain | issue identifiers |
issuewild |
iodef |
Binding | Serving CA |
|---|---|---|---|---|---|
| 1password.com | amazon.com, digicert.com, globalsign.com, letsencrypt.org, sectigo.com |
— | yes | — | Let’s Encrypt |
| atlassian.com | amazon.com, digicert.com, globalsign.com, letsencrypt.org, pki.goog |
yes | — | account | Amazon |
| bitbucket.org | amazon.com, digicert.com, globalsign.com, letsencrypt.org |
yes | yes | — | Amazon |
| caddyserver.com | comodoca.com, digicert.com, letsencrypt.org, pki.goog, ssl.com |
yes | — | — | Let’s Encrypt |
| cloudflare.com | comodoca.com, digicert.com, letsencrypt.org, pki.goog, ssl.com |
yes | yes | — | Google Trust Services |
| debian.org | letsencrypt.org |
deny | yes | account, method | Let’s Encrypt |
| digitalocean.com | awstrust.com, comodoca.com, digicert.com, globalsign.com, letsencrypt.org, pki.goog, ssl.com |
yes | yes | — | Google Trust Services |
| docker.com | amazon.com, comodoca.com, digicert.com, letsencrypt.org, pki.goog, sectigo.com |
— | yes | — | Let’s Encrypt |
| github.com | digicert.com, globalsign.com, letsencrypt.org, sectigo.com |
yes | — | — | Sectigo |
| gitlab.com | amazon.com, amazonaws.com, amazontrust.com, awstrust.com, comodoca.com, digicert.com, globalsign.com, letsencrypt.org, pki.goog, sectigo.com, ssl.com |
yes | yes | — | Sectigo |
| go.dev | letsencrypt.org, pki.goog |
— | — | — | Google Trust Services |
| golang.org | letsencrypt.org, pki.goog |
— | — | — | Google Trust Services |
| kubernetes.io | letsencrypt.org, pki.goog |
— | — | — | Let’s Encrypt |
| letsencrypt.org | amazon.com, letsencrypt.org, pki.goog, sectigo.com, ssl.com, www.digicert.com |
yes | — | — | Let’s Encrypt |
| mozilla.org | amazon.com, amazonaws.com, amazontrust.com, awstrust.com, certainly.com, comodoca.com, digicert.com, letsencrypt.org, pki.goog, sectigo.com |
— | yes | — | Google Trust Services |
| neon.tech | amazon.com, comodoca.com, digicert.com, letsencrypt.org, pki.goog, sectigo.com, ssl.com |
yes | yes | — | Google Trust Services |
| netlify.com | amazon.com, digicert.com |
— | yes | account | DigiCert |
| npmjs.com | comodoca.com, digicert.com, letsencrypt.org, pki.goog, sectigo.com, ssl.com |
yes | — | — | Google Trust Services |
| nuget.org | (none; contactemail only) |
— | — | — | Microsoft |
| openssl.org | letsencrypt.org |
— | yes | — | Google Trust Services |
| packagist.org | amazon.com, letsencrypt.org |
— | yes | — | Let’s Encrypt |
| pagerduty.com | amazon.com, amazonaws.com, amazontrust.com, awstrust.com, comodo.com, digicert.com, letsencrypt.org, pki.goog |
yes | yes | — | DigiCert |
| postgresql.org | amazontrust.com, letsencrypt.org |
— | yes | — | Let’s Encrypt |
| prometheus.io | comodoca.com, digicert.com, letsencrypt.org, pki.goog, ssl.com |
yes | — | — | Google Trust Services |
| pypi.org | amazon.com, globalsign.com, letsencrypt.org |
— | yes | — | GlobalSign |
| redhat.com | amazontrust.com, digicert.com, letsencrypt.org |
— | yes | — | DigiCert |
| render.com | digicert.com, letsencrypt.org, pki.goog |
yes | yes | — | Google Trust Services |
| rubygems.org | amazonaws.com, comodoca.com, globalsign.com, letsencrypt.org |
yes | — | — | GlobalSign |
| sentry.io | digicert.com, letsencrypt.org |
— | yes | — | DigiCert |
| stripe.com | amazon.com, digicert.com, visa.com |
— | yes | — | DigiCert |
| tailscale.com | amazon.com, amazonaws.com, amazontrust.com, awstrust.com, comodoca.com, digicert.com, letsencrypt.org |
deny | — | — | Let’s Encrypt |
| traefik.io | comodoca.com, digicert.com, letsencrypt.org, pki.goog, ssl.com |
yes | — | — | Google Trust Services |
| ubuntu.com | digicert.com, letsencrypt.org |
yes | yes | account | Let’s Encrypt |
| vercel.com | globalsign.com, letsencrypt.org, pki.goog, sectigo.com |
— | — | — | Let’s Encrypt |
What to change on your own domains
- Inventory the CAs you use. Search CT for your names (the CT lookup tool does this) and list every issuing organization for the last year. Include the CDN, load balancer and SaaS vendors that request certificates for you.
- Write CAA to match. Add one
issuevalue per CA you use, plus at most one deliberate backup. If you never use wildcards, addissuewild ";". The CAA record reference covers syntax. - Bind every entry, or none. Add
accounturi(andvalidationmethodsif your CA supports it) to every CA on the list, and delete the unbound duplicate. A partially bound list protects against nothing. - Add
iodef. It costs nothing and gives CAs an address for reporting requests that violate your policy. - Watch for drift. Re-run the CAA query and the serving-issuer check whenever DNS or hosting changes, and before each renewal window. The TLS inspector shows the serving chain.
- Keep CT monitoring. CAA is a preventive control, and CT is what caught the ccTLD certificates. You need both.
Limitations
The sample is 60 hand-picked registrable domains, not a random draw. Results describe each apex name only. Subdomains such as api. or registry. may delegate elsewhere and have their own CAA or CNAME targets, and Cloudflare notes that CAA on a CNAME target takes precedence. Issuer history comes from one CT index and is a lower bound. CAA records change, so this is a snapshot of October 10, 2026.
Recommended reading
- Certificate Transparency explained
- How to read a TLS certificate
- The Control Plane, week of October 5, 2026
Frequently asked questions
What share of developer-infrastructure domains publish CAA records?+
Does a CAA record stop an attacker who hijacks my DNS?+
Which site in the sample had the strongest CAA configuration?+
Why is binding only one CA to an account not enough?+
Can a CAA change break certificate renewal?+
How can I reproduce these measurements?+
Tags: #caa, #dns, #tls, #certificate-transparency, #acme, #original-data