DEV Community

DHg
DHg

Posted on

Modern password policy 2026: stop Password@1

If you remember one thing from this post: password security is mostly won by (1) length + uniqueness and (2) server-side defenses. Complexity rules and forced rotation mostly make people choose more predictable passwords.

This is for devs building or fixing a login system. A copyable policy and the reasoning behind each rule.


TL;DR: the policy you can ship today

  • Min length: 12 when password is the only factor, 8+ if used alongside MFA.
  • Max length: allow at least 64 characters.
  • No composition rules. Don't force "upper + lower + number + symbol."
  • No periodic rotation. Only reset on compromise evidence.
  • Blocklist: reject common, expected, and compromised passwords.
  • UX that helps: allow paste, support password managers, offer "show password."
  • No password hints, no security questions.
  • Rate-limit failed logins.

These align with NIST SP 800-63B. Not a loose interpretation. This is what the standard actually recommends.


Why legacy rules fail

You've probably inherited a policy like this: minimum 8 characters, must include a symbol and uppercase letter, expires every 90 days, security questions for recovery.

It looks secure on paper. In practice, it trains users to do exactly the wrong thing. They pick a base password like Password@1 and increment the number every quarter. They reuse it across services. The "complexity" is a pattern attackers already guess early.

When I built auth for Inner Anchor, I could have gone with the standard 8-char-plus-symbol approach. But I'd seen what that produces in real systems: a wall of P@ssw0rd variants in breach dumps. So I went a different direction.


The rules, and why

1. Minimum length: 12 characters

NIST's baseline is 8. I recommend 12 for password-only auth because it pushes users past the "single word + mutation" pattern and into passphrase territory. Something like mycat sleeps a lot is 20 characters, easy to remember, and orders of magnitude harder to crack than C@tLover1.

For Inner Anchor, I set the minimum at 12. No complaints from users. Most password managers generate 16+ anyway, so the floor rarely matters for people doing the right thing. It mainly catches the people who would otherwise submit hello123.

If your app requires MFA, 8 is a reasonable floor since the password isn't the only barrier.

2. Max length: at least 64 characters

Password managers generate long random strings. Passphrases are naturally long. If you cap at 16 or 20 characters, you're punishing the users with the best security habits.

Allow at least 64. Set an upper bound you can afford to hash (128 or 256 is reasonable) so nobody can DoS your server with a 10MB password.

3. No composition rules

When you force "must contain uppercase, number, and symbol," users converge on the same patterns: capital first letter, number at the end, ! at the end. Attackers know this. They try those patterns first.

Drop the rules. Require length and a blocklist instead. You get less predictability, not more.

Some security teams will push back on this. Point them to NIST SP 800-63B, which explicitly says not to impose composition rules.

4. No periodic forced rotation

Expiring passwords every 90 days creates incrementing passwords and more reuse. Users treat passwords as disposable when they know it's temporary.

Instead, force a reset only when you have evidence of compromise: a breach match, a suspicious login, a leaked credential report. This means you need monitoring and an incident response flow, but you needed those anyway.

5. Blocklist checks

Reject passwords that appear in breach corpuses, common password lists, dictionary words, and context-specific terms (your app name, the user's email handle, obvious derivatives).

This is the hardest part to implement well. You can check passwords against the Have I Been Pwned API using k-anonymity (you send a partial hash, not the actual password). For a local check, a bloom filter over a breach corpus works. Either way, keep a generic rejection message like "this password is too common" rather than revealing why it was blocked.

6. Support password managers

This means: allow paste in password fields, set proper autocomplete attributes (new-password for signup, current-password for login), and offer a "show password" toggle.

Password managers are one of the few things that reliably improve password security at scale. Blocking paste actively prevents your best users from doing the right thing.

7. No hints, no security questions

"What was your first pet's name?" is guessable, researchable, and probably already in a data breach somewhere.

Use real recovery flows instead: email magic link with device confirmation, recovery codes generated at signup, or authenticator-based recovery. Recovery is usually the weakest link in any auth system. Removing security questions forces you to build something better.

8. Rate-limit failed attempts

Even a perfect password policy falls apart if attackers can try unlimited guesses. Rate-limit by account and by IP.

Prefer progressive delays over hard lockouts. Hard lockouts let attackers lock out real users on purpose. A backoff curve (short delay after 5 failures, longer delay after 10, CAPTCHA after 20) protects accounts without creating a denial-of-service vector.


Hash passwords with Argon2id

This isn't optional. If your database leaks and passwords are in plaintext or weak hashes (MD5, SHA-256 without salt), every account is compromised instantly.

Use Argon2id. It's memory-hard, which means attackers can't just throw GPUs at it. OWASP has a cheat sheet with recommended parameters.

For Inner Anchor, I use Argon2id with tuned parameters for my server's resources. The key idea: pick settings that take around 200-500ms on your hardware. That's invisible to a user logging in once, but brutal for an attacker trying millions of hashes.

If you're currently on bcrypt, that's still acceptable. But if you're building from scratch in 2026, go with Argon2id.


What you trade off

Longer minimums can frustrate some users. Mitigate this with passphrase examples during signup ("try a short sentence instead of a complex word") and password manager support.

Blocklists require maintenance. You need to update your breach corpus periodically and handle the privacy implications carefully. Never log raw passwords, even rejected ones.

No forced rotation means you must actually detect compromise. If you drop rotation without adding monitoring, you've made things worse, not better.

Rate limiting can be weaponized. An attacker could trigger delays for a real user. Risk-based scoring (device fingerprint, geo, behavior) helps, but adds complexity.


Further reading


If you're shipping auth this week, start with the TL;DR. Get the minimum length, blocklist, and Argon2id hashing in place. That alone puts you ahead of most apps still running 8 chars + symbol + 90-day rotation. The rest you can layer in as you go.

Top comments (0)