Alpha — the platform is in development. Docs cover what ships today; anything unbuilt is marked. Concepts
-rw-rw-r-- content:content /docs/concepts/password-policy.dtmpl ● verified against v2.0

The password policy

Every password the platform accepts passes through one policy, and every path that sets a credential reads it — the registration form, an administrator setting someone's password, the elevation password, the CLI. There is no second implementation for the command line to drift from.

Length and a breached list, not a shape#

The rule is length plus a check against a list of breached passwords. Composition rules — must contain an uppercase letter, a digit, a symbol — are off by default, and nothing in the platform turns them on.

That is a deliberate reversal of the older model, for a reason worth stating: composition rules produce Password1! — an uppercase, a digit, a symbol, every box ticked, and first out of any cracking dictionary. They reject a shape, not a guess. The breached-list check is the only rule here that rejects a password because it is guessable rather than because of how it is spelled, which is why it is the one that matters. Length does the rest: a long passphrase beats a short scrambled string, and it is easier to remember.

The composition switches exist only because an operator may be obliged to tick a box for an auditor. They default to off and are left off.

Two floors#

There are two minimum lengths, because two kinds of account carry different risk:

account floor why
a person's 12 a length someone will actually choose and remember
a system account 16 machines do not type theirs, and a system account's reach is wider

A system account is one a module writes as (see Identity), not a person; it never sits at a login form, so its longer floor costs nobody convenience and closes more.

What an operator sets, and what needs a shell#

The floors, the composition switches and whether the breached-list check is required are runtime settings — the identity.password block. An operator changes them on the settings screen, and the change takes effect on the next password that is set; no restart. Each has an environment fallback (COOLMS_PASSWORD_MIN_LENGTH, COOLMS_PASSWORD_SYSTEM_MIN_LENGTH) that a deployment can pin, in which case the screen shows the value as set by the environment and refuses to store an edit — the precedence the Settings page describes.

One part is not a screen. The breached-password corpus is fetched by a command, and only by a command:

docker exec coolms_app php bin/console coolms:identity:fetch-breached-list

It downloads the list once; after that the check runs offline, against the local copy, so no password an operator or a user types is ever sent anywhere. Until the list has been fetched, the breached-list check has nothing to test against — which is why fetching it is an install-time act an operator does at a shell, not something a running system reaches for on its own.