markup/fallback-password-encoder-bundle
Symfony bundle adding a fallback password encoder so users with legacy or unsupported hashes can still log in. It verifies old credentials and transparently rehashes them with your modern encoder after a successful login, easing migrations without forcing password resets.
needs_rehash flags, "legacy account" segments, progressive hardening at login, and risk-based step-up auth for users who haven't rotated credentials since the migration.Consider the pattern if:
Look elsewhere — or, more likely, just implement it — if:
Hash::check() plus Hash::needsRehash()/Hash::make() covers the transparent-upgrade loop in a few lines, and custom drivers cover exotic legacy schemes.MigratingPasswordEncoder and PasswordUpgraderInterface. The framework absorbed this exact pattern years ago; adding a third-party bundle for it is strictly worse.Adoption preconditions if you insist on the dependency: pin the commit, vendor it into your repo, add a test corpus of real legacy hashes, and assign an owner. Otherwise, budget the half-day to reimplement.
To executives — frame it as a migration cost, not a dependency request. "We have users whose passwords are stored in an obsolete format. The default plan is to email everyone and force a reset. That costs us a campaign, a support surge, and measurable login attrition among exactly the users we least want to lose. The alternative is that we upgrade their credentials silently the next time they log in — the user notices nothing, and we close the security gap within a normal login cycle. The engineering cost is small: days, not a quarter. I'm recommending the silent-upgrade path and explicitly not recommending we take on a new third-party dependency to do it."
To engineering — be precise about what you want and what you don't.
"This package is a Symfony bundle, so it doesn't apply to us directly, and with 6 stars and no dependents I wouldn't put it in the auth path regardless. What I want is the pattern it implements: an ordered chain of encoders, attempt each on login, and when a legacy encoder succeeds, immediately re-encode with the modern one and persist it. In Laravel that's Hash::check + Hash::needsRehash inside the login flow; the work is defining one driver per legacy scheme and writing a test fixture for each. Deliverable: legacy users transparently migrate to Argon2id/bcrypt over their next N logins, with a dashboard showing the shrinking needs_rehash cohort. Please treat the linked repo as documentation, not as a dependency."
To security/compliance — pre-empt the objection. "No third-party code enters the authentication path; we implement and own the logic, and it's covered by our normal review and patch process. The upgrade is per-login and idempotent. Users who never return retain a legacy hash, which is a known, tracked residual — we can set a policy date to force-reset the remainder if that's required. We keep the old encoders only as long as the residual cohort exists, then delete them."
One-line version: Skip the package, keep the idea — buy yourself a silent credential migration instead of a forced password reset campaign.
How can I help you explore Laravel packages today?