Skip to content

Hardening

  • TLS everywhere: Autentico must run behind a TLS-terminating reverse proxy. Never expose the plain HTTP port to the internet.
  • HSTS: Configure your reverse proxy to set Strict-Transport-Security with a long max-age and includeSubDomains.
  • Minimum TLS version: Enforce TLS 1.2+ at the proxy level. Disable SSLv3, TLS 1.0, TLS 1.1.
  • Cookie secret: AUTENTICO_COOKIE_SECRET must be at least 32 random bytes. Generate it with openssl rand -base64 32.
  • Admin token: AUTENTICO_ADMIN_TOKEN should be a long random string. Treat it like a root password — rotate it on suspicion of compromise.
  • Private key: AUTENTICO_PRIVATE_KEY (a base64-encoded RSA PEM) is the trust anchor for all issued tokens. Store it in a secrets manager, back it up securely, and never commit it to source control.
  • Secrets rotation: Rotating AUTENTICO_COOKIE_SECRET invalidates all active SSO session cookies (users must re-login). Rotating the RSA private key invalidates all issued tokens (users must re-authenticate). Plan rotations for low-traffic windows.
  • Enable MFA: Set mfa_enabled = true. TOTP is preferred over email OTP.
  • Strong passwords: Set validation_min_password_length to at least 12. Consider requiring complexity rules via external tooling if needed.
  • Account lockout: Keep lockout_max_attempts at a reasonable value (5-10). Set lockout_duration to at least 15m.
  • Passkeys: For high-assurance deployments, consider passkey_only mode — phishing-resistant by design.
  • Principle of least privilege: Only grant clients the grant types they actually use.
  • Exact redirect URIs: Never use wildcards. Each redirect URI should be the precise callback URL.
  • Rotate client secrets: Rotate client_secret for confidential clients periodically or after any suspected exposure.
  • Disable unused clients: Deactivate clients that are no longer in use.

Autentico includes a built-in per-IP token-bucket rate limiter on all authentication endpoints (/oauth2/login, /oauth2/mfa, /oauth2/token, /oauth2/passkey/login/finish). It is enabled by default at 5 requests/second with a burst of 10.

  • Two tiers: the per-second limiter (AUTENTICO_RATE_LIMIT_RPS, default 5; burst AUTENTICO_RATE_LIMIT_BURST, default 10) stops rapid automated bursts. The per-minute limiter (AUTENTICO_RATE_LIMIT_RPM, default 20; burst AUTENTICO_RATE_LIMIT_RPM_BURST, default 20) caps sustained enumeration from attackers who space requests to avoid the per-second limit. A request must pass both.
  • Disabling: set AUTENTICO_RATE_LIMIT_RPS=0 if your reverse proxy or WAF already handles rate limiting — no need to double-count.
  • Scope: limits are per source IP (extracted from X-Forwarded-For when behind a proxy). The limiter complements account lockout — lockout stops single-account brute force, rate limiting stops IP-level enumeration and MFA hammering.
  • Firewall the admin port: If AUTENTICO_APP_LISTEN_PORT is not behind a proxy, firewall it so only your proxy can reach it.
  • CORS: Only enable AUTENTICO_ENABLE_CORS=true if you have a browser SPA that needs to call token endpoints directly. Otherwise leave it off.
  • Admin API access: The admin API (/admin/api/*) is bearer-token protected, but consider additionally restricting it by IP at the proxy or firewall level.
  • File permissions: The SQLite database file should be readable only by the user running Autentico (chmod 600).
  • Backups: Back up autentico.db regularly. Encrypt backups at rest.
  • No direct access: Do not expose the database file to network shares or web-accessible paths.