Hardening
Transport security
Section titled “Transport security”- 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-Securitywith a long max-age andincludeSubDomains. - Minimum TLS version: Enforce TLS 1.2+ at the proxy level. Disable SSLv3, TLS 1.0, TLS 1.1.
Secrets
Section titled “Secrets”- CSRF secret:
AUTENTICO_CSRF_SECRET_KEYmust be at least 32 random bytes. Generate it withopenssl rand -hex 32. - Token signing secrets:
AUTENTICO_ACCESS_TOKEN_SECRETandAUTENTICO_REFRESH_TOKEN_SECRETshould 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_KEYinvalidates active CSRF tokens. Rotating the RSA private key invalidates all issued tokens (users must re-authenticate). Plan rotations for low-traffic windows.
Authentication
Section titled “Authentication”- Enable MFA: Set
require_mfa = true. TOTP is preferred over email OTP. - Strong passwords: Set
validation_min_password_lengthto at least12. Consider requiring complexity rules via external tooling if needed. - Account lockout: Keep
account_lockout_max_attemptsat a reasonable value (5-10). Setaccount_lockout_durationto at least15m. - Passkeys: For high-assurance deployments, consider
passkey_onlymode — phishing-resistant by design.
Client registration
Section titled “Client registration”- 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_secretfor confidential clients periodically or after any suspected exposure. - Disable unused clients: Deactivate clients that are no longer in use.
Rate limiting
Section titled “Rate limiting”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; burstAUTENTICO_RATE_LIMIT_BURST, default 10) stops rapid automated bursts. The per-minute limiter (AUTENTICO_RATE_LIMIT_RPM, default 20; burstAUTENTICO_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=0if your reverse proxy or WAF already handles rate limiting — no need to double-count. - Scope: limits are per source IP (extracted from
X-Forwarded-Forwhen behind a proxy). The limiter complements account lockout — lockout stops single-account brute force, rate limiting stops IP-level enumeration and MFA hammering.
Network
Section titled “Network”- Firewall the admin port: If
AUTENTICO_LISTEN_PORTis 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_originsruntime 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 bothadminrole andautentico-adminin the token’saudclaim. Tokens from the built-inautentico-adminclient satisfy this automatically. To grant other clients admin API access, add"autentico-admin"to theirallowed_audiences. Consider additionally restricting the admin API by IP at the proxy or firewall level. - Headless admin-API tokens (CI/CD): By default,
autentico-adminonly supportsauthorization_code+refresh_token, which require a browser. To fetch admin-API tokens from scripts (e.g. integration tests), pass--enable-admin-password-grantonautentico onboard(or setAUTENTICO_ENABLE_ADMIN_PASSWORD_GRANT=true). This seeds the admin client with thepassword(ROPC) grant, allowingPOST /oauth2/tokenwithgrant_type=password. For deployments that complete setup via the browser/onboardwizard, add thepasswordgrant 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.
Database
Section titled “Database”- File permissions: The SQLite database file should be readable only by the user running Autentico (
chmod 600). - Backups: Back up
autentico.dbregularly. Encrypt backups at rest. - No direct access: Do not expose the database file to network shares or web-accessible paths.