Auth Was Supposed to Be the Easy Part: How Your Login System Became Your Biggest Liability
Photo: developer security login authentication code screen, via cdna.artstation.com
There's a moment every engineering team experiences. It's usually sometime around sprint three, maybe four, when someone says the words: "Auth should be pretty straightforward — we'll knock it out this week."
Nobody laughs. They should.
Authentication is one of those problems that looks like a weekend project until it absolutely isn't. You start with a username, a password, and a sessions table. You ship it. Users log in. Everything works. And then, slowly, the requests start coming in.
"Can we add Google sign-in?" "Our enterprise client needs SSO." "Legal says we need MFA for anyone with admin access." "We have to pass a SOC 2 audit by Q3."
Each ask is reasonable on its own. Together, they turn your clean little login flow into a distributed identity management system that nobody on your team is actually qualified to maintain.
The Iceberg Nobody Warned You About
Here's what teams typically think authentication involves: a login form, a forgot-password flow, maybe a JWT. Here's what authentication actually involves once you're six to twelve months into a real product:
- Password hashing, salting, and upgrade strategies when you switch algorithms
- Session management across multiple devices and tabs
- OAuth 2.0 flows for every third-party integration (and yes, every provider implements it slightly differently)
- SAML for enterprise SSO, which is a protocol that feels like it was designed specifically to punish you
- MFA via TOTP apps, SMS fallbacks, and backup codes
- Account recovery edge cases that are, ironically, the most common attack vector
- Token refresh logic that breaks in subtle ways under load
- Rate limiting and brute-force protection
- Audit logging for compliance
- Role-based access control that inevitably becomes attribute-based access control because someone needed a permission that didn't fit the model
None of this is exotic. This is just what modern auth looks like for a product that's actually growing. The problem isn't that teams don't know these requirements exist — it's that they don't account for them until they're already mid-crisis.
Where the Architecture Usually Falls Apart
The most common pattern we see: a team builds auth in-house, iterates on it reactively, and ends up with a system where the logic is split across three services, two middleware layers, and a utils/auth.js file that everyone is afraid to touch.
A few specific failure modes worth calling out:
The "we'll add MFA later" trap. Retrofitting multi-factor authentication onto a session system that wasn't designed for it is painful. Token storage, step-up authentication flows, remember-this-device logic — these all interact with your session model in ways that require architectural changes, not just feature additions.
OAuth as an afterthought. Adding Google or GitHub login after the fact means you now have two parallel identity systems. Users who signed up with email and later try to use Google SSO with the same address hit edge cases your code probably doesn't handle gracefully. Merging accounts is a nightmare. Duplicate records are a compliance risk.
The SSO integration that takes three sprints. Enterprise clients want SAML-based SSO. Your team has never implemented SAML. You spend two weeks reading the spec, one week debugging certificate mismatches, and ship something that works for exactly one IdP. The next enterprise client uses a different one.
Compliance requirements that arrive after the architecture is set. SOC 2, HIPAA, FedRAMP — each has specific requirements around session timeouts, audit logs, password policies, and token handling. If your auth system wasn't built with these in mind, retrofitting them is expensive and often requires changes that touch every service in your stack.
The Build vs. Buy Calculation Nobody Does Honestly
At some point, most teams face the question: do we keep maintaining this ourselves, or do we move to a dedicated auth platform?
The honest version of this calculation is harder than it looks, because the cost of building isn't just engineering hours. It's also:
- The security expertise you probably don't have in-house
- The ongoing maintenance burden as standards evolve (OAuth 2.1, passkeys, WebAuthn)
- The liability exposure when something goes wrong
- The opportunity cost of senior engineers spending time on identity plumbing instead of product
Dedicated auth platforms — Auth0, Clerk, Okta, AWS Cognito, WorkOS for enterprise — have real tradeoffs too. Vendor lock-in is legitimate. Pricing can get spiky at scale. Customization has limits. But for most teams, the break-even point where building in-house makes sense is much later than they assume.
The teams that benefit most from building their own auth are typically those with highly specific compliance requirements, unusual scale characteristics, or deep security expertise already on staff. If that's not you, the buy side of the ledger deserves a much harder look than it usually gets.
How to Audit What You've Already Built
If you're already living with a homegrown auth system, the question isn't whether to feel bad about it — it's how to assess the actual risk and prioritize the work.
Start here:
Map every entry point. Where can a user authenticate? Web app, mobile, API tokens, service-to-service? Every entry point is a surface area. Are they all using the same underlying logic, or have they diverged?
Check your token lifecycle. How long do access tokens live? Are refresh tokens rotated? What happens when a user changes their password — are existing sessions invalidated? These are basic hygiene questions that many systems fail.
Look at your account recovery flow. Password reset emails, magic links, backup codes — these are frequently the weakest link. A reset link that doesn't expire, or a recovery flow that leaks user enumeration, can undermine everything else you've built.
Audit your dependency chain. If you're using libraries for JWT handling, OAuth, or password hashing, when were they last updated? Are you on versions with known CVEs? Auth dependencies that drift are a quiet risk.
Review your logging. Can you answer "who logged in from where, and when" for any user, for the past 90 days? If not, you have a compliance gap that's worth fixing before an auditor finds it for you.
The Part Nobody Wants to Hear
Authentication is infrastructure. It's not a feature. It doesn't show up in demos. Users don't tweet about how smooth your login flow is — they tweet about the breach when it goes wrong.
The teams that treat auth as a first-class architectural concern tend to make one of two choices early: they invest heavily in building it right, with real security expertise involved, or they outsource it to a platform that's already done that work. What they don't do is treat it as a sprint task that can be figured out incrementally.
If your auth system has grown organically over the past year or two, it's probably time to spend a week doing nothing but mapping what you have. You'll find surprises. Some of them will be uncomfortable. But finding them yourself is significantly cheaper than the alternative.
Your login form was never simple. You just hadn't met all its requirements yet.