Vibe code everything except your auth
The one layer of your app where 'seems to work' isn't good enough.
Vibe coding has a seductive pitch: describe what you want, let the LLM generate it, and ship. It works surprisingly well for UI components, one-off scripts, and prototypes you'll throw away next week. But there's one place it will significantly compromise your application's security: authentication.
Developers can prompt their way into homegrown auth systems that look correct, pass a few manual tests, and then quietly ship session management bugs, broken token validation, and password storage vulnerabilities straight to production.
The problem with vibe coded auth
When you vibe code auth, you're asking an LLM to synthesize patterns from training data: a mix of tutorials, Stack Overflow answers, outdated blog posts, and open source projects of wildly varying quality. The output looks plausible. It compiles. It might even handle the happy path.
Here's what it won't handle:
- Token expiration edge cases. The LLM doesn't know your session lifecycle requirements. It'll generate a JWT implementation that works until tokens expire mid-request, and then your users start seeing mysterious 401s with no token refresh logic to recover gracefully.
- CSRF and session fixation. Most generated auth code skips these entirely. The LLM doesn't think adversarially unless you specifically prompt it to, and even then it applies mitigations inconsistently. For example, it might add a CSRF token to login forms but omit it from state-changing endpoints.
- Password hashing. I've seen vibe coded auth that stores passwords in unsalted SHA-256. Not bcrypt. Not argon2. A single round of SHA-256 with no salt, which is vulnerable to precomputed rainbow table attacks and trivially brute-forced on modern GPUs.
- OAuth state parameter validation. Generated OAuth flows routinely skip the state parameter check, omitting the nonce comparison that prevents CSRF attacks on your login flow.
- Refresh token rotation. Almost never generated correctly. Token reuse detection, where the server invalidates an entire token family if a previously used refresh token is replayed, is consistently absent.
Auth is not a feature: it's infrastructure
The core issue isn't that LLMs are bad at code generation. The issue is that auth is a deceptively complex domain where the failure modes are invisible until they are exploited.
Authentication touches everything: session management, token storage, redirect handling, multi-factor enforcement, rate limiting, account lockout, email verification, password reset flows. Each of these has well-documented attack vectors and subtle correctness requirements.
Building this yourself, whether by hand or by prompt, means you're now responsible for maintaining it. Every CVE in your JWT library, every change to OAuth provider endpoints, every new compliance requirement your enterprise customers bring up. That's your problem now.
You didn't set out to build an auth company; you set out to build your product. The fix is to treat auth the way you treat your database or payments provider: as infrastructure you rent from a team whose full-time job is getting it right.
WorkOS CLI: Integrate AuthKit with one command
The WorkOS CLI is built for exactly this. It's an AI-powered installer for integrating and managing WorkOS from the terminal. Run one command and it handles everything: from framework detection and SDK installation, to environment setup and build validation. What you end up with is a full AuthKit integration that runs out of the box, not a scaffold you'll spend three days customizing.
To install the WorkOS CLI run:
Or, if you'd rather install globally:
The CLI analyzes your project and then:
- Detects your framework and version, down to router flavor (Next.js App Router vs Pages Router, Vite vs Create React App, React Router variants). 15 frameworks are supported across JavaScript/TypeScript, Python, Ruby, Go, .NET, Kotlin, Elixir, and PHP.
- Authenticates you by opening your browser for WorkOS sign-in. If you don't have an account yet, the CLI provisions a temporary environment you can claim later (for now available only for Next.js with more coming up soon).
- Configures your WorkOS dashboard: redirect URIs, CORS origins, and homepage URL.
- Installs the right SDK for your stack.
- Creates OAuth callback routes, auth middleware, and provider wrappers, composing with any existing middleware rather than replacing it.
- Writes your API keys to
.env.local, with masking and redaction from logs. - Validates the integration by running your build and feeding any errors back to the agent to fix.
The agent runs under restricted permissions. It can install packages, run builds, type-check, and run formatters; it cannot execute arbitrary shell commands. After it finishes, run git diff to review every line it changed.
The CLI also installs WorkOS Skills into your coding agent: a curated set of knowledge about WorkOS APIs, SDK patterns, and integration steps. Future auth changes your agent makes start from an informed baseline, with no prompt engineering or copy-pasting docs into context. Whether you're using Claude, Cursor, Codex, or another agent, it now has a working mental model of WorkOS.
If something drifts out of sync later, workos doctor inspects your project and flags common misconfigurations, in a format your agent can consume and act on rather than just display.
The security concerns WorkOS handles for you
Each of the pitfalls from earlier has a direct answer in AuthKit:
- Token expiration. Access tokens are short-lived (5 minutes by default), and the SDKs refresh them transparently, so expired tokens don't surface as mysterious 401s to your users.
- Refresh token rotation. Refresh tokens are single-use. Each refresh invalidates the old token and issues a new one, blocking the replay attacks that catch homegrown implementations.
- Secure session storage. Session cookies are encrypted ("sealed") with a strong key. Refresh tokens are stored in HttpOnly cookies, inaccessible to client-side JavaScript.
- JWT validation. Access tokens are signed JWTs, verified against a JWKS endpoint. The SDKs handle signature verification and key rotation for you.
- OAuth flow construction. Authorization URLs and code exchange are generated by the SDK (including PKCE for public clients like SPAs and mobile), so you're not hand-assembling the adversarial edges of an OAuth flow.
- Password storage. AuthKit stores credentials in its managed auth service. Passwords never touch your database, which means there's no way to ship unsalted SHA-256 to production by accident.
What you get on top
Beyond the security primitives, the product side is already built:
- SSO, passwordless, and social login out of the box. Google, GitHub, Microsoft, magic auth, passkeys, and SAML all come preconfigured.
- MFA support without building your own TOTP implementation.
- User management with a dashboard you don't have to build.
- Enterprise-ready features like SCIM provisioning, available when your first enterprise customer asks for them (and they will).
The math is simple
The time equation isn't complicated. Vibe coding a basic email + password auth system takes an afternoon. Getting it to production quality (handling edge cases, adding rate limiting, testing adversarial inputs, setting up email verification, building password reset) takes weeks of dedicated security-focused engineering. Maintaining it (tracking dependency CVEs, adapting to provider API changes, responding to pen test findings) is an ongoing cost with no end date.
Running workos install takes minutes. You get auth that's maintained by a team whose entire job is making auth work correctly. Security patches, compliance updates, and new features ship without you writing a line of code.
The opportunity cost of building auth is every feature you're not building while you're debugging why refresh tokens aren't rotating correctly.
Stop prompting, start shipping
Vibe coding is a useful tool with a specific blast radius. Use it for UI iterations, test data generation, and throwaway scripts. Don't use it for the system that protects your users' data.
The WorkOS CLI exists so you can get auth right in minutes and get back to the thing you actually care about: your product. Install it, run workos install, and move on to work that matters.
Common questions
What frameworks does the installer support?
15 at the moment, covering most major stacks: Next.js, React, React Router, TanStack Start, SvelteKit, Vanilla JavaScript, Node.js/Express, Python (Django), Ruby (Rails), Go, .NET (ASP.NET Core), Kotlin (Spring Boot), Elixir (Phoenix), PHP, and PHP/Laravel. The full list lives in the CLI docs.
The CLI didn't detect my framework
Pass it explicitly with the --integration flag:
Will it replace my existing middleware or auth code?
No. The installer is explicit about composing with existing configuration rather than replacing it. If you already have middleware or auth routes, it wires AuthKit in alongside them. The agent creates and modifies files, and you can see exactly what changed afterward with git diff.
Can I try it without creating a WorkOS account?
Yes. Run the installer without authenticating and the CLI provisions a temporary "unclaimed" environment you can use right away. When you're ready to keep it, run workos env claim to link it to a real WorkOS account. This flow is currently supported for Next.js, with more frameworks rolling out over time.
How do I see what the installer changed?
The installer modifies files in place. After it finishes, run git diff to review every line it added or changed. If anything looks off, revert it. Running the CLI on a clean working tree is a good habit for exactly this reason.
The build validation failed
The installer runs your build at the end to verify the integration compiles. If your project had pre-existing build errors, those will cause validation to fail too. Fix those first, or skip the check with --no-validate. You can also re-run with verbose logging:
Something else went wrong
Run workos doctor to diagnose common misconfigurations. If the problem persists, open an issue on the WorkOS CLI repo with the output from --debug mode attached.