So You Vibe-Coded a Legaltech App? Part 1: Authentication
You did it. You described what you wanted to an AI coding tool and now you have a working legal tech application. Maybe it's a document analyzer or a case timeline generator. Whatever it is, it works. At least on your laptop.
Now you want to share it with someone else. A colleague. A client. Your firm's IT department. And suddenly you realize anyone with the URL can access your creation. No login. No password. Just vibes.
Welcome to the authentication problem. This is the first in a series about the infrastructure decisions that separate a cool demo from a deployable tool. Today: making sure only the right people can access your app.
Your Options
Authentication ranges from "embarrassingly simple" to "enterprise-grade." The good news? For most legal tech apps, you don't need to start at the complex end.
Option 1: The Hardcoded Password
Security folks will wince, but this works fine for certain cases. If only you and a couple colleagues will ever use it, a simple password check might be all you need.
Store a password in your environment configuration (not in your code!) and check user input against it. Set something like APP_PASSWORD=your-secret-here in a .env file and you're done.
Works for: Personal tools, internal utilities, prototypes, low-sensitivity data.
Doesn't work for: Anything with client data, anything needing audit trails, anything beyond a small group.
Keep passwords out of your code repository. I've seen way too many API keys committed to public repos. Don't be that person.
Option 2: HTTP Basic Authentication
One of the oldest auth mechanisms on the web. Visit a protected page, your browser pops up a dialog for username and password. Done.
For Node.js apps, the express-basic-auth package makes this trivial. A few lines of config and you're protected.
The appeal: zero frontend work. No login forms, no session management. The browser handles everything.
The downside: no logout (browser remembers until you close it), no way to expire access, and the UX feels like the 1990s. Because it is.
Works for: Internal tools, simple API protection, infrequent access scenarios.
Option 3: Database Authentication
Build your own system with a database backend. You store users in a table with their email and hashed password (never plain text!). When someone logs in, you check their password against the hash and create a session.
Frameworks like NextAuth.js (now Auth.js) handle most of the hard work. If you're using Supabase or Neon, their built-in auth features integrate with your existing database.
This gives you full control: custom registration, role-based permissions matching your firm's structure, and audit logs of who accessed what.
The responsibility is significant, though. Password resets, session handling, account lockouts. Each is a potential security hole if done wrong.
Works for: Apps needing user management where you want full control.
Option 4: The Big Providers (Clerk and Auth0)
When you want someone else to handle the complexity entirely.
Clerk is the favorite for modern web apps, especially React and Next.js. You get pre-built login components, social login, multi-factor auth, and session management. Import the components, configure your keys, done. We use Clerk for all of our apps in case.dev and CaseMark and the free tier covers 10,000 monthly users.
Auth0 is the enterprise option. It supports SAML, LDAP, Active Directory. It has compliance certifications (SOC 2, HIPAA, GDPR) that matter when IT departments get involved. The tradeoff: steeper learning curve and pricing that can surprise you as you scale.
For most vibe-coded apps, Clerk is the pragmatic choice. Auth0 becomes relevant when enterprise requirements dictate.
Option 5: Better Auth with Architectural Templates
A middle path: Better Auth is open-source and gives you database-level control with the polish of Clerk. No vendor lock-in, no usage-based pricing surprises.
What makes it interesting for legal tech: pre-built templates for different app types.
- B2C — Consumer apps like will generators
- Single-org — Internal tools for one firm
- Multi-org SaaS — Products like Clio with firm isolation
- Marketplace — Platforms connecting attorneys with experts
- Cross-org collaboration — Deal rooms, multi-party discovery
- API platform — Legal AI APIs with key management
The templates include role structures that match how firms actually work: owner, partner, associate, paralegal, staff, client. You're not reinventing organizational structures the legal industry figured out decades ago.
Works for: Enterprise-grade auth without enterprise bills. Multi-tenant apps where data isolation matters. Situations where "we own our user data" is a procurement checkbox.
Doesn't work for: Immediate Active Directory integration (Auth0 is still your friend there).
In my experience, "we control our auth infrastructure" is an easier conversation with a law firm's security team than "we send your user data to this startup in San Francisco."
Making Your Decision
Ask yourself: Who uses this app, and how sensitive is the data? Is it internal or client-facing? Does your firm have existing identity systems? How much time do you want to spend on auth versus your actual functionality?
- Quick internal tools: Hardcoded passwords or basic auth
- User management with control: NextAuth or Supabase
- Client-facing with minimal overhead: Clerk
- Enterprise with existing systems: Auth0
- Enterprise features without vendor lock-in: Better Auth
Authentication is infrastructure, not a feature. Users don't choose your app because of the login screen. Ship something. You can always upgrade later.
Or, skip all of this. case.dev gives you production-ready legal tech infrastructure out of the box, and with Thurgood, our legal-first vibe-coding tool, you can build exactly what you want without worrying about the details. We're here to help you get your app over the finish line. Drop us a line at hello@casemark.com.
This is Part 1 of the "So You Vibe-Coded a Legaltech App?" series. Coming next: Storage, or where to put all those documents your users are uploading.

