The State of Authentication in Rails, March 2026
Rails 8 shipped a built-in authentication generator, but it only covers about 30% of what production apps need. Here's how it compares to Laravel, Django, and Better Auth.
Rails 8 shipped with something the community had been asking about for years: a
built-in authentication generator. Run bin/rails generate authentication and you get a User model, Session model, controllers,
views, migrations, and routes for session-based email/password login and password resets. No gems
needed, which is always nice but for me, as someone coming from other frameworks, this felt a bit
lacking.
I was starting a new project and had to go through this painpoint so I've finally decided to do a bit of an explore, comparing what rails offers vs what I'd reach for with other frameworks/tools.
What the generator gives you
The generator scaffolds a User model with has_secure_password, a
Session model that tracks tokens plus IP and user agent, a
SessionsController for login/logout, and a PasswordsController for reset
flows. Password hashing is bcrypt at cost factor 12 (basically the factor iterations on the hashing
operation). The reset token is signed and time-limited with no token stored in the database, which
is a nice touch.
Something I don't see people talk about enough: the generator tracks full session history.
Devise's trackable module only stores the most recent session info, but with the Rails
8 approach you get a sessions table you can actually query. That's useful if you need "sign out of
all devices" or want to do any kind of security auditing.
All the generated code lives in your app, so you can read it and change it. No black box.
What it doesn't do
The generator handles login and password resets for existing users. That's about it.
There's no signup. No registration controller, no sign-up form, no email confirmation. You write all of that yourself, which is strange given that every app needs it. I find this to be a weird overhead.
MFA isn't included at all. NIST has been pushing phishing-resistant MFA requirements, passkeys hit mainstream adoption in 2025, and the generator doesn't even stub out an optional path.
Social login (OAuth/OIDC with Google, GitHub, Apple, etc.) means manually integrating OmniAuth and wiring up account linking yourself. We miss out on the generator flag and basic convention here.
On top of those, that I consider quite important, we also don't have any account lockout strategies, rate limiting or email verification. This felt like a bit of a miss given the rails philosophy of "Convention over Configuration".
I'd estimate the generator covers about 30% of what a production auth system needs. The rest is on you, and it's the stuff that's hardest to get right.
The rest of the Rails auth ecosystem
The generator doesn't exist in isolation. Rails developers have been solving auth for two decades and there are real options.
Devise (my first introduction to rails auth) is still the most widely deployed auth gem. Registration, confirmation, account locking, OmniAuth, and a lot more. It's battle-tested and mature. The downside is that the internals can be opaque, and customizing flows sometimes means fighting the gem rather than working with it.
Rodauth takes a security-first approach with 60+ individually-enabled features: WebAuthn/passkeys, audit logging, JWT support, constant-time comparisons throughout. If you're building something in fintech or healthcare where auth auditing is non-negotiable, it's worth the steeper learning curve.
Authentication Zero is interesting because, like the Rails 8 generator, it scaffolds code directly into your app. But it actually includes registration, 2FA (TOTP and hardware keys), account lockout, recovery codes, activity logging, and pwned-password checking. It's closer to what you'd want to ship.
Then there are managed services like WorkOS AuthKit or Auth0 for teams that want to outsource auth entirely (SSO, SAML, SCIM provisioning, MFA).
How other frameworks handle this
We'll jump into a quick comparison with other frameworks that I consider similar:
Here's a quick overview of what you get out of the box before we get into the details:
| Feature | Rails 8 Generator | Laravel Breeze/Jetstream | Django contrib.auth | Better Auth |
|---|---|---|---|---|
| Login/logout | Yes | Yes | Yes | Yes |
| Signup/registration | No | Yes | Yes | Yes |
| Email verification | No | Yes | No | Yes |
| Password reset | Yes | Yes | Yes | Yes |
| Social login (OAuth) | No | Via Socialite | No | Yes |
| MFA/2FA | No | Yes (Jetstream) | No | Yes |
| Passkeys/WebAuthn | No | No | No | Yes |
| Session management | Yes | Yes (Jetstream) | Yes | Yes |
| Rate limiting | No | No | No | Yes |
| Account lockout | No | No | No | Yes |
| RBAC/permissions | No | No | Yes | Yes |
| Admin panel | No | No | Yes | No |
| First-party | Yes | Yes | Yes | No (third-party) |
Rails and Django both leave social login and MFA to third-party packages, but Django's base layer covers more ground. Laravel and Better Auth are the most complete options here, with Laravel having the advantage of being first-party and Better Auth covering the widest feature set overall.
Now the details:
Laravel
Laravel ships first-party starter kits. Breeze gives you login, registration, password reset, email verification, and password confirmation, all styled with Tailwind and published into your app. This is roughly what the Rails 8 generator would be if it included signup and email verification. Jetstream goes further with two-factor authentication, session management across devices, API token management via Sanctum, and optional team management.
What matters here is that the Laravel team maintains these. They're documented alongside the framework itself. You don't have to evaluate five different gems with different maintainers and figure out which one to go with. Breeze for simple apps, Jetstream for complex ones, done.
Django
Django's django.contrib.auth module ships with user models, authentication backends,
groups and permissions, password hashing with automatic algorithm upgrades, login/logout/password-change
views, and a full admin interface with permission management baked in. That admin panel alone is something
Rails has never matched without extra gems.
Django also doesn't include social login or MFA natively, but the base auth layer is significantly more complete than what Rails 8 generates.
Next.js / Better Auth
The JS auth ecosystem shifted in 2025. Auth.js (formerly NextAuth.js) was the de facto standard for years, but the Auth.js team officially joined Better Auth in September 2025. Auth.js still gets security patches, but Better Auth is what's recommended for new projects now.
Better Auth is TypeScript-first and framework-agnostic (Next.js, Nuxt, SvelteKit, Remix, Astro, Hono, Express, and others). Out of the box you get email/password with verification, social OAuth, passkeys/WebAuthn, two-factor auth (TOTP and SMS), session management, role-based access control, and rate limiting. Database adapters for Prisma and Drizzle, a CLI for generating schemas, and a plugin system for extending it.
It's still a third-party library, not built into Next.js. But the scope of what it ships by default makes the Rails 8 generator look like a proof of concept.
Where Rails falls short
Rails' built-in auth is the weakest of its peer frameworks for production use. The code the generator produces is secure and well-structured, but the scope is too narrow. There's no clear path from "I ran the generator" to "I have production auth."
The lack of a first-party "complete" option is the biggest issue. Laravel has Jetstream. Rails gives you login and password reset, then points you at a bunch of third-party gems with different maintainers and APIs. The "which auth gem should I use?" thread has been going for over a decade and the generator hasn't put it to rest.
No convention for social login either. OmniAuth works, but wiring it into the Rails 8 generator is manual. Compare that to Better Auth where adding a provider is one line in a config object.
The absence of MFA in 2026 is hard to defend. And an auth generator that doesn't include signup is just odd. Every developer who runs it immediately has to write registration by hand.
What Rails does well here
The generated code being yours is a real advantage. When something breaks at 2am you can just open the controller and read it instead of digging through gem internals.
Session tracking is better than what Devise gives you by default. You get IP and user agent logging in a queryable sessions table, which Devise's trackable module doesn't offer.
The security defaults are reasonable too: bcrypt at cost 12 and signed password-reset tokens that don't touch the database.
And honestly, for internal tools or apps where email/password login is all you need, the generator is great. It does that one thing well.
Recommendations
If you're starting a new Rails app today, what I'd reach for depends on the project. The built-in generator plus a hand-rolled registration controller works for MVPs and internal tools.
Devise is still the pragmatic pick for production apps that need the standard feature set (registration, email confirmation, social login), though Authentication Zero is worth a look if you prefer the generator approach. Rodauth is the strongest option in the Ruby ecosystem for anything security-sensitive.
For enterprise requirements like SSO, SAML, or SCIM, a managed solution like WorkOS or Auth0 makes more sense than building it yourself.
What comes next
The Rails 8 authentication generator acknowledged that auth matters enough to be part of the
framework, but it stopped short. A follow-up generator that covers registration, email
verification, and optional MFA would go a long way. Not a Devise replacement. Just enough to get
from rails new to production auth without reaching for a gem.
Laravel proved this approach works. Breeze and Jetstream cover the common path and stay out of your way. Rails could do the same.
This is supposed to be a basic overview on the state of Authentication in Rails, just a point of contention that I don't find with other frameworks that seems to break the Rails philosophies.
Note on AI usage: I used Gemini for header image and Claude for populating the emojis in the comparison table.