Getting Started

Netra is a multi-provider DNS management platform with approval workflows, drift detection, and full audit logging. This guide will get you from zero to running in minutes.

Prerequisites

  • A container runtime (Docker, Kubernetes, ECS, or any OCI-compatible platform)
  • A persistent volume or directory for the data store
  • Network access to your DNS providers (Windows DNS servers, AWS, GCP, or Azure APIs)

Quick Start

# Clone the repository
git clone https://github.com/your-org/netra.git
cd netra

# Copy and configure environment
cp .env.example .env
# Edit .env — set APP_SECRET, passwords, and APP_URL

# Build and launch
docker compose build
docker compose up -d

# Access the UI
open http://localhost:8089

Default Credentials

RoleUsernamePasswordAccess Level
AdminadminadminFull system access
ApproverapproverapproverSubmit + approve/reject
UseruseruserSubmit requests only

Change these immediately after first login via Settings → Credentials.

First-Run Setup Wizard

On first login as admin, the dashboard displays a guided checklist that walks you through:

  1. Changing default passwords
  2. Connecting your first DNS provider
  3. Configuring notification channels
  4. Setting up SSO (optional)
  5. Importing existing zones

Deployment

Netra ships as a container image and can run anywhere containers are supported.

Docker Compose

The simplest deployment method. The included docker-compose.yml defines the Netra app and its companion sidecar service.

# Production deployment with Traefik
docker compose build
docker compose up -d

Key environment variables:

VariableDescriptionRequired
APP_SECRETEncryption key for tokens and credentials. Generate with openssl rand -hex 32Yes
APP_URLPublic URL for notification links (e.g. https://netra.company.com)Yes
ADMIN_USER / ADMIN_PASSInitial admin credentialsYes
TZTimezone (e.g. America/Los_Angeles)No

Kubernetes

Deploy Netra as a Deployment with a PersistentVolumeClaim for the /data directory.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: netra
spec:
  replicas: 1
  selector:
    matchLabels:
      app: netra
  template:
    spec:
      containers:
      - name: netra
        image: your-registry/netra:latest
        ports:
        - containerPort: 3000
        livenessProbe:
          httpGet:
            path: /api/health/live
            port: 3000
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /api/health/ready
            port: 3000
          periodSeconds: 5
          failureThreshold: 3
        volumeMounts:
        - name: data
          mountPath: /data
        env:
        - name: APP_SECRET
          valueFrom:
            secretKeyRef:
              name: netra-secrets
              key: app-secret
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: netra-data

AWS ECS

Run as a Fargate or EC2 task. Mount an EFS volume for the data directory. Use an ALB target group with the /api/health/ready endpoint for health checks.

Health Checks

Netra exposes three health endpoints for different orchestration needs:

EndpointPurposeChecksUse for
/api/healthGeneral statusIn-memory onlyStatus pages, dashboard widgets
/api/health/liveLiveness probeEvent loop responsivek8s livenessProbe — restart if dead
/api/health/readyReadiness probeDB connectivityk8s readinessProbe, Docker healthcheck — stop routing if unhealthy

All three support GET and HEAD methods. The Docker Compose healthcheck uses /api/health/ready by default.

Every response includes an X-Request-Id header for log correlation — useful for tracing errors reported by users back to server logs.

Reverse Proxy

Netra runs on port 3000 internally. Place it behind any reverse proxy (Traefik, nginx, Caddy, ALB) for TLS termination. The included docker-compose.yml has Traefik labels pre-configured.

DNS Providers

Netra supports four DNS providers. You can connect any number of each type and assign domains to specific providers.

Windows DNS

Connects to Windows Server 2016–2025 DNS via a companion sidecar service. Supports:

  • Multiple domain controllers with automatic failover
  • All standard record types (A, AAAA, CNAME, MX, TXT, SRV, NS, PTR)
  • Zone transfers and full zone import
  • Credentials encrypted at rest

AWS Route 53

Native integration via AWS APIs. Configure with IAM access keys or instance role credentials.

  • Hosted zone discovery and record management
  • Alias record support
  • Health check association

Google Cloud DNS

Connects via service account credentials (JSON key file).

  • Managed zone support
  • DNSSEC-enabled zones
  • Change batching for performance

Azure DNS

Connects via App Registration (client ID, client secret, tenant ID).

  • Public and private DNS zones
  • Record set management
  • Subscription and resource group scoping

Cloudflare

Connects via a scoped API token. No SDK required — native HTTPS API calls.

  • Zone-scoped API tokens (principle of least privilege)
  • Full record management (A, AAAA, CNAME, MX, TXT, SRV)
  • Zone ID-based targeting
  • Token encrypted at rest

Adding a Provider

  1. Navigate to Settings → DNS Providers
  2. Click "Add Provider" and select the type
  3. Enter connection credentials
  4. Test the connection
  5. Assign domains to the provider

Approval Workflow

Netra's approval system ensures no DNS change reaches production without review.

How It Works

  1. Submit — Any user creates a DNS change request
  2. Review — An approver or admin reviews the request
  3. Apply — Once approved, the change is executed against the DNS provider

Two-Person Rule

The submitter cannot approve their own request — even if they are an admin. This prevents unreviewed changes from reaching production.

Bypass Review

In emergencies, approvers and admins can bypass the two-person rule. This requires checking a confirmation box and is prominently logged in the audit trail with a [Bypass] flag.

Bulk Approve

Select multiple pending requests with checkboxes and approve or reject them in a single action. The two-person rule still applies to each individual request.

One-Click Approve/Reject

Notification messages (Slack, Teams, Discord, email) include action buttons that approve or reject directly — no need to open the UI.

Disabling Approval

For dev/test environments, approval can be disabled in Settings → Approval Workflow. When disabled, all requests are applied immediately. A warning banner is shown in the UI.

SSO Configuration

Netra supports single sign-on via OAuth 2.0 / OpenID Connect.

Supported Providers

  • Okta — Full OIDC with AD group-based role mapping
  • Microsoft Entra ID — OIDC with group Object ID mapping
  • Generic OIDC — Works with Keycloak, Auth0, PingFederate, Authentik, and others

Role Mapping

Map your identity provider groups to Netra's three roles:

Netra RolePermissions
AdminFull access — settings, providers, audit, drift, approve, submit
ApproverSubmit requests + approve/reject others' requests
UserSubmit requests only

Setup Steps

  1. Create an application in your identity provider
  2. Set the redirect URI to https://your-netra-url/auth/sso/callback
  3. In Netra, go to Settings → SSO
  4. Select your provider (Okta, Microsoft, or Generic OIDC)
  5. Enter Client ID, Client Secret, and domain/issuer
  6. Map group names/IDs to Netra roles
  7. Enable SSO — the login page will show "Sign in with [Provider]" as the primary action

Note: Local login and LDAP remain available as fallback via the "Sign in with password" link on the login page.

Notifications

Get notified when requests are submitted, approved, rejected, or applied.

Channels

  • Slack — Incoming webhook with approve/reject buttons
  • Microsoft Teams — Adaptive card with action buttons
  • Discord — Webhook with embedded message
  • Email — HTML email via SMTP with one-click action links

Requester Notifications

When a request is approved, rejected, or fails to apply, the person who submitted it receives an email notification automatically. The email includes the request details, reviewer name, and a direct link to view the request in Netra. This works for SSO-authenticated users whose username is an email address — no additional configuration required beyond SMTP setup.

Action Buttons

All notification channels include approve/reject buttons that work without opening the Netra UI. Actions are authenticated via signed tokens embedded in the button URLs.

Webhook Retry

Failed deliveries are retried with exponential backoff: 30 seconds → 2 minutes → 10 minutes (max 3 attempts). Delivery history is visible per-channel in Settings.

Delivery Log

Every notification attempt is logged with status, response time, and any error details. View in Settings → Notifications → Delivery Log.

Drift Detection

Netra periodically compares live DNS records against what was approved and applied, alerting you when records diverge.

How It Works

  1. On a configurable interval, Netra queries live DNS for all managed records
  2. Compares live values against the last applied state
  3. Any differences are flagged as drift alerts on the dashboard
  4. Notifications are sent via configured channels

Acknowledging Drift

Drift alerts can be acknowledged individually or in bulk. Acknowledging means "I've seen this and it's expected" — useful during initial setup or planned out-of-band changes.

Configuration

Set the drift check interval in Settings → Drift Detection. Default is every 60 minutes.

Zone Management

Browse, import, export, and search all DNS records across your providers.

Zone Browser

The zone browser shows all records for any managed domain. Search, filter by type, and click any record to view its history.

Import

  • Provider import — Pull all records from a connected provider into Netra
  • BIND zone file — Upload or paste a BIND-format zone file
  • Auto-sync — After first import, zones re-sync automatically on the health check interval
  • Sync All Zones — One-click import for all configured domains

Export

  • CSV — Download any domain's records as CSV
  • BIND format — Export as a standard BIND zone file

Bulk Submission

Submit multiple DNS changes at once via CSV upload. Each row becomes a separate request that goes through the normal approval workflow.

API Tokens

Create named API tokens for automation, CI/CD pipelines, and external integrations.

Creating Tokens

  1. Go to Settings → API Tokens
  2. Click "Create Token"
  3. Give it a descriptive name (e.g. "GitHub Actions - Production")
  4. Copy the token — it's only shown once

Using Tokens

Include the token in the Authorization header:

curl -X POST https://netra.company.com/api/requests \
  -H "Authorization: Bearer your-token-here" \
  -H "Content-Type: application/json" \
  -d '{"domain": "example.com", "type": "A", "name": "app", "value": "10.0.1.50"}'

Token Management

Tokens can be revoked at any time. All API token usage is recorded in the audit log.

CI/CD Integration

Automate DNS changes as part of your deployment pipeline. Netra supports four CI/CD platforms via signed webhooks, plus direct API token access for any platform.

Two Integration Methods

MethodAuthBest for
Signed WebhookHMAC-SHA256 signature or shared tokenGitHub, GitLab, Bitbucket, Azure DevOps
API TokenBearer token in Authorization headerAny platform (Jenkins, CircleCI, Argo, custom scripts)

GitHub Actions (HMAC-SHA256)

Setup

  1. In Netra: Settings → CI/CD Pipelines → GitHub Actions card
  2. Enable the integration and set a webhook secret (openssl rand -hex 32)
  3. In GitHub: Settings → Secrets → add NETRA_URL and NETRA_SECRET

Workflow Example

- name: Request DNS change
  env:
    NETRA_URL: ${{ secrets.NETRA_URL }}
    NETRA_SECRET: ${{ secrets.NETRA_SECRET }}
  run: |
    PAYLOAD='{"dns_records":[{"domain":"corp.local","type":"A","name":"app","value":"10.0.0.5","ttl":300,"action":"create"}],"repository":{"full_name":"${{ github.repository }}"},"ref":"${{ github.ref }}","actor":"${{ github.actor }}"}'
    SIG="sha256=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$NETRA_SECRET" | awk '{print $2}')"
    curl -sf -X POST "$NETRA_URL/api/github/webhook" \
      -H "Content-Type: application/json" \
      -H "X-Hub-Signature-256: $SIG" \
      -d "$PAYLOAD"

Endpoint

POST /api/github/webhook — Auth: X-Hub-Signature-256 header (HMAC-SHA256 of body)

GitLab CI/CD (Token)

Setup

  1. In Netra: Settings → CI/CD Pipelines → GitLab card
  2. Enable and set a webhook token
  3. In GitLab: Settings → CI/CD → Variables → add NETRA_URL and NETRA_SECRET (Protected + Masked)

Pipeline Example

dns-request:
  stage: deploy
  script:
    - |
      PAYLOAD=$(jq -n \
        --arg domain "corp.local" --arg name "app" \
        --arg type "A" --arg value "10.0.0.5" \
        --arg action "create" \
        '{dns_records:[{domain:$domain,name:$name,type:$type,value:$value,action:$action}],
          project:{path_with_namespace:"'$CI_PROJECT_PATH'"},
          ref:"'$CI_COMMIT_REF_NAME'",pipeline_id:"'$CI_PIPELINE_ID'"}')
      curl -fsSL -X POST "$NETRA_URL/api/gitlab/webhook" \
        -H "Content-Type: application/json" \
        -H "X-Gitlab-Token: $NETRA_SECRET" \
        -d "$PAYLOAD"

Endpoint

POST /api/gitlab/webhook — Auth: X-Gitlab-Token header (plain token comparison, timing-safe)

Bitbucket Pipelines (Token)

Setup

  1. In Netra: Settings → CI/CD Pipelines → Bitbucket card
  2. Enable and set a webhook token
  3. In Bitbucket: Repository Settings → Pipelines → Variables → add NETRA_URL and NETRA_SECRET (Secured)

Pipeline Example

pipelines:
  custom:
    dns-request:
      - step:
          name: Submit DNS Change
          script:
            - |
              PAYLOAD=$(jq -n \
                --arg domain "corp.local" --arg name "app" \
                --arg type "A" --arg value "10.0.0.5" \
                '{dns_records:[{domain:$domain,name:$name,type:$type,value:$value,action:"create"}],
                  workspace:"'$BITBUCKET_WORKSPACE'",repository:"'$BITBUCKET_REPO_SLUG'",
                  pipeline_id:"'$BITBUCKET_BUILD_NUMBER'",branch:"'$BITBUCKET_BRANCH'"}')
              curl -fsSL -X POST "$NETRA_URL/api/bitbucket/webhook" \
                -H "Content-Type: application/json" \
                -H "X-Bitbucket-Token: $NETRA_SECRET" \
                -d "$PAYLOAD"

Endpoint

POST /api/bitbucket/webhook — Auth: X-Bitbucket-Token header

Azure DevOps (Token)

Setup

  1. In Netra: Settings → CI/CD Pipelines → Azure DevOps card
  2. Enable and set a webhook token
  3. In Azure DevOps: Pipelines → Library → Variable groups → add NETRA_URL and NETRA_SECRET (Secret)

Pipeline Example

- task: Bash@3
  displayName: Submit DNS Change
  inputs:
    targetType: inline
    script: |
      PAYLOAD=$(jq -n \
        --arg domain "corp.local" --arg name "app" \
        --arg type "A" --arg value "10.0.0.5" \
        '{dns_records:[{domain:$domain,name:$name,type:$type,value:$value,action:"create"}],
          project:"$(System.TeamProject)",repository:"$(Build.Repository.Name)",
          pipeline_id:"$(Build.BuildId)",branch:"$(Build.SourceBranch)"}')
      curl -fsSL -X POST "$NETRA_URL/api/azure-devops/webhook" \
        -H "Content-Type: application/json" \
        -H "X-Azure-Token: $NETRA_SECRET" \
        -d "$PAYLOAD"
  env:
    NETRA_URL: $(NETRA_URL)
    NETRA_SECRET: $(NETRA_SECRET)

Endpoint

POST /api/azure-devops/webhook — Auth: X-Azure-Token header (or HTTP Basic with token as password)

Payload Format (All Providers)

{
  "dns_records": [
    {
      "domain": "corp.local",
      "name": "app",
      "type": "A",
      "value": "10.0.0.5",
      "action": "create",
      "ttl": 3600
    }
  ],
  "repository": { "full_name": "org/repo" },
  "ref": "refs/heads/main",
  "run_id": "12345678",
  "actor": "jdoe"
}
FieldRequiredDescription
dns_recordsYesArray of records (max 20 per request)
dns_records[].domainYesZone name — must be managed by Netra
dns_records[].nameYesRecord name (e.g. app, @ for apex)
dns_records[].typeYesA, AAAA, CNAME, MX, TXT, SRV, PTR, NS
dns_records[].valueYesRecord value
dns_records[].actionNocreate (default), update, delete
dns_records[].ttlNoTTL in seconds (default: 3600, range: 60–86400)
actorNoWho triggered the pipeline (recorded in audit log)

Response Codes

CodeMeaning
200Success — records created (and applied if bypass enabled)
400Integration not enabled or invalid payload
401Invalid or missing signature/token

Bypass Approval

By default, pipeline requests enter the pending queue and require admin approval. To auto-apply pipeline requests immediately:

  1. Go to Settings → CI/CD Pipelines → select the provider card
  2. Enable "Bypass approval for pipeline requests"
  3. Type CONFIRM to acknowledge

When bypass is enabled, requests are applied immediately upon webhook receipt. All bypassed applies are fully audit-logged with the pipeline actor name.

Using API Tokens Instead

For platforms not listed above (Jenkins, CircleCI, Argo CD, custom scripts), use the standard API with a Bearer token:

curl -X POST https://netra.company.com/api/requests \
  -H "Authorization: Bearer dnsf_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{"domain_name":"corp.local","record_type":"A","record_name":"app","record_value":"10.0.0.5","action":"create"}'

API token requests follow the same approval workflow as UI submissions unless requireApproval is disabled.

Terraform Provider

Manage DNS records as infrastructure-as-code using the Netra Terraform provider. Changes are applied immediately — the pull request review process serves as your approval gate.

Requirements

  • Terraform >= 1.5
  • A Netra instance with at least one DNS provider configured
  • An admin API token (Settings → API Tokens)

Provider Configuration

terraform {
  required_providers {
    netra = {
      source  = "your-org/netra"
      version = "~> 1.0"
    }
  }
}

provider "netra" {
  url   = "https://netra.company.com"
  token = var.netra_token  # admin API token
}

Alternatively, use environment variables:

export NETRA_URL=https://netra.company.com
export NETRA_TOKEN=dnsf_your_token_here

Resources

netra_dns_record

resource "netra_dns_record" "app" {
  domain   = "corp.local"
  name     = "app"
  type     = "A"
  value    = "10.0.0.5"
  ttl      = 300
}

resource "netra_dns_record" "mail" {
  domain   = "corp.local"
  name     = "mail"
  type     = "CNAME"
  value    = "mail.provider.com"
}

resource "netra_dns_record" "mx" {
  domain   = "corp.local"
  name     = "@"
  type     = "MX"
  value    = "mail.corp.local"
  priority = 10
}
ArgumentTypeRequiredDescription
domainstringYesZone name (e.g. corp.local)
namestringYesRecord name (@ for zone apex)
typestringYesA, AAAA, CNAME, MX, TXT, SRV, PTR, NS
valuestringYesRecord value
ttlnumberNoTTL in seconds (default: 3600)
prioritynumberNoPriority for MX and SRV records

Changing domain, name, or type forces resource replacement (delete + create).

Data Sources

netra_domains

Lists all DNS zones managed by Netra:

data "netra_domains" "all" {}

output "zones" {
  value = [for d in data.netra_domains.all.domains : d.name if d.enabled]
}

Importing Existing Records

Import DNS records that already exist in Netra into your Terraform state:

terraform import netra_dns_record.app "corp.local/app/A/10.0.0.5"

Format: "domain/name/type/value". The record must already be imported in Netra's zone browser.

CI/CD Usage

# GitHub Actions
- uses: hashicorp/setup-terraform@v3
- run: terraform apply -auto-approve
  env:
    NETRA_URL: ${{ secrets.NETRA_URL }}
    NETRA_TOKEN: ${{ secrets.NETRA_TOKEN }}

Drift Detection

The provider's Read() function queries live DNS records from Netra on every terraform plan. If a record was modified or deleted outside Terraform, the plan shows the drift and proposes to recreate or update it.

Audit Trail

Every terraform apply creates a request record in Netra with source = "terraform", visible in the Audit Log. Filter by actor (the API token name) to see all Terraform-managed changes.

LDAP / Active Directory

Authenticate users against Active Directory or any LDAP-compatible directory with group-based role mapping. No agents, no schema changes required.

How It Works

  1. Netra binds with a service account to search for the user
  2. Finds the user's DN via sAMAccountName or userPrincipalName
  3. Binds as the user to validate their password
  4. Reads the memberOf attribute for group membership
  5. Maps groups to Netra roles (admin / approver / user)

Configuration

Settings → LDAP:

FieldDescriptionExample
HostLDAP server hostname or IPdc01.corp.local
Port389 (LDAP) or 636 (LDAPS)636
Use LDAPSEnable TLS encryptionEnabled for port 636
Bind DNService account distinguished nameCN=netra-svc,OU=Service Accounts,DC=corp,DC=local
Bind PasswordService account password (encrypted at rest)
Search BaseWhere to search for usersDC=corp,DC=local or corp.local
Admin GroupAD group name for admin roleNetra_Admins
Approver GroupAD group name for approver roleNetra_Approvers
User GroupAD group name for user roleNetra_Users

Group Mapping (Default-Deny)

Users must be a member of at least one configured group to gain access. If a user authenticates successfully but doesn't match any group, access is denied. This is a security-first design — no group configured means no LDAP access.

User's AD GroupsNetra Role
Member of Admin GroupAdmin
Member of Approver GroupApprover
Member of User GroupUser
Not in any configured groupRejected

If a user is in multiple groups, the most privileged role wins (admin > approver > user).

Search Base Format

Accepts either format:

  • Simple domain: corp.local (auto-converted to DC=corp,DC=local)
  • Full DN: OU=Users,DC=corp,DC=local

Using LDAP as SSO Fallback

When both SSO and LDAP are configured, SSO is the primary login method (displayed prominently on the login page). LDAP serves as a fallback — available via the "Sign in with password" link for situations when the SSO provider is unreachable.

API Reference

All endpoints require authentication via session cookie or Authorization: Bearer <token> header, except public endpoints noted below.

Public Endpoints (No Auth)

MethodPathDescription
GET/HEAD/api/healthGeneral health status + version
GET/HEAD/api/health/liveLiveness probe (event loop alive)
GET/HEAD/api/health/readyReadiness probe (DB connectivity)
GET/api/metricsPrometheus metrics
GET/api/status/pendingPending request count
GET/api/status/driftOpen drift alert count
GET/api/status/healthServer health summary
POST/api/auth/loginLocal/LDAP login
GET/auth/sso/loginInitiate SSO flow
GET/auth/sso/callbackSSO callback (code exchange)

Requests

MethodPathAuthDescription
GET/api/requestsAnyList requests (paginated, filterable)
POST/api/requestsAnySubmit a new DNS change request
GET/api/requests/:idAnyGet request detail
POST/api/requests/:id/approveAdmin/ApproverApprove a pending request
POST/api/requests/:id/rejectAdmin/ApproverReject a pending request
POST/api/requests/:id/reopenAdmin/ApproverRe-open a rejected request
POST/api/requests/:id/rollbackAdminReverse an applied change
POST/api/requests/bulkAnyBulk submit via CSV
POST/api/requests/batch-approveAdmin/ApproverBatch approve pending requests

Domains & Records

MethodPathAuthDescription
GET/api/domainsAnyList all domains
POST/api/domainsAdminCreate a domain
PUT/api/domains/:idAdminUpdate a domain
DELETE/api/domains/:idAdminDelete a domain
POST/api/domains/:id/importAdminImport zone from provider
POST/api/domains/:id/import-bindAdminImport from BIND file (text/plain body)
GET/api/domains/:id/exportAnyExport zone (CSV or BIND)
POST/api/dns/applyAdminDirect apply (Terraform/IaC)

Admin

MethodPathDescription
GET/PUT/api/settingsGet or update settings
GET/api/auditQuery audit log
GET/api/audit/exportExport audit log (CSV/NDJSON)
GET/api/serversList DNS providers
GET/api/tokensList API tokens
POST/api/tokensCreate API token
GET/api/sessionsList active sessions
GET/api/driftView drift alerts
POST/api/drift/runTrigger manual drift check

Request Body Format

All mutating endpoints expect Content-Type: application/json. Requests without this header receive a 415 Unsupported Media Type response.

Submit a Request

POST /api/requests
{
  "domain_name": "corp.local",
  "record_type": "A",
  "record_name": "app",
  "record_value": "10.0.0.5",
  "record_ttl": 3600,
  "action": "create",
  "scheduled_at": "2026-01-15T02:00:00Z",
  "confirm_overwrite": false
}

Response Headers

Every response includes:

  • X-Request-Id — unique UUID for log correlation
  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY
  • Content-Security-Policy
  • Referrer-Policy: strict-origin-when-cross-origin

Audit Logging

Every action in Netra is recorded in an immutable audit log.

What's Logged

  • Request submissions, approvals, rejections, and applications
  • Login attempts (success and failure) with IP addresses
  • Settings changes
  • Provider configuration changes
  • Session creation and revocation
  • API token usage
  • Drift detection results
  • Bypass approvals (prominently flagged)

Export

Export the audit log as CSV for compliance reporting. Filter by date range, user, or action type.

SIEM Forwarding

Forward audit events in real-time to external systems. Supported targets:

  • Syslog (UDP and TCP)
  • HTTP collectors (Splunk HEC, Elastic, custom endpoints)

Retention

Configure audit log retention in Settings. Admin-controlled purge requires typing CONFIRM to prevent accidental deletion.

Security

Netra is designed to be safe by default, especially for production environments.

Encryption

  • Service account credentials (e.g. WinRM passwords) are encrypted at rest
  • Session tokens are cryptographically signed with APP_SECRET
  • All communication with DNS providers uses encrypted channels

Session Management

  • Maximum 5 concurrent sessions per user (oldest evicted automatically)
  • Configurable session TTL (1–72 hours)
  • Sessions persist across container restarts
  • View and revoke active sessions in Settings
  • Full login/logout/failure history per user

Pre-flight Safety

  • Live DNS lookup before submitting — warns if record already exists
  • Conflict safeguard — user must type CONFIRM if overwriting an existing record
  • Maintenance windows — restrict when changes can be applied

Keyboard Shortcuts

Press ? anywhere in the app to see all keyboard shortcuts. Press ⌘K / Ctrl+K to open the command palette.

Troubleshooting

Container won't start

  • Check that the /data volume is writable
  • Verify APP_SECRET is set (required for encryption)
  • Check container logs: docker logs netra

Can't connect to Windows DNS

  • Verify the sidecar service is running and healthy
  • Check that the DNS server is reachable from the container network
  • Verify credentials in Settings → DNS Providers
  • Check the health indicator in the sidebar — it shows real-time connection status

SSO login fails

  • Verify the redirect URI matches exactly: https://your-netra-url/auth/sso/callback
  • Check that group claims are included in the token (Okta: Security → API → Authorization Servers → Claims)
  • Verify group names/IDs match what's configured in Netra
  • Check container logs for the groups Netra received: docker logs netra | grep "groups"
  • Local login always works as a fallback via "Sign in with password"

LDAP login fails

  • Check that the user is a member of at least one configured group (default-deny: no group = no access)
  • Test connectivity with the built-in test button in Settings → LDAP
  • Verify the search base covers the user's OU (use DC=corp,DC=local for the entire domain)
  • Check container logs: docker logs netra | grep "LDAP"
  • Common error: "User authenticated but is not a member of any authorized group" — add the user to one of the configured AD groups

Notifications not delivering

  • Check the delivery log in Settings → Notifications
  • Verify webhook URLs are reachable from the container
  • For email, verify SMTP settings and check for TLS requirements
  • Failed deliveries retry automatically (3 attempts with backoff)

Drift alerts on first setup

After importing zones for the first time, you may see drift alerts for records that existed before Netra was tracking them. Use "Bulk Acknowledge" to clear these — it's expected on initial setup.