Users and access (RBAC)
DTM has built-in role-based access control (RBAC). Every user has one of three
roles, enforced by the REST API and, through it, the
Terraform provider. The web UI is
stricter: its write controls are admin-only, so an editor sees every page
read-only and makes changes through the API or Terraform.
| Role | Can do | Cannot do |
|---|---|---|
readonly |
List and read DNS data: zones, records, health status, and cluster state. | Make any change, or read restricted data (the audit log is an editor/admin read; the user list and security configuration are admin-only reads). |
editor |
All DNS data-plane writes: zones, records, ALIAS and override records, health checks, forwarders, stub zones, blocklist, subnet mappings, TSIG keys, and zone import. Read the audit log. These are API and Terraform writes; the web UI’s edit controls are admin-only. | Manage users, run cluster operations, or change runtime configuration. |
admin |
Everything, including user management, cluster operations, backup and restore, and all runtime configuration. | - |
Assign the least role each user or integration needs. In particular, give automation (Terraform, CI) a dedicated user rather than reusing a person’s admin account.
Create and manage users
Section titled “Create and manage users”Use the Users page in the UI, or the API (admin role required):

# Create an editor user (password must be at least 16 characters)curl -sk -X POST https://dtm.internal:8443/api/v1/users \ -H "Authorization: Bearer $DTM_TOKEN" \ -H "X-DTM-CSRF: 1" \ -H "Content-Type: application/json" \ -d '{"username": "alice", "password": "long-enough-password-1234", "role": "editor"}'
# Change a user's role, enable/disable, or reset passwordcurl -sk -X PUT https://dtm.internal:8443/api/v1/users/<id> \ -H "Authorization: Bearer $DTM_TOKEN" \ -H "X-DTM-CSRF: 1" \ -H "Content-Type: application/json" \ -d '{"role": "readonly", "enabled": true}'Passwords must be at least 16 characters. Disabling a user ("enabled": false)
blocks sign-in without deleting the account.
Two server-side guards keep an organisation from locking itself out, enforced on the API and reflected in the UI:
- You cannot delete your own account (
400); have another admin do it. The UI simply omits Delete on your own row. - The last enabled admin cannot be deleted, disabled, or demoted. The guard counts only enabled admins, so you cannot disable your way to zero either. Add a second admin first.
Teams that manage DTM as code
can declare users with the dtm_user Terraform resource instead, with a
write-only password that never enters state; see
users and SSO as code.
Tokens
Section titled “Tokens”The API and Terraform authenticate with a JWT bearer token from
POST /api/v1/auth/login. Tokens are valid for 24 hours; refresh them in
long-running automation. See the API overview.
Single sign-on
Section titled “Single sign-on”For centrally-managed identities, configure Entra ID single sign-on. With SSO, users sign in with their Microsoft account and their DTM role is derived from an app role you assign in Entra.
Auditing
Section titled “Auditing”Every change is recorded in the audit log, queryable from the Audit Log page or
GET /api/v1/audit (readable by editor and admin). Filter by user, resource,
action, or a date range (From / Until in the UI; from / to on the
API) to review who changed what; the NDJSON export honours the same filters.
Audit log retention
Section titled “Audit log retention”The stored audit log is bounded, not permanent: by default it keeps the most recent 10,000 entries, pruning oldest-first (on a write-heavy cluster that can amount to only hours of history). Two server-configuration settings control the window:
observability: audit_max_entries: 200000 # count cap; oldest entries dropped first audit_retention: '2160h' # optional time cap (Go duration; 2160h = 90 days)If your compliance regime needs a defined retention (SOC 2, PCI, internal IR
policy), raise the cap and set a time-based retention like the 90-day example
above, and alert when the log approaches its cap: the dtm_audit_entries
metric is the live count, so alerting when it exceeds 90% of your configured
cap gives warning before pruning clips evidence. For retention beyond the
stored window, schedule GET /api/v1/audit/export (NDJSON, filterable, same
editor/admin readability) to immutable storage; see the
audit log API.
With Entra ID SSO enabled, Entra sign-ins appear here as
their own accounts (usernames prefixed entra:, no local password), fully
separate from local accounts even when the names look alike; see
how SSO and local accounts coexist.