Authentication

The plugin signs in to Azure with the azure-identity library. The config file selects one of six methods; the examples on this page show only the authentication keys, add your dns_azure_zone<N> lines as described in Configuration.

Which method?

Where certbot runs

Method

Outside Azure: home server, NAS, Nginx Proxy Manager, other clouds

Service principal, with a certificate if possible, else a client secret

Azure VM, scale set, container instance, App Service, Container Apps

User-assigned managed identity (system-assigned works too)

On-premises server connected with Azure Arc

System-assigned managed identity

Kubernetes with Microsoft Entra Workload ID (AKS)

Workload identity

Interactive use on a workstation

Azure CLI

Managed identities and workload identity store no secret at all; prefer them where they are available.

Note

Each credential set uses exactly one method. If keys for several methods are present, the first one in this order wins and the others are ignored, with no fallback if it fails: Azure CLI, workload identity, service principal with secret, service principal with certificate, user-assigned managed identity, system-assigned managed identity. A leftover dns_azure_use_cli_credentials = true therefore overrides a service principal. Zones that need different identities get their own credential set, see Several credential sets (zones in different tenants).

Required permissions

The plugin reads, creates, updates and deletes the TXT record sets used for validation (the _acme-challenge records, or the record named in a record mapping) and touches nothing else. Assign the built-in role DNS Zone Contributor to the identity; broader roles such as Contributor or Owner are not needed. Keep the scope as small as possible:

Scope

Covers

DNS zone (recommended)

That zone only.

Resource group

Every zone in the group, including zones added later.

Single TXT record set

Only that record. Needs a record mapping, see DNS delegation and least privilege.

az role assignment create \
  --assignee-object-id <object-id> --assignee-principal-type ServicePrincipal \
  --role "DNS Zone Contributor" \
  --scope /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Network/dnszones/example.com

<object-id> is the identity’s object (principal) ID, for a service principal az ad sp show --id <app-id> --query id -o tsv. Managed identities are service principals too. For the Azure CLI method the identity is your user: use --assignee-principal-type User and the ID from az ad signed-in-user show --query id -o tsv. In the portal, use DNS zone → Access control (IAM) → Add role assignment. New assignments can take up to 10 minutes to become effective.

Service principal with client secret

The simplest choice for hosts outside Azure. One command creates the app registration and its secret and assigns the role on the zone:

az ad sp create-for-rbac --name certbot-dns-azure \
  --role "DNS Zone Contributor" \
  --scopes /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Network/dnszones/example.com

It prints appId (client ID, <app-id> in the commands below), password (client secret) and tenant (tenant ID). The portal steps are described in Nginx Proxy Manager.

dns_azure_sp_client_id = 912ce44a-0156-4669-ae22-c16a17d34ca5
dns_azure_sp_client_secret = example-client-secret-not-real
dns_azure_tenant_id = ed1090f3-ab18-4b12-816c-599af8a88cf7

Secret expiry and rotation

Warning

Client secrets expire: after one year with az ad sp create-for-rbac (change it with --years), after the period chosen in the portal (at most 24 months). Renewals fail from that day on, typically with AADSTS7000222.

Check the expiry date and rotate without downtime by adding a new secret before removing the old one:

az ad app credential list --id <app-id> \
  --query "[].{name:displayName, id:keyId, end:endDateTime}" -o table
az ad app credential reset --id <app-id> --append --display-name certbot-2027 --years 1

Put the printed password into the config file, test with certbot renew --dry-run, then delete the old secret with az ad app credential delete --id <app-id> --key-id <old-key-id>.

Service principal with certificate

Same as above, but the app registration authenticates with a certificate, which Microsoft recommends over secrets. Create the service principal with a certificate in one step:

az ad sp create-for-rbac --name certbot-dns-azure --create-cert --years 1 \
  --role "DNS Zone Contributor" \
  --scopes /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Network/dnszones/example.com

The command writes a PEM file with the certificate and the private key and prints its path. For an existing app registration use az ad app credential reset --id <app-id> --create-cert --append. Move the file next to the config file and make it readable for root only (chmod 600).

dns_azure_sp_client_id = 912ce44a-0156-4669-ae22-c16a17d34ca5
dns_azure_sp_certificate_path = /etc/letsencrypt/certbot-dns-azure.pem
dns_azure_tenant_id = ed1090f3-ab18-4b12-816c-599af8a88cf7

The file may be PEM or PKCS#12 (.pfx) and must contain both the certificate and the private key. The key must not be password-protected. Certificates expire as well; rotate them like secrets.

User-assigned managed identity

For Azure resources with a user-assigned managed identity attached: virtual machines, scale sets, container instances, App Service, Container Apps. Assign the role to the identity’s principal ID and reference the identity by its client ID:

az identity show --name <identity> --resource-group <resource-group> \
  --query "{clientId:clientId, principalId:principalId}"
dns_azure_msi_client_id = 912ce44a-0156-4669-ae22-c16a17d34ca5

Every process on the resource that can reach the identity endpoint can use the identity. A user-assigned identity dedicated to certbot keeps that exposure limited to DNS.

System-assigned managed identity

Uses the resource’s own identity. Besides Azure resources this also works on on-premises servers connected with Azure Arc; there, certbot must run as root or as a member of the himds group. Assign the role to the resource’s identity and switch the method on:

dns_azure_msi_system_assigned = true

Workload identity

For pods in Kubernetes with Microsoft Entra Workload ID (AKS, also Azure Arc-enabled Kubernetes). Its webhook injects AZURE_CLIENT_ID, AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE into labelled pods; the linked guide covers the service account and federated credential. The config file only switches the method on:

dns_azure_use_workload_identity_credentials = true

dns_azure_tenant_id, if set, overrides AZURE_TENANT_ID.

Azure CLI

Uses the Azure CLI login (az login) of the user that runs certbot. No secrets are stored in the config file.

dns_azure_use_cli_credentials = true

Note

Intended for interactive and one-off use. A user login is subject to Microsoft’s mandatory multifactor authentication for Azure Resource Manager write operations, and its session expires, so unattended renewals start failing sooner or later. For renewals use a managed identity or a service principal instead.

dns_azure_tenant_id pins the tenant when the CLI is logged in to several. The token cache lives in ~/.azure of the user that ran az login; renewals from cron or systemd usually run as root and need that user’s login. For sovereign clouds, run az cloud set --name <cloud> before az login.