Skip to content

TLS and brute-force protection

Without TLS, passwords, API keys and tokens travel in clear text, and curral warns about it at startup.

  • Native TLS: --tls-cert and --tls-key (TLS 1.2+). SIGHUP reloads the certificate without dropping connections; an invalid file keeps the current one.
  • Reverse proxy: Caddy with automatic certificates, as in Deploy with Docker Compose.

Authentication failures are counted per IP and per user name. Past the limit, requests get 429 with Retry-After, even with the right credential. The lockout is checked before bcrypt, so it costs no CPU, and bcrypt itself is capped at the number of CPUs.

Flag Default
--auth-ip-max-failures 10 failures per IP in the window (0 = off)
--auth-user-max-failures 30 failures per user name in the window (0 = off)
--auth-failure-window 5m counting window
--auth-lockout 15m lockout duration

The per-user limit catches distributed attacks, but it also lets someone lock another person out temporarily. Tune it, or set it to 0.

Lockouts produce auth_blocked audit events and the metrics curral_auth_lockouts_total{scope} and curral_auth_blocked_total{scope}.

curral only reads X-Forwarded-For when the connection comes from a --trusted-proxy, reading right to left and stopping at the first untrusted address, so a client cannot forge its IP.

Trust only the proxy’s IP, never a whole Docker subnet: the subnet includes the gateway, through which anything reaching published host ports arrives.