How I Would Fix exposed API keys and missing auth in a Vercel AI SDK and OpenAI client portal Using Launch Ready.
The symptom is usually blunt: someone finds your OpenAI key in the browser bundle, a network request, or a public repo, and the portal also lets...
How I Would Fix exposed API keys and missing auth in a Vercel AI SDK and OpenAI client portal Using Launch Ready
The symptom is usually blunt: someone finds your OpenAI key in the browser bundle, a network request, or a public repo, and the portal also lets unauthenticated users hit AI features or view client data. In business terms, that means surprise API bills, customer data exposure, broken trust, and a very real chance of having to pause the product before launch.
The most likely root cause is simple: the app was built fast, but server-side boundaries were not enforced. The first thing I would inspect is where requests to OpenAI are actually being made, then I would trace whether auth is checked on every route that can read data, start a chat, or trigger tool calls.
Triage in the First Hour
1. Check the Vercel deployment logs for unusual request volume, repeated 401s or 403s, and any spikes in AI endpoint usage. 2. Inspect the browser Network tab and page source for any OpenAI key, bearer token, or secret-like string. 3. Review Vercel environment variables and confirm no secret is marked as public by mistake. 4. Audit all routes in the client portal that touch user data, AI prompts, file uploads, or billing. 5. Verify authentication middleware is actually protecting pages and API routes, not just hiding UI buttons. 6. Check recent Git commits for accidental secret commits or changes to auth logic. 7. Review OpenAI account usage for abnormal token consumption, unknown projects, or unexpected model calls. 8. Confirm Cloudflare and Vercel access logs are enabled so you can see who called what and when. 9. Check whether build output includes embedded secrets from client-side code or static generation. 10. If exposure is active, rotate keys before anything else.
A quick diagnostic command I often run locally is:
grep -R "sk-" . --exclude-dir=node_modules --exclude-dir=.next
That does not prove safety by itself, but it quickly catches obvious leaks in source files, build artifacts, and config.
Root Causes
| Likely cause | What it looks like | How I confirm it | |---|---|---| | OpenAI key used in client code | Key appears in browser bundle or network requests | Search source and built assets for `sk-`, inspect bundle output | | Missing auth on API routes | Anyone can call `/api/chat` or similar endpoints | Test endpoints without a session cookie or token | | UI-only access control | Buttons disappear for guests but endpoints still work | Call backend routes directly with curl/Postman | | Secrets stored as public env vars | Key available through `NEXT_PUBLIC_*` or equivalent | Review Vercel env names and app config | | Weak session handling | Users stay logged in too long or can reuse stale sessions | Inspect cookie flags, expiry settings, server validation | | Prompt/tooling path bypasses checks | AI tool calls happen before authorization | Trace request flow from page load to tool execution |
The most common failure I see in AI-built portals is this: the founder protected the screen but not the action. That creates a false sense of security because the app looks locked down while the backend still accepts direct requests.
The Fix Plan
My priority is to stop exposure first, then repair auth boundaries without breaking legitimate users.
1. Rotate every exposed secret immediately.
- Replace OpenAI keys.
- Rotate any related database credentials, webhook secrets, and third-party tokens if they may have been exposed too.
- Revoke old keys rather than leaving them active "just in case".
2. Move all OpenAI calls to server-side only.
- Use Vercel serverless functions or route handlers as the only place where the OpenAI SDK runs.
- Keep secrets in server environment variables only.
- Never pass raw API keys to the browser.
3. Add hard authentication checks on every sensitive route.
- Protect page routes that show client data.
- Protect API routes that read records, create messages, upload files, or trigger AI actions.
- Enforce auth on the server even if the frontend already checks it.
4. Add authorization checks per tenant or per user.
- A logged-in user should only see their own portal records.
- Every record fetch should verify ownership or role-based access.
- Do not trust IDs coming from the browser.
5. Lock down prompt and tool execution paths.
- Only authenticated users should reach AI tools.
- Validate inputs before sending them to OpenAI.
- Block any tool action that can mutate data unless permissions are explicit.
6. Tighten deployment and environment handling in Vercel.
- Separate preview and production env vars.
- Audit which variables are exposed to client code through naming conventions.
- Remove unused secrets from all environments.
7. Add rate limits and abuse controls.
- Rate limit chat endpoints per user and per IP.
- Add request size limits for file uploads and prompt payloads.
- Return safe errors instead of detailed stack traces.
8. Add monitoring so you know if this happens again.
- Alert on unusual token spend from OpenAI usage dashboards.
- Alert on spikes in 401s, 403s, 429s, and 5xx responses.
- Log auth failures without storing sensitive prompt content.
A safe implementation pattern looks like this:
// app/api/chat/route.ts
import { NextResponse } from "next/server";
export async function POST(req: Request) {
const session = await getServerSession();
if (!session?.user?.id) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const body = await req.json();
if (!body.message || body.message.length > 4000) {
return NextResponse.json({ error: "Invalid input" }, { status: 400 });
}
// Call OpenAI only here on the server
return streamChatResponse(body.message, session.user.id);
}The point is not just to make it work again. The point is to make sure there is no path where an unauthenticated browser can talk directly to your AI provider or your private data layer.
Regression Tests Before Redeploy
Before I ship this fix, I want proof that both security and usability still hold up.
- Unauthenticated user cannot access protected pages or API routes.
- Authenticated user cannot access another user's portal records by changing an ID in the URL or payload.
- No OpenAI key appears in browser source code, JS bundles, network requests, logs, or error pages.
- All AI requests are rejected if session validation fails.
- Rate limiting returns clean 429 responses after threshold abuse attempts.
- Existing portal flows still work for valid users on desktop and mobile.
- Error states show a clear message instead of exposing stack traces or internal IDs.
Acceptance criteria I would use:
- Zero secrets present in client bundles after build review.
- All sensitive endpoints return 401/403 when no valid session exists.
- p95 response time for chat endpoints stays under 800 ms excluding model latency overhead where possible; if streaming is used, first token should arrive fast enough to feel responsive within about 1 second on normal connections.
- Lighthouse score stays above 85 on key portal pages after adding auth middleware and monitoring scripts only where needed.
I would also run one manual red-team pass with safe checks:
- Try direct endpoint calls without login
- Try stale cookies
- Try cross-account record access
- Try oversized payloads
- Try repeated requests fast enough to trigger rate limits
If any of those pass when they should fail, I do not redeploy yet.
Prevention
This issue usually comes back when teams rely on UI gates instead of backend enforcement. I would put guardrails in place at code review time so future changes do not reopen the hole.
- Require a security checklist for every PR touching auth or AI routes:
- Is auth checked server-side?
- Is authorization checked per record?
- Are secrets server-only?
- Are inputs validated?
- Are errors sanitized?
- Add automated scans for secret leakage:
- Pre-commit secret scanning
- CI checks against committed keys
- Build artifact review before release
- Keep observability tight:
- Log auth failures by route
- Track OpenAI spend daily
- Alert on sudden traffic spikes
- Monitor p95 latency and error rates
- Improve UX so users do not try weird workarounds:
- Clear login state handling
- Friendly expired-session messages
- Empty states that explain what happens next
- Loading states that do not tempt repeated clicks
- Reduce blast radius:
- Separate dev/staging/prod environments
- Use least privilege for database and third-party credentials
- Keep production secrets out of local docs and shared screenshots
If I were reviewing this system long term using a cyber security lens from roadmap.sh thinking patterns, I would treat auth as infrastructure rather than UI decoration.
When to Use Launch Ready
Launch Ready fits when you need me to stop exposure fast without turning your release into a months-long rebuild.
I would recommend Launch Ready if:
- You already have a working prototype
- You need production deployment fixed quickly
- You suspect secrets are exposed
- You want Cloudflare SSL caching DDoS protection set correctly
- You need monitoring before users hit the app
What you should prepare before I start: 1. Vercel access with admin rights 2. Domain registrar access 3. Cloudflare access if already connected 4. Git repository access 5. List of all environments: dev staging prod 6. Any current auth provider details such as Clerk Auth.js Supabase Firebase or custom sessions 7. A list of expected portal roles like admin staff client viewer
My goal in this sprint is simple: get you back to a deployable state with less risk than you started with.
Delivery Map
References
1. Roadmap.sh API Security Best Practices: https://roadmap.sh/api-security-best-practices 2. Roadmap.sh Cyber Security: https://roadmap.sh/cyber-security 3. Roadmap.sh Code Review Best Practices: https://roadmap.sh/code-review-best-practices 4. Vercel Environment Variables: https://vercel.com/docs/environment-variables 5. OpenAI API Security Best Practices: https://platform.openai.com/docs/guides/production-best-practices
---
Take the next step
If this is a problem in your product right now, here is what to do next:
- [Use the free Cyprian tools](/tools) - estimate cost, score app risk, check launch readiness, or pick the right service sprint.
- [Book a discovery call](/contact) - I will tell you honestly whether you need a sprint or if you can DIY the next step.
*Written by Cyprian Tinashe Aarons - senior full-stack and AI engineer helping founders rescue, launch, automate, and scale AI-built products.*
Cyprian Tinashe Aarons — Senior Full Stack & AI Engineer
Cyprian helps founders rescue, secure, deploy, and automate AI-built apps with production-grade engineering, launch systems, and AI integration.