Skip to main content
This guide walks you through configuring the Certplane broker to obtain publicly-trusted certificates from Let’s Encrypt using the dns-01 challenge. The dns-01 challenge proves domain ownership by creating a DNS TXT record — it works even for servers not reachable from the internet, and is required for wildcard certificates.
Let’s Encrypt enforces strict rate limits on its production environment. Always validate your setup against the staging environment before switching to production.
1

Get your Cloudflare API token

In the Cloudflare dashboard, create an API token with Zone → DNS → Edit permission scoped to the zone (or zones) you want Certplane to manage. Do not use a Global API Key — a scoped token limits the blast radius if the credential is ever exposed.Once you have the token, note its value. You’ll store it in the next step.
2

Store the token

The simplest approach is the env secrets provider. Export the token as an environment variable before starting the broker:
export CLOUDFLARE_DNS_API_TOKEN="your-token-here"
With secrets.provider: env the broker reads the environment variable whose name appears in acme.credentials. To load credentials from a file or from Vault/OpenBao instead, see Secrets providers and the Vault and OpenBao secrets guide.
Generate your ACME account key before continuing. Certplane reads this key to sign ACME requests — it is not a certificate, and you should keep it in a secure, backed-up location:
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out /etc/certplane/acme/account.key
3

Configure the broker

Edit your broker.yml to point the issuer block at the Let’s Encrypt staging directory and configure the Cloudflare DNS provider. Start with staging so you can confirm everything works without burning production rate limits.
issuer:
  provider: acme
  acme:
    directory_url: https://acme-staging-v02.api.letsencrypt.org/directory
    account_email: admin@example.com
    account_key: /etc/certplane/acme/account.key
    dns_provider: cloudflare

secrets:
  provider: env
The account_key must be the path to the EC private key you generated above. The account_email is the address Let’s Encrypt uses to send expiry warnings; it does not need to match any DNS record.
4

Create a wildcard profile in policy.yml

Add a profile that requests a wildcard certificate using the dns-01 challenge. The credentials value is the name of the secret as interpreted by your configured secrets provider — for the env provider, this is the environment variable name.
profiles:
  public_wildcard:
    type: wildcard
    dns_names:
      - "*.example.com"
    acme:
      challenge: dns-01
      credentials: CLOUDFLARE_DNS_API_TOKEN
    renew_before: 720h
Then allow the relevant host to request this profile:
hosts:
  web01:
    identity: web01.internal.example.com
    profiles:
      - public_wildcard
Let’s Encrypt ignores the ttl field at issuance time and always issues certificates valid for 90 days. The renew_before value controls when Certplane proactively renews — the default of 720h (30 days) is a sensible starting point.
5

Test with staging, then switch to production

Restart the broker and trigger a certificate request from an agent. Staging certificates are signed by a fake CA that browsers do not trust, but they are structurally identical to production ones — any configuration errors will surface here.Once the staging certificate is issued successfully, switch the broker to the production directory:
issuer:
  provider: acme
  acme:
    directory_url: https://acme-v02.api.letsencrypt.org/directory
    account_email: admin@example.com
    account_key: /etc/certplane/acme/account.key
    dns_provider: cloudflare
Restart the broker. The next renewal cycle (or a forced re-request) will obtain a production certificate trusted by all major browsers and operating systems.