Changelog

2.8.1 (2026-10-09)

Security floor for azure-core, a fix for DNS delegation and reworked documentation. Nginx Proxy Manager 2.16 and later pick this release up automatically (~=2.8.0).

Security

  • Require azure-core>=1.38.0. Older releases are affected by CVE-2026-21226 (deserialization of untrusted data); the previous lower bound 1.32.0 let pip keep such a version when it was already installed in the target environment.

Fixed

  • DNS delegation to a zone whose name occurs inside the requested domain (for example the zone le.com for example.com) wrote the TXT record under a truncated name (_acme-challenge.examp instead of _acme-challenge.example.com), so validation failed. Names outside the target zone now always keep their full name.

Changed

  • A weekly workflow audits the dependencies for known vulnerabilities, both the latest resolvable versions and the declared lower bounds.

Documentation

  • Reworked after a full review: quick start first, new pages for Nginx Proxy Manager (portal steps, credentials box) and for switching from certbot-dns-azure, a guide to choosing the authentication method and the role scope, and corrected facts (client secrets expire after one year with the Azure CLI, the migration command now restores module files removed by uninstalling a stacked upstream package).

  • When and how to raise --dns-azure-propagation-seconds (the default stays 10 seconds) and which Let’s Encrypt errors mean the check came too early.

  • The PyPI page is now a short landing page, and the package homepage points to the documentation site.

2.8.0 (2026-09-04)

Every open upstream issue that can be fixed in code is addressed in this release, plus a pre-release review of the whole plugin.

Added

  • Zones can use different credentials: put zones that share an identity into an INI section ([name]) together with that identity’s settings. Sections without authentication keys use the top-level credentials. This allows one certificate to span zones in different Entra ID tenants (terricain/certbot-dns-azure#49).

  • New option --dns-azure-ttl sets the TTL of the _acme-challenge TXT records; the default stays 120 seconds (terricain/certbot-dns-azure#48).

  • Support azure-mgmt-dns 9.x and drop the <9.0.0 pin. 9.x removed the positional api_version parameter of DnsManagementClient, which made the plugin fail with TypeError: __init__() takes from 3 to 4 positional arguments but 5 were given; the client is now constructed with keyword arguments, which works for 8.x and 9.x (terricain/certbot-dns-azure#60, #62).

Fixed

  • Zone matching respects label boundaries: a request for abcxyz.net no longer matches a configured zone xyz.net, and the relative record name is derived by stripping the zone suffix instead of a substring replace (terricain/certbot-dns-azure#61).

  • Boolean config keys (dns_azure_use_cli_credentials, dns_azure_msi_system_assigned, dns_azure_use_workload_identity_credentials) are parsed as booleans. Previously any non-empty value, including false, switched the method on, so a service principal next to dns_azure_use_cli_credentials = false silently used the Azure CLI login.

  • Creating a new _acme-challenge record set is conditional (If-None-Match: *). Two certbot runs racing for the same name no longer overwrite each other; the loser re-reads the record and merges its value, as already happened for updates.

  • Retrying a TXT record update after a concurrent-modification response (HTTP 412) re-resolves the record from the original validation name; the retry previously passed the already relative record name back in.

  • Record sets without TXT values no longer raise TypeError.

  • An unknown dns_azure_environment is reported as a configuration error naming the valid values instead of a KeyError traceback.

  • A zone mapping whose resource id lacks /subscriptions/<id>/resourceGroups/<name> is rejected with a clear message instead of a ValueError from the Azure SDK.

  • Zone names in mappings are compared case-insensitively and trimmed, so Example.com and example.com count as the same zone.

  • The token scope is https://management.azure.com/.default (single slash), as used by the Azure SDK itself.

Changed

  • Python 3.10 or newer is required (was 3.9). certbot 5.x needs 3.10, and on 3.9 pip silently fell back to certbot 3.x.

  • AzureGermanCloud is no longer accepted as dns_azure_environment; Microsoft closed that cloud in 2021.

  • One DnsManagementClient per subscription and credential set is reused instead of a new client and HTTP session for every record operation.

  • Documentation: troubleshooting entry for managed identities behind a proxy (NO_PROXY=169.254.169.254, terricain/certbot-dns-azure#54); the inherited snap packaging files are removed, this fork never published a snap.

CI

  • Unit tests run on Python 3.10 to 3.13, against certbot 3.x and the latest release, and against both azure-mgmt-dns lines (8.x and 9.x).

  • The Azure integration test (real certificate issuance against dedicated test zones) is a required check for pull requests that change code, runs on release tags and once a week against the latest certbot and Azure SDK releases; it retries transient ACME errors and keeps the certbot log as an artifact on failure.

  • main is protected and only changes via pull request; Dependabot keeps the GitHub Actions current.

2.7.0 (2026-09-04)

First release of the maintained fork, published on PyPI as certbot-dns-azure-modern. The Python package (certbot_dns_azure) and the certbot plugin name (dns-azure) are unchanged, so it is a drop-in replacement for certbot-dns-azure.

  • Allow certbot >= 4 (certbot>=3.0, no upper bound). The old <4.0 cap made pip downgrade certbot/acme to 3.3.0 inside shared venvs such as Nginx Proxy Manager, where acme 3.3.0 then failed to import against pyOpenSSL >= 26 (NginxProxyManager/nginx-proxy-manager#5606, terricain/certbot-dns-azure#65).

  • Pin azure-mgmt-dns<9.0.0; 9.x changed the DnsManagementClient constructor (terricain/certbot-dns-azure#58, #62).

  • Require Python >= 3.9.

  • Tests no longer use the deprecated domain= argument of AnnotatedChallenge when the installed certbot supports identifier=.

  • CI: test matrix across Python 3.11-3.13 and certbot 3.x/latest, build with python -m build, publish via PyPI trusted publishing.

2.6.1 and earlier

See the upstream project: https://github.com/terricain/certbot-dns-azure