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.
  • CSRF secret: AUTENTICO_CSRF_SECRET_KEY must be at least 32 random bytes. Generate it with openssl rand -hex 32.
  • Token signing secrets: AUTENTICO_ACCESS_TOKEN_SECRET and AUTENTICO_REFRESH_TOKEN_SECRET should be long random hex strings. Rotating them invalidates all existing tokens.
  • 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_CSRF_SECRET_KEY invalidates active CSRF tokens. Rotating the RSA private key invalidates all issued tokens (users must re-authenticate). Plan rotations for low-traffic windows.
  • Enable MFA: Set require_mfa = 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 account_lockout_max_attempts at a reasonable value (5-10). Set account_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_LISTEN_PORT is not behind a proxy, firewall it so only your proxy can reach it.
  • CORS: Configure allowed origins via the Admin UI (CORS page) or the cors_allowed_origins runtime setting. Use specific origins in production — avoid * unless necessary. Leave empty to disable CORS entirely (let your reverse proxy handle it).
  • Admin API access: The admin API (/admin/api/*) requires a bearer token with both admin role and autentico-admin in the token’s aud claim. Tokens from the built-in autentico-admin client satisfy this automatically. To grant other clients admin API access, add "autentico-admin" to their allowed_audiences. Consider additionally restricting the admin API by IP at the proxy or firewall level.
  • Headless admin-API tokens (CI/CD): By default, autentico-admin only supports authorization_code + refresh_token, which require a browser. To fetch admin-API tokens from scripts (e.g. integration tests), pass --enable-admin-password-grant on autentico onboard (or set AUTENTICO_ENABLE_ADMIN_PASSWORD_GRANT=true). This seeds the admin client with the password (ROPC) grant, allowing POST /oauth2/token with grant_type=password. For deployments that complete setup via the browser /onboard wizard, add the password grant afterwards from the Admin UI (Clients → autentico-admin). MFA and account lockout still apply; use a strong admin password and enable TOTP for this account in production.
  • 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.