Password policy
The rules are coded in the backend; no environment variable changes them.
Rules by path
Two sets of rules coexist today:
| Path | Rules applied |
|---|---|
| Change by the user (My profile → Security) | at least 8 characters, one uppercase, one lowercase, one digit (ProfileController) |
| Reset through the "forgot password" link | full rules below (PasswordPolicyService). Known defect: the service calls a validatePassword method that does not exist, so this path fails when saving the new password until the code is fixed |
| Account creation or new password typed by an administrator (Settings → Users) | no strength check |
app:reset-user-password command | no strength check |
Full PasswordPolicyService rules:
| Criterion | Requirement |
|---|---|
| Length | 12 to 128 characters |
| Composition | at least one uppercase, one lowercase, one digit and one special character |
| Common passwords | rejected, including when contained in the password (list of about a hundred known passwords) |
| Repetitions and sequences | three identical characters in a row, or a sequence such as 123 or 987, rejected |
| Personal information | last name, first name and the local part of the e-mail address must not appear |
An administrator creating an account must choose a password that meets the full rules: the system does not check it. That password is sent in clear text in the welcome e-mail, and the creation screen cannot force a change at first sign-in: ask the user to replace it straight away under My profile → Security.
Expiry
| Parameter | Value |
|---|---|
| Validity | 90 days after the last change |
| Warning | from 14 days before expiry |
| Effect | the status (passwordExpired, mustChangePassword, days left) is returned at sign-in; the frontend redirects to the profile when the change is mandatory |
An account with no last-change date is reported as expired. Only a mandatory change redirects the user to their profile; plain expiry does not block sign-in.
Lockout
Five failed sign-ins lock the account for 30 minutes. See Rate limiting for unlocking.
Storage
Passwords are hashed with bcrypt by Symfony's security component. No clear-text password is stored or logged.
Operational good practice
- Never send a password by messaging or in a ticket; prefer the reset link or the magic link.
- Never write a password in this documentation, in the repository or in a script.
- Deactivate rather than delete an account when someone leaves the project (audit traceability).