- Algorithm: argon2id (OWASP recommended)
- Parameters: Memory 19 MiB, Iterations 2, Parallelism 1
- Hash length: 32 bytes
- Hashing time: ~300ms per password
argon2id is the most secure password hashing algorithm available, resistant to both side-channel and GPU-based attacks.
- Passwords are never stored in plaintext
- The
passwordHashfield is never included in API responses - User queries use a separate
findByEmailWithPassword()method that explicitly selects the hash
Configurable password policy:
| Rule | Default |
|---|---|
| Minimum length | 8 |
| Maximum length | 128 |
| Require uppercase | Yes |
| Require lowercase | Yes |
| Require number | Yes |
| Require special character | No |
When a user changes their password:
- OAuth-only users (no password set) are blocked with a clear error
- Old password is verified first
- New password is checked against the old one — same-password reuse is rejected
- New password is validated against the configured policy
- New password is hashed with argon2id
- All other sessions are revoked — the current session stays active
- Login history records the event (if enabled)
When a user resets via forgot-password:
- A cryptographically random token is generated
- Token is stored hashed (SHA-256) in the database
- Token expires after 15 minutes (configurable)
- On reset: token is verified, new password is checked against the old one (same-password reuse rejected)
- Password is updated, all sessions revoked
- Token is single-use (marked as used after verification)