github fabriziosalmi/certmate v2.4.6
v2.4.6 — domain alias mode (#122) + CI workflow fix

latest release: v2.4.7
one hour ago

Closes #124. Substantive contribution from @ITJamie (#122 — 1445 additions, 12 files, 47 test cases).

Domain alias mode that actually works

The previous DNS-01 alias flow assumed the primary domain's DNS was manageable by your provider; CertMate would still try to write the _acme-challenge TXT record on the primary zone and fail with Unable to determine zone_id for <primary>. The whole point of alias mode is the case where it isn't — only the alias zone is. This release reworks the flow:

  • modules/core/dns_alias_hook.py — new Lexicon-backed manual DNS hook supporting cloudflare, route53, azure, google, powerdns, digitalocean, linode, gandi, ovh, namecheap, arvancloud, infomaniak, duckdns, acme-dns. Writes the TXT on the alias zone, lets the CNAME chain resolve. Unsupported providers are rejected up-front with a clear error instead of failing mid-certbot.
  • POST /api/certificates/<domain>/check-cnames — new endpoint to verify the _acme-challenge CNAME chain exists for a domain (and all its SANs) before issuing. Surfaces missing records up-front instead of after a 60s certbot retry.
  • UI: alias indicator pill on dashboard cert rows, alias display in cert detail panel, SAN list in the sidebar, hint help text in the create-cert form.
  • Renewal path: rebuilds the manual hook from cert metadata so renewals don't fail when the temp credentials file is gone (the alias-mode sibling of #112 — different code path, same shape of bug, fixed here for the alias case).
  • Tests: 47 cases in tests/test_domain_alias.py covering hook regeneration on renewal, SAN+wildcard expectations, CNAME existence reporter, unsupported-provider rejection, missing-credentials handling, ACME-DNS subdomain matching, lexicon adapter mapping for all 14 supported providers.

CI workflow fix (visible to every external contributor)

docker-multiplatform.yml was constructing image tags like docker.io//certmate:pr-NN (double slash from an empty secrets.DOCKERHUB_USER on fork PRs — GitHub Actions intentionally doesn't pass secrets to fork workflows). Every dependabot PR and every external contributor PR had been red on the build job for that reason alone, hiding real test signal. Added a one-line fallback: when DOCKERHUB_USER is empty, use github.repository_owner instead. Push to Docker Hub is still disabled for PRs (gated separately).

Maintainer reconciliation during the rebase

The PR was opened before the v2.4.x cleanup landed. To bring it on top of v2.4.5:

  • dashboard.js cert-row template reconciled with the v2.4.2 CertMate.html auto-escape helper (alias indicator now uses ${domainAlias} interpolation; providerLabel goes through rowRaw()).
  • Bandit B310 hardening: scheme-validate the DNS-provider API URL in _json_request, # nosec B310 - hardcoded https literal on the two static URLs (api.ipify.org for Namecheap public-IP injection; cloudflare-dns.com for the new DoH lookup).

Tests

  • 209 unit tests pass (was 162 — +47 from #122)
  • All e2e tests pass (build + test (3.12) green on the merged PR for the first time across all the v2.4.x triage PRs)

Full diff: v2.4.5...v2.4.6

Don't miss a new certmate release

NewReleases is sending notifications on new releases.