Open source & community driven

DNS administration for PowerDNS,
built for teams.

A modern, self-hosted admin UI for PowerDNS Authoritative - first-class RBAC, OIDC single sign-on, multi-backend management, diff-before-apply zone editing, and an append-only audit log. One Docker image. No telemetry. No CDN.

MIT licensed SQLite or Postgres SSO & MFA DNSSEC
demo.powerdns-authadmin.org
PowerDNS-AuthAdmin dashboard PowerDNS-AuthAdmin dashboard
~60permissioned actions
5+system & custom roles
4.6 → 5.0PowerDNS versions tested
1self-contained image
Features

Everything you need to run authoritative DNS

Designed for teams that actually operate multi-backend infrastructure.

🛡️

Real RBAC

Five system roles plus org-defined custom roles. ~60 actions across zones, records, DNSSEC, TSIG, users, and tokens - scoped to global, team, zone, or server.

🔑

SSO & MFA

Local accounts with Argon2id, generic OIDC with PKCE and group→role mapping, TOTP MFA, and scoped pda_pat_ API tokens. RP-initiated logout signs out at the IdP.

🗂️

Multi-backend

One install fronts standalone primaries, primary + secondary groups, and multi-primary clusters. Zones merge into one searchable, amalgamated list.

📝

Diff-before-apply

A per-RRset editor with per-type validators and optimistic concurrency. Every change is previewed as a BIND-style before / after diff before it's written.

🔐

DNSSEC & TSIG

Cryptokey create / update / delete with per-key activity from the audit log. Manage TSIG keys and autoprimary registrations, with reveal split into its own permission.

🧾

Append-only audit

Every write logged with redacted before/after snapshots, a per-row PDNS HTTP trail, per-zone history, and operator-driven CSV export.

🔄

Cluster & sync

NOTIFY-aware sync probes compare every secondary's serial against the primary, record-for-record on demand - the same UI shape for replicated clusters.

📊

Observability

Pino structured logs (secret-redacted), Prometheus /metrics, /healthz liveness, and /readyz readiness gated on DB + migration version.

📦

Provision on boot

A single provisioning.yaml applied on first boot brings up settings, roles, teams, templates, backends, demo zones, and OIDC providers - zero clicks.

A closer look

Clean, fast, and mobile-first

Every page reflows cleanly down to a phone viewport. Toggle the theme above - the shots follow.

Amalgamated zones list Amalgamated zones list
Amalgamated zones - every backend's zones in one searchable list with serial and per-row sync state.
Diff before apply Diff before apply
Diff-before-apply - review every change as a BIND-style diff.
Audit log Audit log
Audit log - append-only, redacted snapshots, CSV export.
Backend health Backend health
Backend health - advisories for unreachable hosts and replication drift.
Roles and RBAC Roles and RBAC
RBAC roles - system and custom roles across ~60 actions.
Quickstart

Deploy with Docker Compose

Ships as a single image - ghcr.io/powerdns-authadmin/powerdns-authadmin. Runs on SQLite or Postgres; migrations and the role seed run automatically on boot.

# Minimal production stack - SQLite, single instance
services:
  app:
    image: ghcr.io/powerdns-authadmin/powerdns-authadmin:latest
    restart: unless-stopped
    ports: ["3000:3000"]
    environment:
      # Exact public URL the browser uses - scheme + host must match
      APP_URL: https://dns.example.com
      DATABASE_URL: file:/data/powerdns_authadmin.db
      # Generate once into .env, back up, never change them
      APP_SECRET_KEY: ${APP_SECRET_KEY}
      APP_ENCRYPTION_KEY: ${APP_ENCRYPTION_KEY}
      # First admin account, created on first boot
      BOOTSTRAP_ADMIN_EMAIL: admin@example.com
      BOOTSTRAP_ADMIN_PASSWORD: ${BOOTSTRAP_ADMIN_PASSWORD}
      # Optional: replication-aware sync UI (default false)
      PDNS_BACKGROUND_POLLING: "false"
      # Optional: apply provisioning.yaml once on first boot
      PROVISION_ON_BOOT: "true"
      PROVISIONING_FILE: /etc/pda/provisioning.yaml
      # ── Outbound-URL guards (opt-in, off by default) ──
      # Enable when PowerDNS / your IdP are on a private
      # network or speak http:// (e.g. in-compose PowerDNS):
      #   *_PRIVATE_NETWORKS  allow loopback / RFC1918 / ULA
      #   *_INSECURE_HTTP     allow http:// instead of https://
      #   WEBAUTHN_*_ORIGINS  passkeys over http:// (LAN dev)
      #   LDAP_*_PORT_389     plain LDAP on :389 (trusted LAN)
      # APP_PDNS_ALLOW_PRIVATE_NETWORKS: "true"
      # APP_PDNS_ALLOW_INSECURE_HTTP: "true"
      # APP_OIDC_ALLOW_PRIVATE_NETWORKS: "true"
      # APP_OIDC_ALLOW_INSECURE_HTTP: "true"
      # WEBAUTHN_ALLOW_INSECURE_ORIGINS: "true"
      # LDAP_ALLOW_INSECURE_PORT_389: "true"
    volumes:
      - app-data:/data
      - ./provisioning.yaml:/etc/pda/provisioning.yaml:ro
volumes:
  app-data:

Bring it up

  1. Generate secrets into a persistent .env next to the file:
    openssl rand -base64 32APP_SECRET_KEY & APP_ENCRYPTION_KEY.
  2. Set APP_URL to the real URL the browser uses, and your BOOTSTRAP_ADMIN_* values.
  3. Start it: docker compose up -d → first login with the bootstrap admin.
  4. Optional: drop a provisioning.yaml (second tab) to register backends, roles, and teams on first boot - zero clicks.

Flip PDNS_BACKGROUND_POLLING to "true" for primary/secondary or cluster topologies - it enables the live sync state, drift advisories, and the dashboard PowerDNS-metrics tab. Off by default for standalone installs.

Postgres + Redis is the path for HA (replicas > 1) - see the installation guide. Just evaluating? Spin up the live demo instead.

Community driven

Built in the open. Run it your way.

PowerDNS-AuthAdmin is MIT-licensed and developed in public. Star the repo, open an issue, file a feature request, or send a pull request - contributions of every size are welcome. There's no SaaS lock-in and no telemetry phone-home.