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
| Role | Username | Password | Access Level |
|---|---|---|---|
| Admin | admin | admin | Full system access |
| Approver | approver | approver | Submit + approve/reject |
| User | user | user | Submit 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:
- Changing default passwords
- Connecting your first DNS provider
- Configuring notification channels
- Setting up SSO (optional)
- 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:
| Variable | Description | Required |
|---|---|---|
APP_SECRET | Encryption key for tokens and credentials. Generate with openssl rand -hex 32 | Yes |
APP_URL | Public URL for notification links (e.g. https://netra.company.com) | Yes |
ADMIN_USER / ADMIN_PASS | Initial admin credentials | Yes |
TZ | Timezone (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:
| Endpoint | Purpose | Checks | Use for |
|---|---|---|---|
/api/health | General status | In-memory only | Status pages, dashboard widgets |
/api/health/live | Liveness probe | Event loop responsive | k8s livenessProbe — restart if dead |
/api/health/ready | Readiness probe | DB connectivity | k8s 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
- Navigate to Settings → DNS Providers
- Click "Add Provider" and select the type
- Enter connection credentials
- Test the connection
- Assign domains to the provider
Approval Workflow
Netra's approval system ensures no DNS change reaches production without review.
How It Works
- Submit — Any user creates a DNS change request
- Review — An approver or admin reviews the request
- 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 Role | Permissions |
|---|---|
| Admin | Full access — settings, providers, audit, drift, approve, submit |
| Approver | Submit requests + approve/reject others' requests |
| User | Submit requests only |
Setup Steps
- Create an application in your identity provider
- Set the redirect URI to
https://your-netra-url/auth/sso/callback - In Netra, go to Settings → SSO
- Select your provider (Okta, Microsoft, or Generic OIDC)
- Enter Client ID, Client Secret, and domain/issuer
- Map group names/IDs to Netra roles
- 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
- On a configurable interval, Netra queries live DNS for all managed records
- Compares live values against the last applied state
- Any differences are flagged as drift alerts on the dashboard
- 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
- Go to Settings → API Tokens
- Click "Create Token"
- Give it a descriptive name (e.g. "GitHub Actions - Production")
- 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
| Method | Auth | Best for |
|---|---|---|
| Signed Webhook | HMAC-SHA256 signature or shared token | GitHub, GitLab, Bitbucket, Azure DevOps |
| API Token | Bearer token in Authorization header | Any platform (Jenkins, CircleCI, Argo, custom scripts) |
GitHub Actions (HMAC-SHA256)
Setup
- In Netra: Settings → CI/CD Pipelines → GitHub Actions card
- Enable the integration and set a webhook secret (
openssl rand -hex 32) - In GitHub: Settings → Secrets → add
NETRA_URLandNETRA_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
- In Netra: Settings → CI/CD Pipelines → GitLab card
- Enable and set a webhook token
- In GitLab: Settings → CI/CD → Variables → add
NETRA_URLandNETRA_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
- In Netra: Settings → CI/CD Pipelines → Bitbucket card
- Enable and set a webhook token
- In Bitbucket: Repository Settings → Pipelines → Variables → add
NETRA_URLandNETRA_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
- In Netra: Settings → CI/CD Pipelines → Azure DevOps card
- Enable and set a webhook token
- In Azure DevOps: Pipelines → Library → Variable groups → add
NETRA_URLandNETRA_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"
}
| Field | Required | Description |
|---|---|---|
dns_records | Yes | Array of records (max 20 per request) |
dns_records[].domain | Yes | Zone name — must be managed by Netra |
dns_records[].name | Yes | Record name (e.g. app, @ for apex) |
dns_records[].type | Yes | A, AAAA, CNAME, MX, TXT, SRV, PTR, NS |
dns_records[].value | Yes | Record value |
dns_records[].action | No | create (default), update, delete |
dns_records[].ttl | No | TTL in seconds (default: 3600, range: 60–86400) |
actor | No | Who triggered the pipeline (recorded in audit log) |
Response Codes
| Code | Meaning |
|---|---|
200 | Success — records created (and applied if bypass enabled) |
400 | Integration not enabled or invalid payload |
401 | Invalid or missing signature/token |
Bypass Approval
By default, pipeline requests enter the pending queue and require admin approval. To auto-apply pipeline requests immediately:
- Go to Settings → CI/CD Pipelines → select the provider card
- Enable "Bypass approval for pipeline requests"
- Type
CONFIRMto 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
}
| Argument | Type | Required | Description |
|---|---|---|---|
domain | string | Yes | Zone name (e.g. corp.local) |
name | string | Yes | Record name (@ for zone apex) |
type | string | Yes | A, AAAA, CNAME, MX, TXT, SRV, PTR, NS |
value | string | Yes | Record value |
ttl | number | No | TTL in seconds (default: 3600) |
priority | number | No | Priority 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
- Netra binds with a service account to search for the user
- Finds the user's DN via
sAMAccountNameoruserPrincipalName - Binds as the user to validate their password
- Reads the
memberOfattribute for group membership - Maps groups to Netra roles (admin / approver / user)
Configuration
Settings → LDAP:
| Field | Description | Example |
|---|---|---|
| Host | LDAP server hostname or IP | dc01.corp.local |
| Port | 389 (LDAP) or 636 (LDAPS) | 636 |
| Use LDAPS | Enable TLS encryption | Enabled for port 636 |
| Bind DN | Service account distinguished name | CN=netra-svc,OU=Service Accounts,DC=corp,DC=local |
| Bind Password | Service account password (encrypted at rest) | |
| Search Base | Where to search for users | DC=corp,DC=local or corp.local |
| Admin Group | AD group name for admin role | Netra_Admins |
| Approver Group | AD group name for approver role | Netra_Approvers |
| User Group | AD group name for user role | Netra_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 Groups | Netra Role |
|---|---|
| Member of Admin Group | Admin |
| Member of Approver Group | Approver |
| Member of User Group | User |
| Not in any configured group | Rejected |
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 toDC=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)
| Method | Path | Description |
|---|---|---|
GET/HEAD | /api/health | General health status + version |
GET/HEAD | /api/health/live | Liveness probe (event loop alive) |
GET/HEAD | /api/health/ready | Readiness probe (DB connectivity) |
GET | /api/metrics | Prometheus metrics |
GET | /api/status/pending | Pending request count |
GET | /api/status/drift | Open drift alert count |
GET | /api/status/health | Server health summary |
POST | /api/auth/login | Local/LDAP login |
GET | /auth/sso/login | Initiate SSO flow |
GET | /auth/sso/callback | SSO callback (code exchange) |
Requests
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /api/requests | Any | List requests (paginated, filterable) |
POST | /api/requests | Any | Submit a new DNS change request |
GET | /api/requests/:id | Any | Get request detail |
POST | /api/requests/:id/approve | Admin/Approver | Approve a pending request |
POST | /api/requests/:id/reject | Admin/Approver | Reject a pending request |
POST | /api/requests/:id/reopen | Admin/Approver | Re-open a rejected request |
POST | /api/requests/:id/rollback | Admin | Reverse an applied change |
POST | /api/requests/bulk | Any | Bulk submit via CSV |
POST | /api/requests/batch-approve | Admin/Approver | Batch approve pending requests |
Domains & Records
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /api/domains | Any | List all domains |
POST | /api/domains | Admin | Create a domain |
PUT | /api/domains/:id | Admin | Update a domain |
DELETE | /api/domains/:id | Admin | Delete a domain |
POST | /api/domains/:id/import | Admin | Import zone from provider |
POST | /api/domains/:id/import-bind | Admin | Import from BIND file (text/plain body) |
GET | /api/domains/:id/export | Any | Export zone (CSV or BIND) |
POST | /api/dns/apply | Admin | Direct apply (Terraform/IaC) |
Admin
| Method | Path | Description |
|---|---|---|
GET/PUT | /api/settings | Get or update settings |
GET | /api/audit | Query audit log |
GET | /api/audit/export | Export audit log (CSV/NDJSON) |
GET | /api/servers | List DNS providers |
GET | /api/tokens | List API tokens |
POST | /api/tokens | Create API token |
GET | /api/sessions | List active sessions |
GET | /api/drift | View drift alerts |
POST | /api/drift/run | Trigger 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 correlationX-Content-Type-Options: nosniffX-Frame-Options: DENYContent-Security-PolicyReferrer-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
/datavolume 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=localfor 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.