Issue certificates with DNS-01 validation
ACME certificate authorities such as Let's Encrypt can verify that you control a domain by asking you to publish a TXT record on its _acme-challenge name. This is the DNS-01 challenge. It is the only challenge type that can issue wildcard certificates, and it works for servers that are not reachable from the internet.
Domain Chief has two endpoints for this: one publishes a challenge value and one deletes it. A token with the domainchief:acme:write scope can call them and nothing else, so a server that renews certificates never holds a token that can change your other DNS records.
Use an existing client when one fits:
- Certbot for servers that run Certbot.
- cert-manager for Kubernetes clusters.
- The ACME endpoints directly when you build or extend your own ACME client.
Before you start
Domain requirements
The domain must be in the team that owns the token and must use Domain Chief hosted DNS. The challenge records are published in the hosted DNS zone, so a domain that uses other nameservers cannot be validated this way.
Create a token
Create a team access token with only the domainchief:acme:write scope. Select the team that owns the domains you issue certificates for.
A team access token keeps working when the person who created it leaves the team, and it never switches to another team. See authentication for the token types and scopes for what the scope allows.
Anyone holding the token can obtain certificates for every domain in the team. Store it like any other credential and give each server or cluster its own token, so you can revoke one without affecting the others.
Use an existing client
Certbot
The certbot-dns-domainchief plugin adds a dns-domainchief authenticator to Certbot. Install it the same way you installed Certbot:
Code
Save the token in a credentials file that only the user running Certbot can read:
Code
Then request a certificate:
Code
Certbot stores the credentials path and reuses it for renewals. The plugin waits a fixed time for the record to reach the nameservers before Certbot asks for validation. Raise it with --dns-domainchief-propagation-seconds if validation fails because the record was not found.
cert-manager
The cert-manager-webhook-domainchief webhook adds Domain Chief as a DNS01 solver for cert-manager. Install it into the cert-manager namespace:
Code
Store the token in a Secret the webhook can read:
Code
Reference the webhook from an issuer's DNS01 solver:
Code
The webhook publishes the challenge on the _acme-challenge name in the domain's own hosted DNS zone, so the cnameStrategy: Follow solver option is not supported.
cert-manager checks the nameservers itself and only asks for validation once the record is visible. The chart documentation lists every chart value, including how to read the Secret from other namespaces for namespaced issuers and how to run multiple replicas.
Publish and delete challenges
Use these requests when you build your own ACME client or add Domain Chief to one. The flow for each challenge is:
- Your ACME client receives a DNS-01 challenge and computes the TXT value.
- Publish the value on the
_acme-challengename. - Wait until the nameservers serve it.
- Tell the certificate authority to validate the challenge.
- Delete the value once validation finishes, whether it succeeded or not.
Publish a challenge value
Send the fully qualified challenge name and the value to publish ACME challenge:
Code
The name must start with _acme-challenge.. A trailing dot is accepted, so you can pass the name exactly as most ACME libraries return it. The value is the base64url-encoded challenge value, without padding.
You don't send the domain. Domain Chief finds it from the name, using the most specific matching domain in the team. The response returns an ACMEChallenge with the domain it chose:
Code
Publishing is safe to repeat. If the value is already published, Domain Chief returns the existing challenge instead of adding a second record.
Other values on the same name are kept. A certificate for both example.com and *.example.com needs two values on _acme-challenge.example.com, and you can publish both before validating either.
Wait for the record
A successful response means Domain Chief accepted the value, not that the nameservers already serve it. Publishing to the hosted DNS nameservers takes a short time.
Before you ask the certificate authority to validate, look up the TXT record on the domain's authoritative nameservers until the value appears. Query the authoritative nameservers directly. A public resolver may cache the earlier answer and keep returning it for longer than the record takes to publish.
Delete a challenge value
After validation, delete the value with delete ACME challenge. Pass the same name and value as query parameters:
Code
Only that value is deleted. Values for other challenges on the same name stay published, so concurrent renewals don't remove each other's records.
Deleting a value that is not published also succeeds, so a cleanup step can run safely after a failed or repeated attempt. If your client crashes before cleaning up, Domain Chief removes challenge values automatically after 24 hours.
Handle errors
Errors use the standard error response. Branch on the HTTP status and, for 409 responses, on the code:
| Status | Meaning | What to do |
|---|---|---|
401 | The token is missing, expired, or revoked. | Replace the token. |
403 | The token has neither domainchief:acme:write nor domainchief:dns:write. | Create a token with domainchief:acme:write. |
404 | No domain in the team matches the challenge name. | Check that the domain is in the token's team. |
409 with dns.not_hosted | The domain does not use hosted DNS. | Retrying does not help until the domain uses hosted DNS. |
409 with dns.zone_busy or dns.zone_changed | Another hosted DNS change for the domain was running. | Retry after a few seconds. |
422 | The name or value is invalid. | Fix the request using the messages in errors. |
5xx | Domain Chief could not complete the request. | Retry with a growing delay. Publishing and deleting are safe to repeat. |
Treat unknown code values as permanent failures and report the message to the person running the client.