Password policy and recovery security
Typed password policy replaces an administrator-written regular expression with understandable, independently configurable rules. It also provides versioned recommendations, bounded evaluation, Unicode-aware length handling, common-password screening, and a self-describing PBKDF2 hash format.
Why typed policy is safer
A regular expression can express almost anything, but it does not tell an administrator or user which rule failed. Complex expressions can also consume excessive CPU, behave differently from client-side validation, and encourage composition rules that produce predictable passwords.
Typed policy gives each requirement a name, range, default, and stable API representation. ProAuth remains the final authority: browser guidance may describe the policy, but password creation and replacement always run the server evaluator.
Existing instances remain compatible
Existing UserStore IDP instances stay in PasswordPolicyMode=LegacyRegex until an administrator previews and applies typed options. Do not activate typed policy while an older ProAuth binary can serve traffic. Reverting to a pre-typed binary after new hashes or policies are active is unsupported.
Choose a recommendation
Recommendations are versioned presets that write concrete options. They are not permanent customer modes. Administrators can review every proposed value, apply a preset, and then adjust individual options if required.
| Recommendation | Use it when | Important qualification |
|---|---|---|
ConsumerBalanced-v1 | Passwords are a normal primary authenticator for public or general-purpose users. | Recommended default: minimum 15 characters, no composition rules, common-password screening, advisory strength feedback. |
WorkforceMfa-v1 | Every affected user is independently required to complete MFA or a passkey policy. | Lowers the minimum to 8 only for compatibility with an enforced second factor. Do not use for password-only access. |
PasswordlessFirst-v1 | Passwords remain temporarily while users move to passkeys. | Enforces the strength score for remaining passwords. Password prohibition comes from passkey policy. |
RegulatedHighAssurance-v1 | A regulated deployment still permits passwords and has benchmarked additional cost. | Uses 1,200,000 PBKDF2 iterations and enforced strength. Phishing resistance still requires passkeys or another suitable authenticator. |
If you are unsure
Use ConsumerBalanced-v1. Avoid uppercase, digit, and symbol requirements unless a contract or regulation explicitly requires them. Long passphrases, common-password rejection, throttling, and MFA provide better security and usability than arbitrary composition rules.
Inspect, preview, and apply
Management API v2 exposes the effective policy and recommendation workflow:
GET /api/management/v2/idpinstances/{idpInstanceId}/password-policy
POST /api/management/v2/idpinstances/{idpInstanceId}/password-policy/preview
GET /api/management/v2/idpinstances/{idpInstanceId}/password-policy/recommendations
POST /api/management/v2/idpinstances/{idpInstanceId}/password-policy/recommendations/{recommendationId}/versions/{version}/preview
POST /api/management/v2/idpinstances/{idpInstanceId}/password-policy/recommendations/applyThe generic preview overlays proposed name/value pairs without persisting them and reports cross-option validation errors. Recommendation preview also reports the current value, proposed value, option ID, concurrency token, warnings, recommendation fingerprint, and inventory fingerprint.
Apply requires both fingerprints and AllServingNodesCurrentAttestation=true. If the option inventory changes after preview, ProAuth returns a conflict and the administrator must preview again.
Compatibility mode
PasswordPolicyMode=LegacyRegex preserves PasswordComplexityPolicyRegex. ProAuth does not try to translate an arbitrary expression because a translation could silently weaken or change its meaning.
| Option | Valid values | Default | Purpose |
|---|---|---|---|
PasswordPolicyMode | LegacyRegex, Typed | LegacyRegex for existing instances | Selects the runtime evaluator. |
PasswordComplexityPolicyRegex | Valid .NET regular expression | Existing configured value | Complete legacy rule. Used only in LegacyRegex mode. |
LegacyPasswordRegexTimeoutMilliseconds | 10–1000 | 250 | Hard timeout for each legacy match. A timeout rejects the password. |
Existing password hashes cannot reveal whether their original plaintext satisfies a new content rule. Typed policy applies when a password is created, changed, reset, or successfully supplied for reevaluation and rehash. Migration tooling must never claim that hashes were content-validated.
Complete typed-policy option reference
All values are scoped to the UserStore IDP instance. Length is measured in Unicode code points after NFC normalization; UTF-8 bytes are bounded separately before expensive hashing.
Length and normalization
| Option | Valid values | Default | Guidance |
|---|---|---|---|
PasswordMinimumLength | 8–128 | 15 | Use 15 for password-only or general access. Use 8 only with independently enforced MFA. |
PasswordMaximumLength | 64–1024, and not below the minimum | 128 | Keep at least 64 so password managers and passphrases work. |
PasswordMaximumUtf8Bytes | 256–4096 | 1024 | Bounds memory, storage, and hashing cost for large Unicode input. |
PasswordUnicodeNormalization | NFC | NFC | The only supported normalization. The normalized value is evaluated and hashed. |
Spaces and printing Unicode are accepted. ProAuth does not silently trim the password before hashing.
Optional composition and pattern checks
| Option | Valid values | Default | Guidance |
|---|---|---|---|
PasswordRequiredUppercaseCount | 0–10 | 0 | Leave at 0 unless required. |
PasswordRequiredLowercaseCount | 0–10 | 0 | Leave at 0 unless required. |
PasswordRequiredDigitCount | 0–10 | 0 | Leave at 0 unless required. |
PasswordRequiredSymbolCount | 0–10 | 0 | Leave at 0 unless required. Whitespace does not count as a symbol. |
PasswordMaximumRepeatedRun | 0, or 2–32 | 0 | 0 disables. A value of 3, for example, rejects a run of four equal characters. |
PasswordMinimumSequenceLengthToReject | 0, or 3–16 | 0 | 0 disables. Detects ascending or descending ASCII sequences. |
PasswordIdentityDerivedChecks | Flags None, Username, Email, Tenant, Profile | Username, Email, Tenant | Rejects passwords containing selected identity values of at least three characters. |
Pattern checks can create surprising rejections in passphrases and localized input. Enable them only when their support cost and false-positive behavior are acceptable.
Common-password and strength evaluation
| Option | Valid values | Default | Guidance |
|---|---|---|---|
PasswordLocalBlocklistEnabled | Boolean; must be true in typed mode | true | Rejects the bundled common-password catalog. It cannot be disabled in typed mode. |
PasswordBlocklistDatasetVersion | Immutable catalog identifier | proauth-common-v1 | Records the packaged dataset version in policy output and the fingerprint. Keep the shipped value unless the installed release documents another catalog. |
PasswordStrengthEstimatorMode | Disabled, Advisory, Enforce | Advisory | Advisory returns a score without rejecting solely on that score. Enforce applies the minimum. |
PasswordMinimumStrengthScore | 0–4 | 3 | Used as a rejection threshold only when mode is Enforce. |
The packaged proauth-common-v1 catalog screens common passwords locally. It is not an external breach service and does not claim that every compromised password is present. The built-in score is a bounded online estimate based on length and character diversity; it is guidance, not a cryptographic entropy measurement.
No password or password-derived value is sent to an external provider by these options.
Password storage options
Typed mode writes a versioned, self-describing PBKDF2-HMAC-SHA-256 envelope using System.Security.Cryptography.
| Option | Valid values | Default | Guidance |
|---|---|---|---|
PasswordHashAlgorithm | Pbkdf2HmacSha256V1 | fixed | Other values are rejected. |
PasswordHashIterations | 600000–10000000 | 600000 | Benchmark on the slowest production node under expected peak load before increasing. |
PasswordHashSaltBytes | 16–64 | 16 | Random salt stored in the envelope. |
PasswordHashOutputBytes | 32–64 | 32 | Derived hash length. |
AutomaticPasswordRehash | Boolean | true in recommendations | Rewrites a successfully verified legacy or lower-cost hash using current parameters. |
Legacy hash formats remain verify-only. A successful authentication can rehash the password; rollback never downgrades a hash. Increasing iterations affects login CPU and denial-of-service capacity, so test it together with layered abuse protection.
Activation metadata
These locked values are written by recommendation apply and are not normal administrator settings:
| Option | Meaning |
|---|---|
PasswordPolicyActivationFingerprint | Exact preview fingerprint that was applied. |
PasswordPolicyActivatedOn | UTC activation time. |
PasswordPolicyAllNodesCurrentAttested | Recorded all-serving-nodes-current attestation. |
They support audits and upgrade diagnostics. Editing them directly is unsupported.
Password reset and recovery
Password reset is a recovery operation, not a normal login. A mailbox proof never receives unlimited authority merely because the account also has a password.
The reset request returns an enumeration-safe response and applies abuse controls to known and unknown identifiers. For an eligible user, ProAuth creates a 256-bit random secret, stores only its SHA-256 digest, binds it to the UserStore user, authentication-security epoch, verified-contact snapshot, issue time, and expiry, and commits the protected notification intent in the same transaction.
Redemption verifies the digest in constant time and rejects the artifact after expiry, prior consumption, verified-contact change, authentication-security-epoch change, or an incompatible passwordless policy. Password replacement and consumption use one tracked transaction, so concurrent redemptions have one winner.
If PasskeyPasswordRecreationPolicy prohibits password recreation, reset cannot recreate a password. Users without an active verified PasswordRecovery contact must use another configured route such as a recovery code, temporary access pass, identity proofing, or governed administrator recovery.
See Verified security contacts and Passkey security operations.
Security effects and operations
Password change, reset, recreation, relevant contact change, recovery, and administrative security changes advance the appropriate UserStore epoch or scoped revocation cutoff. Older authentication artifacts fail validation, and renewable grants are revoked according to scope.
Before production activation:
- preview the recommendation and retain its warnings;
- benchmark PBKDF2 under peak authentication and attack load;
- test localized guidance for every enabled rule;
- confirm Account Management and custom clients render the effective v2 policy rather than copying rules;
- confirm that all serving nodes run the coordinated version and review the documented rollback restrictions;
- monitor policy failure codes, rehash duration, reset delivery, reset replay rejection, and epoch invalidation.