Blog

All posts
John Damask · 2026-03-15
devlogsecurityarchitectureawsfeatures

Multi-factor authentication is one of those features that every developer knows they should implement but keeps putting off. It touches every layer of the stack -- backend auth logic, database schema, frontend UI flows, infrastructure, key management -- and the edge cases multiply fast. What happens when someone loses their phone? What if they want two authenticator apps? How do you rate-limit brute force attempts without locking out legitimate users during testing?

I'd been meaning to add MFA to the admin pages on Now I Get It! for a while. The admin dashboard and takedown management console were protected by a static token, which was fine as a starting point but not where I wanted to stay long-term. This week, I sat down with Claude and built the whole thing -- TOTP enrollment with QR codes, session management, recovery codes, multi-device support, and a complete lost-device recovery flow -- in a single afternoon.

What Got Built

The admin pages now require two-factor authentication using TOTP (Time-based One-Time Passwords) -- the same standard used by Google Authenticator, 1Password, Authy, and every major authenticator app. The existing token auth remains as the first layer. After entering the token, admins verify their identity with a 6-digit code from their authenticator app. A time-limited session keeps them logged in across browser tabs so they're not entering codes on every page load.

First-time setup walks admins through scanning a QR code, confirming the code works, and saving a set of one-time recovery codes for emergency access. You can register up to two authenticator apps in case you want redundancy across devices.

The Expected UX

The first working version required admins to manually copy a secret key into their authenticator app. It worked, but it didn't feel right -- every other service you add MFA to gives you a QR code to scan. I wanted the same experience - Claude on-shotted the solution. The setup wizard now displays a scannable QR code, with the manual key available as a fallback. Admins can register up to two authenticator apps -- a browser-based password manager like 1Password and a mobile app like Google Authenticator -- so there's always a backup device within reach.

Edge Cases Are Where Security Lives

The recovery flow -- what happens when someone loses their phone -- took several iterations to get right. The key insight was that recovery has to assume the lost device is compromised, so all previous credentials get invalidated when someone re-enrolls. AI is great at generating the initial implementation, but security flows like this really need a human walking through every scenario asking "what happens if..."

What AI Changes About Security Work

The reason MFA used to take a week is that it requires coordinated changes across many components, and every component has its own gotchas. You need to understand TOTP internals, session management patterns, rate limiting, recovery flows, cryptographic hashing, infrastructure-as-code for new database tables and API routes, and frontend state management. No single piece is hard, but the integration surface is large.

What's different with AI-assisted development is that the boilerplate and integration plumbing happen fast. The Lambda handler, the session validation module, the CloudFormation resources, the frontend UI components -- all of that came together quickly. That freed me to spend most of my time on the things that actually matter for security: thinking through edge cases, testing the recovery flow end-to-end, making sure credential invalidation is thorough, and verifying that rate limiting actually works under real conditions.

The lesson isn't that AI makes security easy -- it's that AI handles the mechanical parts so you can focus on the judgment calls. Security features have always been more about design decisions than lines of code, and that's still true. The difference is that now you can actually implement those decisions in an afternoon instead of a week.