Skip to content

TLS certificates

DTM terminates TLS in two places, and they have different certificate lifecycles. This page covers what serves which certificate, the two-year clock on the first-boot certificate, how to watch expiry, and how to rotate or bring your own.

Surface Port(s) Certificate
Web UI 8080 The managed UI certificate at /etc/dtm/tls/ on each node: self-signed with 2-year validity at first boot, or one you supply.
REST API 8443 By default, a fresh self-signed certificate at every service start. Configurable; see below.
DNS-over-TLS and DNS-over-HTTPS 853, 443 Share the API’s certificate material; there is no separate DoT or DoH certificate.

How the UI certificate is provisioned depends on how you deployed:

  • Terraform: the primary node generates the certificate and key at first boot and publishes them to Key Vault as the dtm-tls secret (a single combined PEM bundle, certificate plus key); every node reads the same bundle, so the whole cluster serves one UI certificate. The private key never enters Terraform state. See Terraform provider setup.
  • Azure Marketplace: each node generates its own self-signed UI certificate at first boot, with the node’s IP as the subject alternative name.

The first-boot UI certificate is valid for 730 days and there is no automatic renewal. When it expires, browsers refuse the UI outright (a harder stop than the self-signed warning you already click through), so plan a rotation before the two-year mark. A natural moment is your regular certificate-hygiene cycle, or the first rotation onto a corporate-CA certificate, which makes the warning disappear too.

The API’s default certificate has no such clock: it is regenerated at every service start, which is exactly why the examples in these docs use curl -sk and why production clients that verify TLS should give the API a stable certificate.

On a node (the certificate directory is group-restricted, so the read needs sudo):

Terminal window
sudo openssl x509 -in /etc/dtm/tls/cert.pem -noout -enddate

Or from anywhere that can reach the UI:

Terminal window
openssl s_client -connect <node-ip>:8080 </dev/null 2>/dev/null \
| openssl x509 -noout -enddate

The Diagnose page also runs a certificate-validity check against a configured API certificate: it warns when the certificate is within 30 days of expiry and fails once it has expired, so it shows up in routine health reviews and in support bundles.

Terraform deployments (one cluster-wide certificate)

Section titled “Terraform deployments (one cluster-wide certificate)”
  1. Produce a new combined PEM bundle: the certificate and its private key concatenated into one file. From your CA, or self-signed again:

    Terminal window
    openssl req -x509 -newkey rsa:4096 -nodes -days 730 \
    -keyout key.pem -out cert.pem \
    -subj "/CN=dtm-ui" -addext "subjectAltName=DNS:dtm-ui"
    cat cert.pem key.pem > bundle.pem
  2. Update the dtm-tls Key Vault secret with the new bundle:

    Terminal window
    az keyvault secret set --vault-name <vault> --name dtm-tls --file bundle.pem

    If you deployed with the write-only certificate variable, update through Terraform instead so your configuration stays the source of truth: set the new bundle in dtm_ui_tls_pem_wo, increment dtm_ui_tls_pem_wo_version (write-only values are never stored in state, so the version counter is what tells Terraform to re-send the bytes), and apply.

  3. On each node in turn, remove the installed pair and re-run the secret bootstrap, which re-fetches the bundle from Key Vault, validates that the certificate and key match (a mismatched bundle is refused rather than served), and installs it with the right ownership:

    Terminal window
    sudo rm /etc/dtm/tls/cert.pem /etc/dtm/tls/key.pem
    sudo systemctl restart dtm-bootstrap.service
    sudo systemctl restart dtm-ui

Rotating the UI certificate never touches DNS: only the UI service restarts.

Marketplace deployments (per-node certificates)

Section titled “Marketplace deployments (per-node certificates)”

Each node manages its own pair at /etc/dtm/tls/. On each node, either install your own certificate and key over the existing files, or delete both files and restart dtm-bootstrap.service to mint a fresh two-year self-signed pair; then restart dtm-ui. If you install files by hand, match the expected ownership, since the UI refuses to start on a group- or world-readable private key:

Terminal window
sudo chown root:dtm-ui /etc/dtm/tls/cert.pem && sudo chmod 0640 /etc/dtm/tls/cert.pem
sudo chown dtm-ui:dtm-ui /etc/dtm/tls/key.pem && sudo chmod 0400 /etc/dtm/tls/key.pem
sudo systemctl restart dtm-ui

Enterprise deployments usually want the UI on a certificate their browsers already trust:

  • At deploy time (Terraform): supply a combined PEM bundle through the write-only dtm_ui_tls_pem_wo variable. It is written straight to the dtm-tls Key Vault secret and never persisted to Terraform state, and the cluster boots directly onto your certificate instead of self-signing.
  • After deploy: follow the rotation procedure with your CA-issued bundle.

Issue the certificate with subject alternative names covering however your operators reach the UI (a DNS name you publish for the nodes, or the node IPs).

To stop the API regenerating its certificate on every start, and to let API clients (including the Terraform provider) verify TLS properly, point dtm-server at certificate files on disk in /etc/dtm/dtm-server.yaml on each node:

listen:
tls:
cert_file: /etc/dtm/api-tls/cert.pem
key_file: /etc/dtm/api-tls/key.pem

Both fields must be set together, the key file must be readable by its owner only, and a missing or unreadable file stops startup with a clear error rather than silently falling back to self-signing. Restart dtm-server one node at a time to pick the files up: a node stops answering DNS while it restarts, so treat it like a step of a rolling upgrade.

The DNS-over-TLS and DNS-over-HTTPS listeners serve the same certificate, so configuring this once also gives resolvers a verifiable certificate on ports 853 and 443. Include every node’s address (or a shared DNS name) in the certificate’s subject alternative names.

  • Rotating secrets: the rest of the cluster’s credential lifecycle in one place.
  • Security: the full protections-and-responsibilities picture.