CAA pinning
A CAA record on a hostname restricts which ACME account — and which validation method — may issue a TLS cert for it, even from a different account on a different server. Pin whoever runs ACME for the hostname.
Tunneled services
Section titled “Tunneled services”Tunneling is TLS passthrough: your origin runs ACME and holds the cert.
So you pin your own ACME client’s account. accounturi= is your
client’s account URI, and validationmethods= is whatever your client
actually uses (http-01, dns-01, or tls-alpn-01).
Where to find your account URI:
- cert-manager: the account URL is stored on the
Issuer/ClusterIssuerstatus (status.acme.uri) once the issuer is registered. You can also re-derive it by re-registering with the existing account private key — Let’s Encrypt’snewAccountendpoint returns the existing account’s URL via theLocationheader when the key already has an account. - certbot:
/etc/letsencrypt/accounts/<server>/directory/<id>/regr.json, fielduri. - acme.sh:
~/.acme.sh/ca/<server>/account.json, fieldlocation. - Caddy: in the data directory, look for
acme/<server>/users/<email>/<acc>.json, fieldlocation.
Publish the record at your hostname:
<your-hostname> CAA 0 issue "letsencrypt.org;validationmethods=<method>;accounturi=<your-account-uri>"What it actually says
Section titled “What it actually says”validationmethods=...— only that challenge type may be used. The others are refused even from the same Let’s Encrypt account.accounturi=...— only that specific Let’s Encrypt account may issue. Pin the account that actually runs ACME for the hostname; pinning any other account refuses every renewal.
Catching a bypassed pin
Section titled “Catching a bypassed pin”Certificate Transparency is the backstop: every cert issued for your hostname appears in public CT logs, even if CAA enforcement failed. Watch your hostname with:
- certspotter — email alerts on new certs.
- merklemap — browser search over CT.
Verify the record actually published
Section titled “Verify the record actually published”Some DNS providers (Cloudflare in particular) silently rewrite or drop CAA records when their own cert features are on. Check with an external resolver:
dig @1.1.1.1 +short <your-hostname> CAAIf your letsencrypt.org;... line isn’t there, look for a “Universal
SSL” / “auto CAA” / “managed certs” toggle in the provider dashboard and
turn it off.
Hub operators
Section titled “Hub operators”The hub runs ACME for its own control-plane hostname (e.g.
hub.example.eu). Pin that hostname so a rogue ACME client can’t get a
cert for it.
The hub’s account is public at /v1/acme/account:
curl https://<hub>/v1/acme/account{ "account_uri": "https://acme-v02.api.letsencrypt.org/acme/acct/123456789", "caa_record": "letsencrypt.org;validationmethods=tls-alpn-01;accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/123456789"}Paste caa_record verbatim as the value of a CAA record at the hub
hostname. The CLI prints the same line ready to paste:
towonel acme account