go-acme/lego Week in Review: PrimeDNS Provider and an Experimental Conditional DNS Builder


go-acme/lego is the ACME client most Go operators reach for when they need certificates issued against Let’s Encrypt or any RFC 8555 compliant CA. The past week brought four commits to main, and two of them matter beyond routine maintenance: a new PrimeDNS DNS provider and an experimental feature that changes how the DNS01 challenge can be composed. The dependency updates are the bulk of the diff volume but the least interesting part.

The headline change is the PrimeDNS provider, merged on October 18. It follows the standard provider layout the project has settled on: a thin exported wrapper in providers/dns/primedns/primedns.go, the actual HTTP client hidden in providers/dns/primedns/internal/client.go, TOML configuration in primedns.toml, and generated documentation in docs/content/dns/zz_gen_primedns.md.

One detail worth noting is that PrimeDNS also lands in providers/dns/internal/dnslight/ with a generated zz_gen_primedns.go. That is the dnslight abstraction the project uses for smaller DNS APIs, and it means the provider gets wired into both code paths automatically. The commit count in cmd/zz_gen_cmd_dnshelp.go and providers/dns/zz_gen_dns_providers.go is a reminder of how much of this project is generated: CLI help, provider registration, and the CI matrix all regenerate when a provider is added.

For anyone operating certificates, the practical takeaway is simple. If your DNS zone lives on PrimeDNS, you can now automate the DNS01 challenge without shelling out to a second tool. Expect the usual environment variable configuration shape:

// typical provider setup, as with every lego DNS provider
dnsProvider, err := primedns.NewDNSProviderConfig(config)

The test fixtures under fixtures/create.json, delete.json, and error.json show the API surface the client exercises: create, delete, and an error path. That error fixture matters. Many third party DNS APIs return nonstandard error bodies, and a provider that only tests the happy path tends to produce confusing ACME failures later.

The more interesting change for people who already run lego in production is the experimental conditional DNS builder. The DNS01 challenge traditionally assumes one provider handles the whole zone. If your certificate set spans zones in different accounts or different registrar APIs, you had to either run separate lego instances or glue providers together yourself.

The word experimental in the commit subject is doing real work here. This is not a marked stable API. The tradeoff as it stands: early adopters get zone level routing between providers without external orchestration, while anyone pinning to this surface should expect the shape of the builder to move in subsequent commits. If you build automation on top of it, wrap it behind your own interface so the migration cost stays inside one file when it changes.

For platform teams managing hundreds of certificates across accounts, this direction is the right one. The alternative patterns in wide use, such as running one issuer deployment per DNS account, work but multiply your certificate inventory and your alerting. A first class conditional builder inside lego reduces that operational sprawl.

Two commits on October 14 account for most of the 275 changed files and roughly five thousand of the added lines: a regular dependency update and a major version update sweep. Both touch go.mod and go.sum.

Most of the diff volume in this window is generated artifacts and lockfile churn. That is normal for this repository. A single provider addition regenerates the CLI help data, the provider registry, and the CI workflow file that lists every build tag. The workflow in .github/workflows/tests-lint.yml carries a test invocation with a --tags list covering every DNS provider, and it is generated by a Makefile target, which is why it appears in two commits this week.

The major version sweep is worth a second look if you import lego as a library rather than run the binary. Major version bumps in transitive dependencies occasionally change behavior in edge cases, and the project’s own test suite of roughly two hundred DNS providers is the best canary you will get. If your own CI pins lego, run your certificate issuance path against this week’s main before the next tagged release.

Three follow ups to track:

  • The conditional DNS builder is flagged experimental. Watch for follow up commits that either stabilize the API or change its constructor surface. Do not hard code against it yet.
  • PrimeDNS will get its first real world exercise. Third party DNS providers that land with fixture based tests sometimes need quick fixes once real API responses diverge from the fixtures. Check the provider issues if you plan to adopt it early.
  • The major version dependency sweep may inform the next tagged release. If you ship lego in a Go service, review the diff to go.mod now rather than at release time.

Overall this was a focused week: one new provider, one forward looking API experiment, and routine dependency hygiene. Everything is on the repo main branch.