Quick reference
Everything on this page is documented for SpatiumDDI 1.0.0-beta.3, and each table names its source. It is laid out to print: use your browser’s Print command to keep a copy next to the keyboard. For the reasoning behind these values, see Tips and tricks and the Troubleshooting playbook.
The Academy lab
Section titled “The Academy lab”| What | Value |
|---|---|
| Start or resume the lab | ./lab/up.sh |
| Start with the upstream demo data | ./lab/up.sh --seed |
Keep admin / admin for the first-login exercise |
./lab/up.sh --first-login |
| Stop the lab, keep its data | ./lab/down.sh |
| Delete everything and start fresh | ./lab/destroy.sh |
Put admin back to admin (forced change) |
./lab/reset-admin.sh |
Check lab n |
./lab/check.sh <n> |
| Web UI | http://localhost:8077 |
| REST API | http://localhost:8077/api/v1/… (the API container is also published on 127.0.0.1:8000, for the lab host only) |
| Interactive API docs | http://localhost:8077/api/docs (Swagger) and /api/redoc; sign in to the console first |
| Sign in | admin with the LAB_ADMIN_PASSWORD from lab/.env |
| DNS (BIND9 agent) | 127.0.0.1, port 1053, UDP and TCP |
| DHCP (Kea agent) | host port 6767/udp (bridged: it can’t serve real LAN clients) |
| SpatiumDDI version | 1.0.0-beta.3, pinned by SPATIUMDDI_VERSION in lab/.env |
| Feature modules | 16 of 57 on, as on any fresh install (Features & Integrations) |
Where to run docker compose |
inside lab/ (Compose project spatium-academy) |
Source: the Academy lab scripts (lab/up.sh, lab/.env.example, lab/docker-compose.yml); verified in the Academy lab, 1.0.0-beta.3.
Ridgeline College at a glance
Section titled “Ridgeline College at a glance”| Object | Value |
|---|---|
| DNS and DHCP server groups | default (agents dns-bind9 and dhcp-kea) |
| Forward zone | corp.example.edu |
| IP space, block | Campus, 10.20.0.0/16 “Ridgeline campus” (groups and zone pinned here) |
| Staff subnet | 10.20.21.0/24 “Staff VLAN 21” (VLAN convention 10.20.<VLAN>.0/24) |
| Reverse zone | 21.20.10.in-addr.arpa, created automatically when you save Staff VLAN 21 (one zone per /24, inherited DNS included) |
| DHCP pools | dynamic 10.20.21.100–199 (the scope’s initial pool, named default, in place of the suggested .10–.254); excluded 10.20.21.1–9 (“Network infrastructure”) |
| First host | print-01 = 10.20.21.10 (A in corp.example.edu, PTR in 21.20.10.in-addr.arpa) |
| Reservation | cam-01 = 10.20.21.20, MAC 52:54:00:12:34:56, status static_dhcp |
| Bulk hosts | lab-pc-01 … lab-pc-10 = 10.20.21.30–39 |
| Scratch subnet | 10.20.99.0/24 “Scratch” (its reverse zone 99.20.10.in-addr.arpa is created the same way) |
| RBAC | group Helpdesk with role Viewer; user jsmith |
| API token | ridgeline-automation |
Source: Getting Started, the worked example and the Academy’s running example.
Ports and protocols
Section titled “Ports and protocols”| Port | Protocol | Used by | Notes |
|---|---|---|---|
| 8077 | TCP (HTTP) | Web UI, API and API docs (frontend nginx) | HTTP_PORT; the container listens on 80 |
| 443 | TCP (HTTPS) | Web UI with TLS | When you configure TLS |
| 8000 | TCP (HTTP) | API (uvicorn) | API_PORT; published on 127.0.0.1 only by default (API_BIND) |
| 5432 | TCP | PostgreSQL | Internal only; never expose |
| 6379 | TCP | Redis | Internal only; never expose |
| 53 | UDP + TCP | DNS daemons | Compose publishes 1053 (BIND9), 5453 (PowerDNS), 6053 (Technitium) |
| 67 | UDP | DHCPv4 (Kea) | Compose publishes 6767 (HA peer: 6768) |
| 547 | UDP | DHCPv6 (Kea) | The appliance DHCP role opens 67, 68 and 547 |
| 8000 in the Kea container | TCP | Kea HA peer traffic | Compose publishes 8001 (HA peer: 8002) |
| 853 | TCP | DNS over TLS | Compose overlay publishes 1853 for BIND9 |
| 443 (8443 on an appliance) | TCP | DNS over HTTPS | Compose overlay publishes 8443 for BIND9 |
| 853 | UDP | DNS over QUIC | Technitium only |
| 8081 / 5380 | TCP | PowerDNS / Technitium REST API | Loopback only, inside the agent container |
| 5985 / 5986 | TCP | WinRM (HTTP / HTTPS) | Windows DNS Path B and Windows DHCP; prefer 5986 |
| 53 on the Windows DC | UDP + TCP | RFC 2136 updates and AXFR | Windows DNS Path A |
| 6443, 2379–2380, 10250 | TCP | k3s API, etcd, kubelet | Appliance cluster peers only |
| 7946 | TCP + UDP | MetalLB memberlist | Appliance control-plane peers only |
| 19443 | TCP | frr-k8s webhook | Appliance control-plane peers only |
| 179 | TCP | BGP Looking Glass collector | Uses host networking; the module ships off |
Sources: Docker Compose deployment §1 and §10 · README, encrypted DNS · DNS drivers · Windows Server setup · Deployment topologies, fleet firewall (#1827) · Troubleshooting (#1139)
Docker Compose operations
Section titled “Docker Compose operations”# Start the stack with the built-in DNS and DHCP containersdocker compose --profile dns-bind9 --profile dhcp up -d# or set COMPOSE_PROFILES=dns-bind9,dhcp in .env and run: docker compose up -d# other DNS profiles: dns-powerdns, dns-technitium (dns = alias of dns-bind9)
# Status and logsdocker compose psdocker compose logs -f api worker # control plane (NDJSON on stdout)docker compose logs -f dns-bind9 # BIND9 agent and daemondocker compose logs -f dhcp-kea # Kea agent and daemondocker compose logs --tail=20 beat | grep 'Sending due task'
# Restart one agentdocker compose restart dns-bind9
# Upgrade: take a backup first, set SPATIUMDDI_VERSION=<tag> in .env, thengit pull # outside the lab: refresh docker-compose.yml and .env.exampledocker compose pull # with --profile flags instead of COMPOSE_PROFILES,docker compose run --rm migrate # pass them to pull and up -d; migrate is safe todocker compose up -d # repeat and resumes after a failure ("deadlock detected")docker compose images # confirm every container runs the new tag
# Before upgrading from 2026.09.04-1: copy local-volume backups out of the containersdocker compose cp api:/var/lib/spatiumddi/backups ./backups-apidocker compose cp worker:/var/lib/spatiumddi/backups ./backups-worker
# See what Kea is really runningdocker compose exec dhcp-kea \ cat /var/lib/spatium-dhcp-agent/rendered/kea-dhcp4.json | grep -A4 subnet4
# Publish DoT and DoH for BIND9 (overlay file)docker compose -f docker-compose.yml -f docker-compose.dns-encrypted.yml \ --profile dns-bind9 up -dComing from 2026.09.04-1, upgrade to 2026.10.02-1 first, then to 1.0.0-beta.3; the upgrade checklist has the steps.
Sources: README, upgrading and running the built-in containers · Docker Compose deployment §8 and §9 · Troubleshooting · Observability §3
Verify with dig
Section titled “Verify with dig”# Forward record (A) against the lab BIND9 agentdig @127.0.0.1 -p 1053 print-01.corp.example.edu A +short# Reverse record (PTR)dig @127.0.0.1 -p 1053 -x 10.20.21.10 +short# Is the zone loaded? Ask for its SOA and NSdig @127.0.0.1 -p 1053 corp.example.edu SOA +shortdig @127.0.0.1 -p 1053 corp.example.edu NS +short# Is the reverse zone loaded?dig @127.0.0.1 -p 1053 21.20.10.in-addr.arpa SOA +short# The gateway's PTR (published when the subnet is created)dig @127.0.0.1 -p 1053 -x 10.20.21.1 +short# Round robin: every A record for one namedig @127.0.0.1 -p 1053 <hostname>.corp.example.edu A +short# DoT and DoH, once the encrypted overlay is runningdig +tls +tls-hostname=<cert-name> @127.0.0.1 -p 1853 <name> A +shortdig +https=/dns-query +tls-hostname=<cert-name> @127.0.0.1 -p 8443 <name> A +shortOn a production server, drop -p 1053 and query port 53 on the server’s address. A blank Primary NS and Admin Email produce an SOA naming ns1.<zone> and admin.<zone>; values you fill in are served as entered.
Sources: README, running the built-in containers and encrypted DNS · Getting Started §10 · GitHub issue #1150 · GitHub issue #1153
Host and appliance checks
Section titled “Host and appliance checks”# DHCP host (appliance): are UDP 67, 68 and 547 open in the firewall?sudo nft list chain inet filter input | grep -E 'dport (67|68|547)'# Does kea-dhcp6 listen on the global address a DHCPv6 relay sends to?ss -ulpn6 | grep 547
# Appliance: compare nmtui edits with the saved state, or save them backspatium-network-adopt --checkspatium-network-adopt --adopt
# Appliance control plane: back up the Secret that holds SECRET_KEY (keep it off the box)kubectl -n spatium get secret spatium-control-app-keys -o yaml > app-keys.yaml# Why does an older release's api wait forever? (database migrated by a newer release)kubectl -n spatium logs deploy/spatium-control-spatiumddi-api -c wait-for-migrate# CNPG: rebuild one lost standby from the primary (never the primary)kubectl -n spatium cnpg destroy <cluster> <n>Sources: Troubleshooting (#1140, #2317) · OS appliance, network and rolling back (#1016, #1448)
API cheat sheet
Section titled “API cheat sheet”| What | Where |
|---|---|
| API base | /api/v1 |
| Swagger UI / ReDoc | /api/docs / /api/redoc, through the web port; sign in to the console first |
| OpenAPI schema | /api/openapi.json with a session or API token (401 otherwise); the openapi.json attached to every release needs none |
| Running version | GET /api/v1/version; anonymous callers get "version": "restricted" |
| Your effective permissions | GET /api/v1/auth/me/permissions |
| One audit row in full | GET /api/v1/audit/{id} (needs read on audit_log) |
| Approve a pending DNS agent | POST /api/v1/dns/groups/{group_id}/servers/{server_id}/approve (superadmin; DHCP: POST /api/v1/dhcp/servers/{id}/approve) |
| Rotate a DNS group’s TSIG key | POST /api/v1/dns/groups/{id}/group-tsig-key/rotate (superadmin) |
| Cross-space integration report | GET /api/v1/ipam/integration-space-audit (superadmin) |
| MCP endpoint (Operator Copilot) | /api/v1/ai/mcp, read-only tools, module ai.copilot |
| About page | /about in the console (ⓘ About): version, license and third-party notices; signed-in users only |
SPATIUM=http://localhost:8077
# Sign in: the body carries access_token (15 min); the 7-day refresh token# arrives as the HttpOnly spatium_refresh cookie, never in the bodycurl -s -X POST "$SPATIUM/api/v1/auth/login" \ -H 'Content-Type: application/json' \ -d '{"username":"admin","password":"<your-password>"}'
# Use a session token or an sddi_ API token the same wayTOKEN='<your-token>'curl -s "$SPATIUM/api/v1/ipam/spaces" -H "Authorization: Bearer $TOKEN"
# Change a forced password (until you do, almost every other call is refused)curl -s -X POST "$SPATIUM/api/v1/auth/change-password" \ -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \ -d '{"current_password":"<old>","new_password":"<new>"}'
# Mint an API token scoped like the course's (read + ipam:write). Minting asks for# your password again (SSO accounts: "stepup_totp_code"); the sddi_ value is returned oncecurl -s -X POST "$SPATIUM/api/v1/api-tokens" \ -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \ -d '{"name":"ridgeline-automation","scopes":["read","ipam:write"],"expires_in_days":90,"stepup_password":"<your-password>"}'
# Allocate the next free IP in a subnet (skips dynamic pools)curl -s -X POST "$SPATIUM/api/v1/ipam/subnets/<subnet-id>/next" \ -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \ -d '{"hostname":"<hostname>","status":"allocated"}'
# Page through a subnet's addresses (total in the X-Total-Count header)curl -s -D - "$SPATIUM/api/v1/ipam/subnets/<subnet-id>/addresses?limit=100&offset=0" \ -H "Authorization: Bearer $TOKEN"
# Fetch the OpenAPI schema from a scriptcurl -s "$SPATIUM/api/openapi.json" -H "Authorization: Bearer $TOKEN" -o openapi.json
# Scrape Prometheus metrics: the scrape token (PROMETHEUS_METRICS_TOKEN) or any API tokencurl -s "$SPATIUM/metrics" -H "Authorization: Bearer $TOKEN" | headList shapes. Core IPAM, DNS and DHCP lists return a bare JSON array. Newer routers return {"items": […], "total": n, "limit": n, "offset": n}. DNS records and DHCP leases return items, total, page and page_size, and the audit list total and items.
Token scopes. read (GET, HEAD and OPTIONS only), ipam:write, dns:write, dhcp:write and agent. Several scopes combine; no scopes means “whatever the owner may do”. A token never exceeds its owner.
| Status | Meaning |
|---|---|
| 400 | Semantically invalid input (for example a wrong current password) |
| 401 | Missing, invalid or expired credential, or a token scope that doesn’t cover the call (“Token scope insufficient for this request”) |
| 403 | Authenticated but not allowed (RBAC, superadmin-only, disabled account, forced password change, a wrong step-up answer) |
| 404 | Not found, or the feature module is disabled |
| 409 | Conflict or collision (warnings come with requires_confirmation: true; re-send with force=true), or a delete refused because rows still reference the target |
| 413 | Request body over the API’s cap (MAX_REQUEST_BODY_BYTES, 8 MiB by default; backups, images and importers have larger limits) |
| 422 | Validation failure, or a reference to a row that doesn’t exist |
| 429 | Rate limit or attempt budget: sign-in throttles, MFA and step-up budgets, appliance registration (some carry Retry-After) |
| 503 | Maintenance mode (Retry-After: 120), a transient database error, or a failing readiness check |
Every response carries an X-Request-ID to match against the server logs. Errors use {"detail": …}.
Sources: REST API · Auth & permissions, API tokens and step-up (#1355) · IPAM features §5 · System administration §5 · Verified in the Academy lab, 1.0.0-beta.3
Health endpoints
Section titled “Health endpoints”| Endpoint | Answers | Login |
|---|---|---|
/health/live |
200 while the process is up | None |
/health/ready |
Database, Redis, and the schema at head; 503 with details when not ready (an api already ready stays ready on a newer schema that still has every column it uses) | None |
/health/startup |
Same checks as ready, for slow-starting Kubernetes containers | None |
/health/platform |
Always 200; the per-component rollup (api, postgres, redis, celery-workers, celery-beat) for a signed-in caller or API token, only the overall status for anyone else | Optional |
/metrics |
Prometheus API-request and process metrics (on by default) | Bearer: the scrape token (PROMETHEUS_METRICS_TOKEN) or an API token |
A red celery-beat means no heartbeat tick landed; the fault can be beat or the workers (see the playbook).
Sources: REST API §1 (#1159, #2777, #2935) · Observability §6 and §7
Built-in roles
Section titled “Built-in roles”| Role | What it grants |
|---|---|
| Superadmin | Everything (* on *) |
| Viewer | Read on everything |
| IPAM Editor | Admin on spaces, blocks, subnets, addresses, address sets, VLANs, NAT, custom fields, IPAM templates, customers, sites, providers, services |
| DNS Editor | Creates, edits and deletes zones, records, views, ACLs and blocklist entries, and manages the TLS certificate store; reads DNS pools. Server groups, servers, TSIG keys, DNSSEC and pools stay with superadmins |
| DHCP Editor | Admin on scopes, pools, reservations, client classes, option templates and MAC blocks. DHCP servers and server groups stay with superadmins |
| Network Editor | Admin on network devices, scans, packet capture, block sync, network tools, ASNs, VRFs, circuits and related network objects |
| Auditor | Read on conformity, the audit log, IPAM (spaces, blocks, subnets, addresses), DNS (groups, zones, records), DHCP scopes and TLS certificates |
| Compliance Editor | Admin on conformity; read on the audit log, IPAM, DNS groups, zones and records, and DHCP scopes |
| Address Set Editor | Admin on address sets only |
| Change Approver | Approve and read change requests (also needs the change’s own permission; never their own request) |
| Requester | Submit and read their own provisioning requests; can’t provision anything. Also grant read on the subnets, blocks, zones or scopes a department may request into |
| Appliance Operator | Admin on the OS appliance management surface and the TLS certificate store; Fleet management (upgrade images, member actions, MetalLB, pairing codes) still needs a superadmin |
Every built-in role can read alerts. Built-in roles can be cloned but not deleted. Actions are read, write, delete, admin (all three), approve (the second-person decision on a change request, which admin doesn’t include) and *. A custom role needs read on each IPAM and DNS type it should see: ip_space, ip_block, subnet, ip_address, dns_group, dns_zone, dns_record.
Source: Permissions model (#1861, #3058, #3067, #3073)
IP address statuses
Section titled “IP address statuses”| Status | Meaning |
|---|---|
available |
Not assigned and not seen |
allocated |
Assigned manually in IPAM |
reserved |
Held but not assigned (the auto-created gateway row uses it) |
dhcp |
An active DHCP lease, mirrored into IPAM (locked: edit it at the DHCP source) |
static_dhcp |
Has a DHCP reservation; needs a MAC, and SpatiumDDI puts it on the subnet’s scope |
discovered |
Seen on the network but not recorded in IPAM |
orphan |
Deleted through the UI (Mark as Orphan); its DNS records leave the zone until you restore it, or purge it |
deprecated |
Was assigned, now decommissioned; still counts as allocated until you delete the row |
Each subnet also gets network and broadcast placeholder rows (not on /31 and /32), which can’t be edited or allocated.
Sources: IPAM features §5, §8, §11 and §14 · DHCP features §3
DNS record types
Section titled “DNS record types”| Record types | Where the API accepts them |
|---|---|
| A, AAAA, CNAME, MX, TXT, NS, PTR, SRV, CAA, TLSA, SSHFP, NAPTR, LOC | Any zone |
| SVCB, HTTPS, DNAME | Groups whose servers run BIND9, PowerDNS or Technitium |
| ALIAS (CNAME at the apex), LUA (scripted answers) | PowerDNS groups only |
SRV records need a priority, a weight and a port. A CNAME must be alone at its name and never at the apex. Per-IP DNS aliases in IPAM are CNAME or A records.
Sources: DNS features §0 and §5 · IPAM features §16 · Migration, CNAME beside other data
Keyboard shortcuts
Section titled “Keyboard shortcuts”| Keys | Where | Does |
|---|---|---|
| Ctrl+K (⌘K on a Mac) | Anywhere | Opens Search or jump to… |
| ↑ ↓, then Enter | In the search palette | Moves through results and opens one |
? |
Anywhere, when not typing | Shows every shortcut for your version |
| Esc | Palette and dialogs | Closes |
| Shift+Click | IP address table checkboxes | Selects a range of rows |
Press ? in the app for the authoritative list.
Sources: IPAM features §10 · GitHub issue #81, shortcut overlay
Environment variables
Section titled “Environment variables”The Compose .env settings this course mentions. The agent variables go in the standalone agent compose files’ .env.
| Variable | Default | What it does |
|---|---|---|
SPATIUMDDI_VERSION |
latest (the lab pins 1.0.0-beta.3) |
Image tag for every component; pre-releases are only reachable by pinning |
COMPOSE_PROFILES |
unset | Which agent containers start, for example dns-bind9,dhcp |
HTTP_PORT / API_PORT |
8077 / 8000 |
Host ports of the web UI and the API |
API_BIND |
127.0.0.1 |
Host address the API port is published on |
SECRET_KEY |
none | Signs sessions and derives the credential key; the api refuses a placeholder or anything under 32 characters. Replace one with python -m app.core.rotate_secret_key (Rotating SECRET_KEY in the Docker docs) |
CREDENTIAL_ENCRYPTION_KEY |
empty (derived from SECRET_KEY) |
Fernet key for stored credentials; an invalid one stops the api |
ALLOW_INSECURE_SECRET_KEY |
false |
Boots on a weak key with a warning; local development only |
TRUSTED_PROXY_CIDRS |
private, loopback, CGNAT and ULA ranges | Peers whose X-Real-IP and X-Forwarded-Proto the API believes |
FRONTEND_TRUSTED_PROXY_CIDRS |
unset | Your own reverse proxy in front of the frontend |
LOGIN_FAIL_MAX_PER_USERNAME / LOGIN_FAIL_MAX_GLOBAL |
20 / 500 |
Failed passwords per 15 minutes before sign-in answers 429; 0 turns one off |
PROMETHEUS_METRICS_TOKEN |
empty (API tokens only) | Scrape token for /metrics |
PROMETHEUS_METRICS_REQUIRE_AUTH |
true |
false serves /metrics to anyone (not recommended) |
MAX_REQUEST_BODY_BYTES |
8 MiB | Request body cap; over it the API answers 413 |
DNS_REQUIRE_AGENT_APPROVAL / DHCP_REQUIRE_AGENT_APPROVAL |
false |
New agents wait for approval before they get config |
DNS_BIND9_MEM_LIMIT |
2g |
Memory limit of the dns-bind9 container; size it for your blocklists |
SPATIUM_DRILL_MAX_DB_BYTES |
20 GiB | Restore drills refuse a larger database; 0 disables the guard |
TLS_CA_PATH (agents) |
unset | CA bundle a remote agent verifies the control plane with |
SPATIUM_INSECURE_SKIP_TLS_VERIFY (agents) |
0 |
1 turns verification off: labs only |
Sources: Docker Compose deployment §3 and §10 (#1159, #1220, #1221, #1222) · Docker Compose .env.example · REST API §8 · System administration §2.9
Defaults and limits
Section titled “Defaults and limits”| Setting | Documented value | Source |
|---|---|---|
| First sign-in | admin / admin, password change forced and held to the password policy |
Docker §2 |
| Access token / refresh token | 15 min / 7 days (refresh rotates; HttpOnly spatium_refresh cookie) |
REST API §3 |
| Password policy | 12+ characters, upper, lower and digit; last 5 refused; no symbol rule, no expiry | System admin §6 |
| Password length | At most 72 bytes (from 2026.08.22-1) |
Release notes |
| Account lockout | Off (threshold 0); 15 min lock and reset window when on | System admin §6 |
| Sign-in throttles | 30 attempts / 60 s per source; 20 failed per username and 500 install-wide per 15 min; then 429 | Auth, sign-in throttles |
| Step-up budget | 5 wrong answers per 15 min per account, then 429 | Auth, TOTP MFA |
| Idle session timeout | 60 min (Session & Security → Session Timeout, enforced by the API; API tokens unaffected); Auto-Logout Warning 0 (off) | System admin §6 |
| API token expiry (UI) | 90 days | Auth §API tokens |
| Feature modules on a fresh install | 16 of 57 on | REST API §5 |
| Default zone TTL / zone type | 3600 s / primary | System admin §6 |
| Recursion on new DNS groups | On, answering only loopback, local and private networks | DNS §3.2 |
| DNSSEC signing | One agent DNS server per group; BIND9 and PowerDNS only | DNS §0 |
| DoT / DoH ports | 853 / 443 (8443 on an appliance) | DNS §20 |
| DNS pool (GSLB) TTL | 30 s | DNS §17 |
| DDNS | Off per subnet; policy client_or_generated |
DNS §7 |
| Default DHCP lease time | 86400 s (24 h) | System admin §6 |
| Kea lease cache | 0.0 (off) |
DHCP §4b |
| Kea HA | Between Kea members with an HA Peer URL; a third becomes a backup peer; DHCPv4 only | DHCP §14 |
| DHCP Lease Sync poll | 15 s (minimum 10 s) | Getting Started §5 |
| IP allocation strategy | Sequential | System admin §6 |
| Utilization thresholds | Warn 80%, critical 95%; IPv4 longer than /29 excluded | System admin §6 |
| Bulk allocate | Up to 1024 IPs per run | CHANGELOG |
| Discovery sweep | Off per subnet; up to /20; IPv4 only | IPAM §8 |
| IPAM → DNS Reconciliation | Off; hourly when on | DNS §14 |
| Zone ↔ Server Reconciliation | Off; every 30 min when on | DNS §14 |
| Agent heartbeat | Every 30 s (±3 s) | DNS agent §4 |
| Server marked unreachable | After 3 missed heartbeats (90 s) | DNS agent §4 |
| Agent token | 24 h, rotated within 12 h of expiry | DNS agent §6 |
| Agent outage spool | 256 MiB (AGENT_SPOOL_MAX_BYTES) |
Observability §9.1 |
| Config change reaches agents | Well under 1 s; at most about 12 s | Architecture §4 |
| Alert evaluation | Every 60 s | Observability §9.1 |
| Maintenance mode | Writes get 503 with Retry-After: 120 |
System admin §5 |
| Request body cap | 8 MiB (MAX_REQUEST_BODY_BYTES), larger for backups, images and importers |
REST API §8 |
| Backup passphrase | At least 8 characters; it encrypts secrets.enc only |
System admin §2.9 |
| Restore drills | Refused when the database is over 20 GiB | System admin §2.9 |
| Support bundle | 48 MB at most | System admin §9 |
| Pairing code | 8 digits; single-use codes expire after 15 min, persistent codes after 30 days | Appliance §9 |
| Appliance disk | 32 GiB minimum; 40 GiB SSD for a control plane; 48 GiB per node for a three-node control plane | Appliance · Sizing |
| Appliance control-plane members | 1, 3, 5 or 7 | Topologies |
| Docker Compose host | 2 vCPU / 4 GiB minimum, 4 vCPU / 8 GiB recommended | Docker |
Data retention
Section titled “Data retention”All under Settings → Application → Data Retention, superadmin-only, applied by a nightly prune.
| Data | Default | Range |
|---|---|---|
| DNS query & DHCP activity logs | 24 hours | 1–168 hours |
| DNS & DHCP metrics | 7 days | 1–365 days |
| DHCP lease history | 90 days | 0–3650 days (0 keeps forever) |
| Trash | 30 days | 0–365 days (0 never purges) |
| Packet captures | 7 days | 1–90 days |
| Deleted (revoked) Fleet appliances | 30 days | 0–365 days (0 keeps them until deleted for good) |
The audit log has no retention setting: nothing prunes it.
Source: System administration §2.7, data retention (#2273)
Go deeper
Section titled “Go deeper”- Getting Started: setup order
- REST API and Permissions model
- Docker Compose deployment, Sizing and Deployment topologies
- System administration: settings, data retention, backup and restore
- Glossary for any term on this page