Skip to content

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.

Use the Users page in the UI, or the API (admin role required):

The Users page, listing each user with role, source, enabled state and last login, with add, edit and delete actions and a change-password form that notes the 16 character minimum

Terminal window
# 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 password
curl -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.

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.

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.

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.

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.