IP Allowlist
Administrators can restrict who reaches the admin interface and the external data APIs. The two lists are independent. Both are off by default.

The application reads the TCP peer address from an internal header set by scripts/peer-ip.cjs. A client cannot spoof that header. Detected IP shows the TCP Peer IP and the Allowlist IP used for access decisions (they match unless trusted-proxy headers apply).
Denied requests return HTTP 403 (IP_NOT_ALLOWED on API paths). They are not written to the audit log. A rate-limited console.warn line is emitted to application stdout (for example docker logs) — at most one log per client IP and surface (admin, external, or probe) per minute, and ten per hour — so scanners cannot flood the logs.
Trusted proxies
Enable Trust reverse proxy headers only when duplistatus is not reachable except through a reverse proxy that overwrites X-Forwarded-For / X-Real-IP (do not append). Add each proxy CIDR with Add (or paste a comma- or newline-separated list). Entries appear as removable chips. When the TCP peer is not in that list, forwarded headers are ignored.
Admin interface
When enabled, pages, login, CSRF, and session APIs accept only listed CIDRs. Add entries with Add; your current Allowlist IP is tagged current IP when it is in the list. 127.0.0.1 and ::1 are included by default and cannot be removed. Add current IP and Recent admin login IPs (from the audit log) offer quick suggestions. You cannot enable this list unless your current IP is already included (or you are connecting from loopback). A lockout can be recovered with:
ADMIN_IP_ALLOWLIST_ENABLED=false
or by adding your CIDR to ADMIN_IP_ALLOWLIST. Full recovery steps (Docker recreate, then fix Settings and remove the override) are in Locked Out by IP Allowlist.
External APIs
When enabled, /api/upload, /api/summary, and /api/lastbackup* accept only listed CIDRs.
/api/health and /api/ping are not on the external list alone (the dashboard ping comes from the admin UI IP). When either allowlist is enabled, those probes accept loopback (127.0.0.1, ::1) and CIDRs from the admin or external list. Unlisted IPs receive HTTP 403. When both lists are off, the probes stay public.
Non-loopback probe requests are also rate-limited (HTTP 429, PROBE_RATE_LIMITED): /api/ping 60/minute and 600/hour; /api/health 30/minute and 120/hour. In-container Docker checks hit localhost and are never throttled. App-level limits do not stop a volumetric connection flood; put that on the reverse proxy.
This list is the protection to use when API keys are not required. Add CIDRs as chips like the admin list. 127.0.0.1 and ::1 are included by default and cannot be removed. Recent upload source IPs from the audit log are offered as quick-add suggestions.
If both this allowlist and API keys are required, a request must pass both.
Environment overrides
| Variable | Purpose |
|---|---|
IP_TRUSTED_PROXIES | Comma-separated trusted proxy CIDRs (also implies trust-proxy) |
ADMIN_IP_ALLOWLIST_ENABLED | true / false |
ADMIN_IP_ALLOWLIST | Comma-separated CIDRs |
EXTERNAL_API_IP_ALLOWLIST_ENABLED | true / false |
EXTERNAL_API_IP_ALLOWLIST | Comma-separated CIDRs |
Environment values override the database so a lockout is recoverable without the UI.