Last updated: July 2026
Keycloak password policies are configured per realm under Authentication > Policies > Password Policy in the admin console. Modern best practice, per NIST SP 800-63B, favors a longer minimum length over forced complexity rules and periodic rotation, combined with blocking known-breached and blacklisted passwords. Keycloak 26.x supports length, not-username, not-email, password blacklist (file-based), regex pattern, expire-password, not-recently-used (history), and configurable hashing algorithm and iteration count out of the box — giving you everything needed to build a credential policy that holds up under real-world attack pressure without frustrating legitimate users.
Where password policies live in Keycloak
Every policy is scoped to a realm. Open the admin console, select your realm, then navigate to Authentication > Policies > Password Policy. The page presents an “Add policy” drop-down — each selection adds a configurable row. Click Save and the policy takes effect on the next password-set or change event. Existing hashes are re-hashed transparently at each subsequent login.
There is no global default that propagates across realms. For teams managing many realms programmatically, PUT /admin/realms/{realm}/ accepts a passwordPolicy string in the request body, enabling consistent baseline enforcement via Terraform or CI. See the Keycloak production-ready checklist for a broader view of realm-level hardening decisions.
Available policy types and how to configure each
Minimum length
Recommended setting: 12 characters, or 15+ for privileged accounts.
Length is the single most impactful factor in password strength against brute-force and dictionary attacks. A 12-character passphrase drawn from a modest vocabulary is far more resistant than an 8-character string with mixed case and symbols. NIST 800-63B dropped mandatory complexity in favor of length precisely because complexity requirements push users toward predictable substitution patterns (“P@ssw0rd1!”) while length increases the real search space.
Set the Minimum Length policy to 12 for standard user accounts. For realm-admin or service accounts, consider 15 or higher. Keep in mind that this is a floor — your UI should encourage passphrases, not just technically valid short strings.
Not-username and not-email
Add both. These are low-cost, high-signal checks that block one of the most common user behaviors: reusing the account identifier as the password. Keycloak’s check is case-insensitive, so Alice and alice are both rejected for a user whose username is alice.
These policies add no measurable latency and eliminate a trivially exploitable credential pattern. Always enable them.
Password blacklist
Keycloak supports a file-based password blacklist: a plain-text file with one password per line (UTF-8, lowercase), deployed to the Keycloak server and referenced by filename in the policy. When a user sets a password, Keycloak checks the candidate against the list after lowercasing it.
How to set it up:
- Obtain a common-passwords list — the SecLists Top 10 Million Passwords list or the Have I Been Pwned k-anonymity-safe top-N export are both practical sources. A list of 100,000–1,000,000 common strings covers the most dangerous candidates without ballooning file size.
- Lowercase every entry and remove duplicates:
tr '[:upper:]' '[:lower:]' < raw-list.txt | sort -u > blacklist.txt - Place the file at a path accessible to the Keycloak process. The default search path is
${jboss.server.data.dir}/password-blacklists/for legacy distributions; with Quarkus-based Keycloak 26.x, place the file under thedata/directory of your Keycloak installation or configure theKC_SPI_PASSWORD_POLICY_PASSWORD_BLACKLIST_BLACKLIST_FOLDERenvironment variable to point to your chosen directory. - In the admin console, add the
Password Blacklistpolicy and enter the filename (without path) as the value.
The blacklist check runs in-process with O(1) lookup via a bloom filter for large lists, so performance impact is negligible. This is not a substitute for real-time breached-password APIs, but it eliminates the most commonly sprayed passwords with zero external dependency.
Regex pattern
Use sparingly. Complex regex requirements encode the same counterproductive thinking that NIST moved away from: they force users into predictable patterns while offering minimal security gain. The only genuinely useful application is blocking specific strings relevant to your organization — company name variations, product names, or patterns from known breached datasets specific to your user base.
If you do use regex, keep it simple and document why. Example: ^(?!.*acmecorp).*$ to block the company name. Avoid multi-requirement regex like (?=.*[A-Z])(?=.*[0-9]) — this is the complexity-rule anti-pattern.
Expire password (periodic rotation)
NIST 800-63B explicitly advises against forced periodic rotation unless there is evidence or suspicion of compromise. Forced rotation drives users toward weak, sequential passwords (“Spring2026!”, “Summer2026!”) and increases support burden without meaningfully reducing breach risk.
Keycloak’s Expire Password policy sets a day-count after which users are forced to change their password at next login. If your compliance framework requires it (some PCI DSS interpretations, certain government standards), set the minimum interval your auditors will accept — typically 90 or 180 days. For most modern deployments, omit this policy entirely and rely on breach detection and MFA instead.
If you do set expiration, pair it with the not-recently-used policy to prevent immediate recycling.
Not-recently-used (password history)
The Not Recently Used policy takes an integer value representing the number of previous passwords Keycloak will reject. Keycloak stores hashed previous passwords and checks candidates against the history on each password change.
A value of 5 prevents the five most recent passwords from being reused. Combined with an expiration policy, this blocks the common pattern of cycling through passwords to get back to a favorite.
Even without expiration enabled, keeping not-recently-used at 3–5 is a useful guard against accidental reuse after a breach.
Hashing algorithm and iterations
Keycloak uses PBKDF2 as its default password hashing algorithm. The default configuration in Keycloak 26.x uses PBKDF2-HMAC-SHA256 with 210,000 iterations, which aligns with OWASP’s current recommended minimum for PBKDF2-SHA256. You can increase this value via the Hashing Iterations policy.
Argon2 is available in recent Keycloak versions (introduced as a supported algorithm in Keycloak 21+, configurable via the Hashing Algorithm policy). Argon2id is the current OWASP-recommended choice when memory-hard hashing is available, as it resists both GPU-based and side-channel attacks more effectively than PBKDF2. However, Argon2 requires tuning memory and parallelism parameters (m, t, p) and may have different performance characteristics depending on your JVM and infrastructure — test under realistic load before enabling in production.
Practical guidance:
- If staying with PBKDF2: ensure
Hashing Iterationsis set to at least210000for SHA-256. Increase to600000if your server hardware comfortably handles the latency. - If enabling Argon2id: use
m=64(MB RAM),t=3(time cost),p=4(parallelism) as a starting baseline, then benchmark against your expected concurrent login volume. - After changing iterations or switching algorithms, existing password hashes are automatically upgraded the next time each user logs in. No manual migration is needed.
Recommended baseline policy table
| Policy | Recommended Value | Notes |
|---|---|---|
| Minimum Length | 12 | 15+ for admin/service accounts |
| Not Username | Enabled | Always on |
| Not Email | Enabled | Always on |
| Password Blacklist | Enabled (100k+ word list) | Custom per organization |
| Regex Pattern | Disabled (unless specific need) | Avoid complexity rules |
| Expire Password | Disabled (unless compliance-mandated) | NIST advises against periodic rotation |
| Not Recently Used | 5 | Pair with expiration if enabled |
| Hashing Algorithm | PBKDF2 (default) or Argon2id | Test Argon2id before enabling in prod |
| Hashing Iterations | 210,000+ (PBKDF2-SHA256) | Increase if hardware allows |
The length-over-complexity rationale
NIST SP 800-63B makes the case directly: verifiers should not impose composition rules (requiring uppercase, numbers, or symbols) because those rules create predictable substitution patterns and increase cognitive burden without proportionally increasing entropy. A user forced to include a number and a symbol produces “Password1!” with regularity; a user encouraged to use a long passphrase produces “correct-horse-battery-staple” — which is far stronger and far more memorable.
The practical implication for Keycloak: set a meaningful minimum length (12+), add the blacklist and identity checks, and omit the complexity regex. For an in-depth look at the broader hardening picture, the Keycloak security audit hardening checklist covers password policy alongside network controls, token lifetimes, and session management.
Pairing password policy with MFA and brute-force protection
Password policy alone is not a complete credential-security strategy. Two additional controls are essential in any production Keycloak deployment:
Multi-factor authentication: Even a strong password policy is undermined by phishing. Requiring a second factor — TOTP, WebAuthn, or a hardware key — dramatically reduces the blast radius of a credential compromise. The multi-factor authentication integration patterns for enterprise applications guide covers conditional MFA flows Keycloak supports, including step-up authentication. For deployments ready to eliminate passwords entirely, Keycloak WebAuthn and passwordless with passkeys describes configuring FIDO2 passkeys as a primary authenticator.
Brute-force protection: Keycloak’s built-in brute-force detection (under Realm Settings > Security Defenses > Brute Force Detection) locks accounts after configurable failed attempts. IP-based rate limiting at the Keycloak layer has known gaps — the Keycloak brute-force IP-based protection gap post covers where native protection falls short and how to close the gap with a reverse proxy or WAF rule. A 12-character minimum with a blacklist plus lockout at 10 attempts with a 30-minute wait is a materially stronger combination than either control alone.
Testing your password policy
Before rolling out a new policy to production, run through these checks in a non-production realm:
- Attempt to set a blacklisted password — Keycloak should return a policy-violation error referencing the blacklist.
- Attempt passwords shorter than the minimum — verify the length error appears.
- Attempt to reuse the current password — verify history rejection if
not-recently-usedis set. - Check hash upgrade behavior: after increasing iterations, log in and confirm via
GET /admin/realms/{realm}/users/{id}/credentialsthat the hash reflects the new algorithm/count. - Load test under new hash settings: use Gatling or
abto ensure the increased iteration count keeps per-login latency under 300–500 ms.
The admin console also displays a real-time policy summary on the password-change form — a quick way to confirm your configuration is active.
Per-realm strategy: when one policy is not enough
Keycloak’s per-realm scoping lets you enforce different policies per audience:
- Master realm (admin access only): 20-character minimum, 10-entry history, Argon2id hashing, no expiration.
- Employee/workforce realm: 14-character minimum, blacklist enabled, MFA required, no expiration.
- Customer/B2C realm: 12-character minimum, blacklist enabled, not-username/not-email, MFA optional.
- Service account realm: Policy is less relevant for machine credentials — use client secrets or certificate auth and disable direct grants for human users.
The Keycloak production-ready checklist covers realm segmentation alongside other top-priority hardening decisions.
Frequently asked questions
How do I set a password policy in Keycloak?
Navigate to your realm in the Keycloak admin console, then go to Authentication > Policies > Password Policy. Use the “Add policy” drop-down to select each policy — each appears as a configurable row. Click Save. To apply policies via API, PUT /admin/realms/{realm} with passwordPolicy in the JSON body accepts a space-separated policy string: "length(12) notUsername notEmail hashAlgorithm(pbkdf2-sha256) hashIterations(210000) passwordHistory(5)".
Should Keycloak passwords expire?
For most deployments, no. NIST SP 800-63B recommends against forced periodic rotation because it drives users toward predictable cycling patterns without reducing breach risk. If you are subject to a compliance framework that mandates expiration (certain PCI DSS or government standards), set the minimum interval your auditors require and pair it with a password history of at least 5 to prevent immediate re-use. In all cases, invest in breach detection and MFA before relying on expiration as a security control.
Can Keycloak block breached passwords?
Keycloak supports a file-based password blacklist that rejects passwords found on the list at set/change time. This is not a real-time API check against live breach databases (like HIBP’s k-anonymity API), but a static file that you update periodically. To get closer to real-time breach blocking, you can wrap the credential-update flow with a custom SPI that calls the HIBP range API before allowing the password to be saved. Out of the box, the file-based blacklist is the supported mechanism.
What hashing algorithm does Keycloak use by default?
Keycloak 26.x defaults to PBKDF2-HMAC-SHA256 with 210,000 iterations. This meets OWASP’s current minimum recommendation for PBKDF2-SHA256. Argon2id is available as an alternative hashing algorithm in recent versions and is preferred by OWASP when memory-hard hashing is feasible, but it requires additional tuning and load testing before production enablement. You can change both the algorithm and iteration count via the Password Policy UI or the Admin API without requiring manual credential migration — hashes are upgraded transparently at next login.
How do I prevent users from using common passwords like “Password1”?
Enable the Password Blacklist policy and provide a file containing common and known-breached passwords (one per line, lowercase). Sources like the SecLists common-credentials lists or a HIBP top-N export work well. Place the file in Keycloak’s configured blacklist folder, reference it by filename in the policy, and Keycloak will reject any candidate that appears in the list after lowercasing. Combine this with a 12-character minimum length and the not-username/not-email policies for a solid baseline against credential stuffing and spray attacks.
Properly configured password policies are one layer in a defense-in-depth identity strategy. Combined with MFA, brute-force protection, and audit logging, they significantly raise the cost of credential-based attacks against your Keycloak-protected applications.
If you would rather skip the infrastructure work and focus on the policy itself, Skycloak’s managed Keycloak runs production-hardened Keycloak with sensible security defaults — including password policy, brute-force protection, and TLS — configured from day one.