Getting Started

ZoneRails is a self-hosted server for managing DNS records across Cloudflare and Active Directory DNS, used from your browser. Install ZoneRails Server on Linux, Docker, or Windows, open http://your-server:3000, and sign in.

First Steps

  1. Sign in with the default admin account and change the password immediately.
  2. Open the 04 // ADMIN tab → Connections and add your first DNS provider connection (Cloudflare API token or AD DNS server). The first connection becomes active automatically and zones load right away.
  3. Add user accounts and assign roles under Admin → Users.
  4. Optionally register for a free Server Professional license to unlock every feature for 5 named seats.

Desktop app: the macOS/Windows desktop application is being sunset in favor of ZoneRails Server. Existing desktop installs keep working (including connecting to a server), but new setups should start with the server.

Cloudflare API Token

Create a scoped API token at dash.cloudflare.com → My Profile → API Tokens → Create Token.

Required Permissions

PermissionAccessPurpose
ZoneReadList zones
DNSRead + EditManage DNS records

Tip: Set the Zone Resources to "All zones" or specific zones you want to manage. Scoped tokens are more secure than Global API Keys.

Active Directory DNS

Connect to Windows DNS servers via WinRM (Windows Remote Management).

FieldExampleNotes
LabelDC01 — Corp DNSDisplay name for the connection
Server Addressdc01.corp.localDNS server hostname or IP
Port5986WinRM HTTPS port (default)
HTTPSCheckedUse TLS for WinRM
UsernameDOMAIN\adminDomain credentials
Password••••••Domain password

Prerequisite: WinRM must be enabled on the DNS server. Run winrm quickconfig on the server if not configured.

AD DNS Zone Delegations

A zone delegation carves a subdomain out of a parent AD DNS zone and points it at a separate set of nameservers — commonly used to hand off a child zone (e.g. dev.example.com) to a different team, external provider, or DNS appliance while keeping the parent zone authoritative.

ZoneRails exposes the full delegation lifecycle for AD DNS connections:

  • List — see all delegations in a selected parent zone, with their nameservers and glue IPs.
  • Create — add a child delegation with one or more nameservers; optional glue IPs are required when a nameserver is in-bailiwick (its hostname ends with the delegated child zone).
  • Delete — remove a delegation with a confirmation prompt; the NS records and glue records in the parent zone are removed together.

How to use

  1. Switch to an AD DNS connection (the Delegations button on the DNS tab is only visible for AD DNS).
  2. Click Delegations and select the parent zone from the dropdown.
  3. Click New Delegation — enter the child name (e.g. dev becomes dev.example.com), add one or more nameservers, and optionally set glue IPs and a TTL. Click Create Delegation.
  4. Existing delegations appear in the list with a Delete action.

Under the hood

ZoneRails issues the standard Windows DNS PowerShell cmdlets over WinRM:

  • Add-DnsServerZoneDelegation -ZoneName <parent> -Name <child> -NameServer <ns,...> [-IPAddress <ip,...>]
  • Get-DnsServerZoneDelegation -Name <parent>
  • Remove-DnsServerZoneDelegation -ZoneName <parent> -Name <child> -Force

Works in both standalone mode (desktop → AD DNS directly via WinRM) and server-connected mode (desktop → ZoneRails Server → AD DNS). Audit entries land in the Activity Log with record type DELEGATION.

Cloudflare note: The Delegations UI is hidden for Cloudflare connections. To delegate a subdomain on Cloudflare, create NS records in the parent zone via the regular record editor.

Connect to ZoneRails Server

If your organization runs a ZoneRails Server, connect to it for shared DNS management, RBAC, and scheduled deployments.

FieldExample
Server URLhttps://zonerails.corp.local:3000
UsernameYour AD username or local account
PasswordYour password

Click Test to verify connectivity before connecting. The app will auto-reconnect on subsequent launches.

Edit / Create / Delete

The Edit tab opens when you double-click a search result or click the NEW row to create a record.

Creating a Record

  1. Search for the record name in Tab 1
  2. If it doesn't exist, double-click the NEW row
  3. Select the record type, fill in content and other fields
  4. Click Create Record

Editing a Record

  1. Search for the record in Tab 1
  2. Double-click the record row
  3. Modify the fields you want to change
  4. Click Update Record

Deleting a Record

  1. Open the record for editing (double-click from search)
  2. Click Delete Record
  3. Confirm the deletion

AD DNS-Specific Behavior

  • The Proxy status toggle is hidden for AD DNS zones (AD DNS doesn't support Cloudflare proxying)
  • The TTL defaults to 300 seconds (5 minutes) instead of Auto
  • A Create Delegation Instead button appears in the form footer — click it to create a zone delegation rather than a record
  • Advanced record types (HTTPS, SVCB, TLSA, etc.) are not supported for AD DNS

Note: All changes are logged in the Activity Log with before/after snapshots and can be rolled back.

Deployments

Deployments let you batch multiple DNS changes together and execute them as a single operation. This is safer than making changes one at a time.

Creating a Deployment

  1. Go to the Deploy tab and click New Deployment
  2. Give it a name and optional ticket number
  3. Click Search to Add to find records
  4. Double-click a record to add an edit or delete, or click the NEW row to add a create
  5. Repeat for all changes needed

Executing a Deployment

  1. Review all items in the deployment
  2. Click Deploy Now
  3. Confirm the changes in the dialog
  4. Watch the progress view for per-item results
  5. DNS verification runs automatically after deployment

Scheduling a Deployment

Click Schedule instead of Deploy Now. Pick a date and time; the server executes it automatically — no browser or laptop needs to be open. At fire time the server re-checks that the scheduling user still exists, is enabled, and still holds deploy:execute; if not, the deployment fails closed with the reason recorded in its results and the audit log.

Pre-Flight Validation

Click Validate before deploying to run 8 checks per item without making any changes:

  1. Connection — can we reach the provider?
  2. Zone accessible — does the target zone exist?
  3. Record exists (update/delete) — is the record still there?
  4. Drift detection (update/delete) — has it been modified since the snapshot?
  5. Content validation (create/update) — will the provider accept these values?
  6. CNAME conflicts (create) — incompatible record type at the same name?
  7. Duplicate detection (create) — does this record already exist?
  8. Snapshot completeness (update/delete) — will rollback be possible?

Results show per-item pass/warning/error. Click items with issues to expand detailed check results. Fix any errors before deploying.

Real-Time Progress

During execution, the progress bar advances in three phases:

  • 0–50% — Execution: each item's Status cell flips from Pending to Success/Failed in real-time
  • 50–60% — Status review: a 3-second pause so you can read the results before verification begins
  • 60–100% — Verification: DNS propagation checked per item (6 attempts, 10 seconds apart)

Viewing Results

Click any deployed, failed, partial, or rolled-back deployment in the list to see the results view with per-item status and DNS verification results. Click Verify DNS to re-check propagation.

Deployment Rollback

Click Rollback Deployment on any deployed or partial deployment to reverse all successful changes. The impact modal shows:

  • Per-item risk assessment: Safe, Modified (record changed since deployment), or No snapshot (item will be skipped)
  • Downstream deployments that later modified the same records
  • Click any risk badge to expand details showing before/current/deployed state

Rollback reverses items in reverse order (last change undone first) with a full audit trail. The deployment status changes to ROLLED BACK or PARTIAL ROLLBACK if some items fail.

Duplicate Prevention

Records already in the current deployment show an In Deployment badge in the deploy search results. Attempting to add the same record (name + type) twice is blocked with an error message. Records in other active deployments show In Draft or Scheduled badges and cannot be added.

Deployment Statuses

StatusMeaning
DRAFTChanges planned but not yet executed
SCHEDULEDScheduled to execute at a specific time
DEPLOYINGCurrently executing changes
DEPLOYEDAll changes applied successfully
FAILEDNo changes applied — all failed
PARTIALSome changes succeeded, some failed
CANCELLEDUser cancelled before execution
ROLLED BACKAll successful changes reversed
PARTIAL ROLLBACKSome changes reversed, some rollback items failed

Connectors & Tunnels

The Connectors tab manages Cloudflare Tunnels, ingress rules, private network routes, and virtual networks.

Tunnels

View, create, and delete Cloudflare Tunnels. Each tunnel shows its health status, number of active connectors, and creation date. Click a tunnel to view its token and connector details.

Ingress Rules (Config)

Configure which hostnames route to which backend services through a tunnel. Each rule maps a hostname + optional path to a service URL.

FieldExample
Hostnameapp.example.com
Servicehttp://127.0.0.1:8080
Path (optional)^/api/.*$

Routes

Create routes to private networks via tunnels. Routes map CIDR blocks to tunnels and virtual networks.

Virtual Networks

Create and manage virtual networks (VNets) for organizing private network routes.

Activity Log

Every DNS change is logged with a full audit trail including before/after snapshots, the user who made the change, and a timestamp.

Filtering

  • Action Type — All, Create, Update, Delete
  • Search — Filter by record name

Rollback

Click the rollback button on any audit entry to restore the record to its previous state. The rollback itself is also logged in the activity log.

Export

Click Export to download the full audit log as a JSON file for compliance or archival.

Settings

Click the gear icon in the title bar to open the Settings drawer.

Connections

Provider connections are managed centrally by administrators in Admin → Connections (see Admin Dashboard) and shared with all users. Credentials are write-only in the UI and encrypted at rest.

Cache & Refresh

  • Cache TTL — How long zone/record data is cached locally (default: 5 minutes)
  • Auto-refresh — Toggle automatic data reload on a timer
  • Interval — Auto-refresh interval in minutes

License

Enter a server license key to unlock all features (see Licensing & Seats). An unregistered server runs the Standard feature set — one zone, one connection.

Data & Privacy

Clear All Data removes all stored tokens, audit logs, DNS cache, and settings from the device.

ZoneOps: Record Protection

Mark critical DNS records as protected to prevent accidental modification or deletion. When editing a protected record, a confirmation dialog appears before any change is applied.

Toggle protection using the shield icon in the edit form footer.

ZoneOps: Conflict Detection

Before creating or updating a record, ZoneRails checks for conflicts:

  • CNAME conflicts — CNAME records cannot coexist with other record types at the same name
  • Duplicate detection — Warns about duplicate name + type combinations
  • MX validation — Warns if an MX record points to an IP address instead of a hostname

ZoneOps: Drift Detection

When editing a record, ZoneRails compares the loaded state against the current live state. If someone else changed the record since you loaded it, a drift warning appears so you don't accidentally overwrite their changes.

ZoneOps: Propagation Verification

After deploying DNS changes, ZoneRails verifies each item — and "Verified" means the DNS system actually serves what you deployed, not merely that the API accepted it:

  • Cloudflare — two-stage: an API read-back confirms the configured record (name, type, and content), and a live DNS-over-HTTPS query (1.1.1.1) confirms what actually resolves, content-matched per record type (MX priority prefixes, SRV targets, TXT quoting, and trailing dots are normalized). Proxied records are content-checked via the API and resolution-checked via DNS (they serve Cloudflare edge addresses); proxied CNAMEs are queried as A records since Cloudflare flattens them.
  • Deletes — verified as absence: the deleted content must no longer appear in the API or in live DNS. Sibling records at the same name and type (common for TXT) don't block it.
  • AD DNS — queried against the connection's own domain controller (not the app host's resolver), so internal-only zones verify correctly. NXDOMAIN/no-data counts as absence for deletes.

Verification runs automatically after deployment (6 attempts over ~60 seconds, converging as propagation completes) and can be re-run any time with the Verify DNS button. Advanced record types (HTTPS, LOC, NAPTR, …) are auto-verified from the API response, since their DNS answer formats aren't comparable.

ZoneOps: Tunnel Guardrails

ZoneRails monitors your Cloudflare Tunnel DNS records for issues:

  • Orphaned records — DNS records pointing to tunnels that no longer exist
  • Dangling routes — Tunnel DNS records with no matching ingress rule
  • Health mapping — Shows tunnel health status on DNS records in search results

Orphan alerts appear in the status bar. Click to view and clean up affected records.

ZoneRails Server: Installation

ZoneRails Server is a self-hosted Node.js backend for enterprise teams. It requires Node.js 18+ and runs on Linux, Docker, or Windows.

Linux (systemd)

sudo ./install/install-linux.sh

This installs to /opt/zonerails-server, creates a zonerails user, and registers a systemd service.

systemctl status zonerails-server
systemctl restart zonerails-server
journalctl -u zonerails-server -f

Docker

docker-compose up -d

Volumes: /var/lib/zonerails (database), /var/log/zonerails (logs).

Windows

Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
.\install\install-windows.ps1

Installs as a Windows Service at C:\ZoneRails-Server.

First Run

On first startup, the server:

  1. Generates JWT secret and encryption key (saved to config.json)
  2. Runs database migrations
  3. Creates default roles (Admin, Operator, Deployer, Planner, Viewer)
  4. Creates a local admin account (default: admin / admin)

Change the default admin password immediately via the web UI at http://server:3000.

ZoneRails Server: Configuration

Configuration is stored in config.json in the server directory. All settings can be overridden with environment variables.

{
  "port": 3000,
  "host": "0.0.0.0",
  "database": {
    "type": "sqlite",
    "path": "./data/zonerails.db"
  },
  "auth": {
    "type": "local",
    "jwt": {
      "expiresIn": "1h",
      "refreshExpiresIn": "7d"
    }
  },
  "cache": {
    "enabled": true,
    "refreshIntervalMinutes": 10
  },
  "websocket": {
    "enabled": true,
    "heartbeatIntervalMs": 30000
  },
  "scheduler": {
    "enabled": true
  }
}

Environment Variables

VariableDefaultDescription
ZR_PORT3000Server port
ZR_HOST0.0.0.0Bind address
ZR_DB_PATH./data/zonerails.dbDatabase file path
ZR_AUTH_TYPElocallocal or active-directory
ZR_JWT_SECRET(auto-generated)JWT signing secret
ZR_ADMIN_PASSadminDefault admin password
ZR_CACHE_INTERVAL10Cache refresh interval (minutes)
ZR_LDAP_URLLDAP server URL
ZR_LDAP_BASE_DNLDAP base DN

ZoneRails Server: Active Directory

Set auth.type to "active-directory" in config.json to enable AD authentication. Local accounts still work alongside AD (hybrid auth).

{
  "auth": {
    "type": "active-directory",
    "ldap": {
      "url": "ldap://dc01.corp.local:389",
      "baseDN": "DC=corp,DC=local",
      "bindDN": "CN=svc-zonerails,OU=Service,DC=corp,DC=local",
      "bindPassword": "ServiceAccountPassword",
      "userSearchFilter": "(sAMAccountName={{username}})",
      "groupSearchBase": "OU=Groups,DC=corp,DC=local",
      "tlsOptions": { "rejectUnauthorized": false }
    }
  }
}

How AD Login Works

  1. User enters AD credentials
  2. Server binds to LDAP with service account
  3. Searches for user by sAMAccountName
  4. Re-binds as the user to verify password
  5. Extracts group memberships from memberOf
  6. Maps AD groups to ZoneRails roles (configured in admin UI)
  7. Issues JWT with roles and permissions

If no AD groups are mapped, the user gets the Viewer role by default.

ZoneRails Server: Roles & Permissions

System Roles

RoleWhat it can doPermissions
AdminEverything*
OperatorDirect record writes, full deployment lifecycle, audit rollback, connection managementdns:read/create/update/delete, deploy:read/create/execute/schedule/cancel/delete, audit:read/rollback, connections:read/manage
DeployerPlan and execute deployments; records change only through the guardrailed pipelinedns:read, deploy:read/create/execute/schedule/cancel, audit:read, connections:read
PlannerDraft and validate deployments — can never execute, schedule, or delete themdns:read, deploy:read/create
ViewerRead-onlydns:read, deploy:read, audit:read, connections:read

Admins can create custom roles from the full permission catalog in the role editor — every permission is presented with a label and description, grouped by namespace (dns, deploy, audit, connections, admin), including the four admin:* permissions for delegating user, role, settings, or maintenance duties without granting full access. Permission format: namespace:action; namespace wildcards (dns:*) and the global * are supported.

The UI hides controls a role cannot use, the API enforces every permission server-side, and scheduled deployments re-check the scheduling user's deploy:execute at fire time.

ZoneRails Server: Admin Dashboard

Administration lives in the 04 // ADMIN tab of the web app. The tab appears only for users holding an admin permission, and each section is gated individually — a delegated "User Manager" role sees only Users.

Sections

  • Users (admin:users) — Create local users, enable/disable accounts, reset passwords, assign roles, delete users. A live seat banner shows named-seat usage (e.g. Seats: 3 of 5 used); creating a user beyond the licensed seat count is refused with a clear notice.
  • Roles (admin:roles) — View system roles, build custom roles from the grouped, labeled permission catalog.
  • AD Groups (admin:roles) — Map Active Directory groups to ZoneRails roles for automatic role assignment on login. Degrades gracefully with a notice when LDAP auth isn't configured.
  • Connections (connections:manage) — Add, edit, test, and delete shared DNS provider connections (Cloudflare API tokens, AD DNS servers). Secrets are write-only in the UI and encrypted at rest; the Test button saves first, then verifies against the provider. The first connection you add becomes the active one automatically.

The server license is managed in the Settings drawer (gear icon) — see Licensing & Seats.

ZoneRails Server: Licensing & Seats

An unregistered server runs the Standard feature set: one zone, one provider connection, full record CRUD and the deployment pipeline, with RBAC and the Admin tab included. Registering upgrades it to Server Professional — free, and it unlocks every feature for 5 named user seats.

  1. Open the Settings drawer (gear icon) → License and click Request one, or go directly to register.getzonerails.com/license/zrsv from the link the app generates (it carries your server's fingerprint).
  2. Enter your email and accept the Terms of Service, Privacy Policy, and EULA — acceptance is required and recorded with the license.
  3. Your license key arrives by email; paste it into Settings → License and click Activate. The license validates against the licensing service and unlocks immediately.

Named seats

  • A seat is an enabled user account on your server — not a device and not a concurrent session. Seated users can sign in from any browser.
  • Seat limits are enforced when an account is created or re-enabled; disabling or deleting an account frees its seat instantly.
  • The Admin → Users seat banner always shows current usage. The server's licensing heartbeat reports only the count of enabled accounts — never usernames or emails.
  • Need more than 5 seats? Contact us about Server Enterprise.

A server keeps working through temporary licensing-service outages: the last successful validation is cached with a 72-hour grace window.

ZoneRails Server: REST API

The server exposes a full REST API. All endpoints (except /api/auth and /api/health) require a JWT token in the Authorization: Bearer header.

Key Endpoints

MethodEndpointDescription
POST/api/auth/loginAuthenticate and get JWT
GET/api/dns/cached/allGet all cached zones and records
POST/api/dns/recordsCreate a DNS record
PUT/api/dns/records/:idUpdate a DNS record
DELETE/api/dns/records/:idDelete a DNS record
GET/api/deploymentsList deployments
POST/api/deployments/:id/executeExecute a deployment
POST/api/deployments/:id/verifyVerify DNS propagation
POST/api/deployments/:id/validatePre-flight validation (8 checks per item)
GET/api/deployments/:id/rollback-impactRollback impact analysis
POST/api/deployments/:id/rollbackExecute deployment rollback
GET/api/auditGet audit log entries
POST/api/audit/:id/rollbackRollback a change
GET/api/admin/usersList users (admin only)
GET/api/admin/permissionsPermission catalog for the role editor
POST/api/deployments/:id/scheduleSchedule a draft deployment
GET/api/healthServer health check

WebSocket endpoint: ws://server:3000/ws?token=JWT for real-time events.

Record Types Reference

ZoneRails supports every DNS record type that Cloudflare's API exposes — from the nine common types with dedicated form fields down to the full set of RFC-defined advanced types via a structured-data editor.

Common types

TypeContentExtra FieldsProxyable
AIPv4 addressYes
AAAAIPv6 addressYes
CNAMETarget hostnameYes
MXMail server hostnamePriority (0–65535)No
TXTText contentNo
NSNameserver hostnameNo
SRVTarget hostnamePriority, Weight, PortNo
CAA(assembled from fields)Flags, Tag, CA DomainNo
PTRDomain nameNo

Advanced types (RFC-defined, structured-data editor)

TypePurposeData FieldsProxyable
CERTCertificate storage (RFC 4398)type, key_tag, algorithm, certificateNo
DNSKEYDNSSEC public key (RFC 4034)flags, protocol, algorithm, public_keyNo
DSDelegation signer (RFC 4034)key_tag, algorithm, digest_type, digestNo
HTTPSHTTPS service binding (RFC 9460)priority, target, value (SvcParams)No
LOCGeographic location (RFC 1876)lat/long degrees, minutes, seconds, direction, altitude, size, precisionNo
NAPTRNaming authority pointer (RFC 3403)order, preference, flags, service, regex, replacementNo
OPENPGPKEYOpenPGP public key (RFC 7929)content (base64)No
SMIMEAS/MIME cert association (RFC 8162)usage, selector, matching_type, certificateNo
SSHFPSSH host key fingerprint (RFC 4255)algorithm, type, fingerprintNo
SVCBService binding (RFC 9460)priority, target, value (SvcParams)No
TLSATLS cert association / DANE (RFC 6698)usage, selector, matching_type, certificateNo
URIURI resource identifier (RFC 7553)priority, weight, targetNo

About advanced types

Advanced record types use Cloudflare's structured data object (one field per column above) rather than a single content string. ZoneRails's advanced editor renders one input per subfield, with a collapsible Edit as JSON escape hatch for power users who'd rather paste a full payload.

Validation is strict on presence and numeric ranges (all required fields must be populated; integer fields are range-checked), but format-level validation of certificate blobs, public keys, fingerprints, SvcParams, and NAPTR regex is delegated to Cloudflare's API — bad inputs surface through the standard error dialog. DNS-over-HTTPS propagation verification is skipped for advanced types, since record equality over DoH text-match isn't reliable.

Advanced types are Cloudflare-only. Active Directory DNS connections will reject any advanced type with a clear error message.

Badge Reference

BadgeWhereMeaning
CFSearch resultsCloudflare provider
ADSearch resultsActive Directory DNS
In DraftRecord nameRecord is in a draft deployment
Scheduled Apr 15Record nameRecord scheduled for deployment
TunnelRecord nameTunnel healthy
No routeRecord nameTunnel exists but no ingress rule matches
ORPHANRecord nameTunnel no longer exists
ACTIVESettingsCurrently selected connection

Deployment Statuses

StatusColorDescription
DraftGrayChanges planned, not yet executed
ScheduledBlueWaiting for scheduled execution time
DeployingAmberCurrently executing changes
DeployedGreenAll changes applied successfully
PartialOrangeSome succeeded, some failed
FailedRedAll changes failed
CancelledGrayCancelled by user before execution
Rolling BackRedRollback in progress
Rolled BackGrayAll successful changes reversed
Partial RollbackOrangeSome items reversed, some rollback failed

Keyboard Shortcuts

KeyAction
Enter in searchExecute search
Enter in token setupSave token
Enter in license fieldActivate license
Double-click search resultOpen record for editing
Double-click deploy search resultAdd record to deployment

ZoneRails v1.0.2 · © 2026 A Holdings Company LLC · Back to homepage