I read a lot about people running things like Caddy which will automatically retrieve Lets Encrypt certificates. And I think it makes sense for publicly accessible web sites since you can use an HTTP challenge with Let's Encrypt.
For internal-use certificates, you'll have to make use of a DNS challenge with Let's Encrypt. I've been hesitant to set that up because I'm concerned about the potential compromise of a token that has permissions to edit my DNS zone. I see that the author creates exactly that kind of token and has permanently accessible to his script. For a home lab where he's the only person accessing his hardware, that's less of a concern. But what about at a company where multiple people may have access to a system?
Am I being too paranoid here? Or is there a better way to allow DNS challenges without a token that allows too much power in editing a DNS zone?
> I've been hesitant to set that up because I'm concerned about the potential compromise of a token that has permissions to edit my DNS zone.
Depending on your DNS provider, it may be possible to narrow the permissions to allow only updates of a particular record. Route53 as an example:
* https://github.com/acmesh-official/acme.sh/wiki/How-to-use-A...BIND 9 example:
* https://dan.langille.org/2020/12/19/creating-a-very-specific...
You can also point the hostname that you wish to issues certs for to another (sub-)domain completely via a CNAME, and allow updates only for that other (sub-)domain:
* https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mo...
* https://www.eff.org/deeplinks/2018/02/technical-deep-dive-se...
Yes, I see that AWS Route53 can limit credential scope. That kind of thing helps a lot.
I've never heard of that CNAME approach for changing the validation domain. That looks like a viable solution since it requires a one-time setup on the main domain and ongoing access to the second (validation) domain.
> That looks like a viable solution since it requires a one-time setup on the main domain and ongoing access to the second (validation) domain.
At my last job we deployed a special sub-domain for that purpose (dnsauth.example.com) and manually created CNAMEs on our main (sub-)domains to point to it.
We then deployed a single (no-HA) externally exposed BIND server with a bunch of scripts that folks could connect to (we had deploy hooks scripts for users/developrs). Nowadays there even purpose-build DNS servers for this purpose:
* https://github.com/acme-dns/acme-dns
My experience has been that CertBot doesn't play well with CNAME delegation, but it's probably very situational, like depending upon which DNS hosting provider plugin you're using.
My solution was to give up on CertBot and use dehydrated instead. This did require me to come up with a script to make the necessary API call to the DNS hosting, which dehydrated will then run as necessary.
> My experience has been that CertBot doesn't play well with CNAME delegation […]
A CertBot ticket on the subject opened January 2026:
* https://github.com/certbot/certbot/issues/10555
DNS-PERSIST-01 is coming soon https://letsencrypt.org/2026/02/18/dns-persist-01
Oh... that's fantastic! It specifically addresses my concerns about needing DNS credentials accessible to scripts.
The article says it is for those who
> prefer to keep DNS updates and sensitive credentials out of their issuance path.
Oh wow, this will make self-hosting so much easier! I have so far issued probably about 30 different API keys for my subdomain zones for services I host, which you then have to configure with ACME/Certbot. This reduces it to a simple DNS record change!
I used to have a separate Cloudflare account with a separate DNS Zone for my internal services. Because CF PATs were free-for-all. They've improved this since, so now you can create a token scoped to a single Zone. If you really care about, you can move a subdomain to a separate zone with a child NS record, but I haven't tried it with cloudflare. If you are using something like AWS, you can create an IAM role that can only update a single DNS record.
Moving subdomains to separate zones can make sense for a small set of subdomains and all your certificates would be for names under those subdomains. It gets unwieldy if you have to create a separate zone for each certificate because the certificates don't share a subdomain. But this can be a solution in some circumstances. Thanks.
I see that AWS permissions can be set to limit the risk of compromised credentials. That's a good idea. I see that the lego project has an example of this in their documentation: https://go-acme.github.io/lego/dns/route53/index.html#least-...
[dead]
With bind9 you can limit each server to being able to set the TXT record for the specific cert it needs: https://news.ycombinator.com/item?id=47066072
> Am I being too paranoid here? Or is there a better way to allow DNS challenges without a token that allows too much power in editing a DNS zone?
I'd look for a custom DNS challenge provider plugin which delegates the task of creating DNS records to another machine which holds the actual token.
There's at least one ACME client that has this as an explicit feature:
> Get certificates for remote servers - The tokens used to provide validation of domain ownership, and the certificates themselves can be automatically copied to remote servers (via ssh, sftp or ftp for tokens). The script doesn't need to run on the server itself. This can be useful if you don't have access to run such scripts on the server itself, e.g. if it's a shared server.
* https://github.com/srvrco/getssl
It's written in Bash, so dependencies aren't too heavy.
Ah, that's a clever mechanism. That way the secondary machine could not only keep the token secure, but also validate which DNS records to create.
[dead]
There is a way to delegate the DNS challenges, but you can also create a dummy Caddysite for HTTP challenge (e.g., firewall.internal.example.com resolves externally to an IP that Caddy will respond to and get the certificate, and then said certificate is copied internally to whatever needs it).
My solution, put a cname record in your zone, to a subdomain, have that subdomain be served by a seperate DNS server (for example desec.io)
If something gets the credentials for desec.io, they can only use them to do stuff with the single txt record.
In Q2 this year, so very soon, there will be the DNS PERSIST method, which is non rotating.
That looks like a great solution. I'll probably make use of that as soon as it's available.
There’s a way to direct dns challenges to a dns server just for the dns acme challenges: https://blog.bryanroessler.com/2019-02-09-automatic-certbot-...
No need to give broader access