fixes / launch-ready

How I Would Fix exposed API keys and missing auth in a Vercel AI SDK and OpenAI AI chatbot product Using Launch Ready.

The symptom is usually ugly and expensive: someone finds your OpenAI key in the browser bundle, the chatbot starts getting abused, usage spikes, and you...

How I Would Fix exposed API keys and missing auth in a Vercel AI SDK and OpenAI AI chatbot product Using Launch Ready

The symptom is usually ugly and expensive: someone finds your OpenAI key in the browser bundle, the chatbot starts getting abused, usage spikes, and you realize there is no real auth gate on the app. The most likely root cause is that the product was built fast with the Vercel AI SDK, but the team let client-side code talk to sensitive services directly or shipped a demo flow into production without access control.

The first thing I would inspect is the deployed app itself, not just the repo. I want to see what is actually public in the browser, which routes are exposed, whether the AI endpoint is protected, and whether secrets are already leaking through build output, source maps, logs, or env var misuse.

Triage in the First Hour

1. Check the live site in an incognito browser.

  • Try opening the chatbot without logging in.
  • See whether any chat actions work from a fresh session.
  • Confirm if there is a visible sign-in step or if anyone can use it.

2. Inspect browser network requests.

  • Look for direct calls to OpenAI from the client.
  • Confirm whether requests go through your own backend or Vercel route handler.
  • Check request headers for leaked keys or tokens.

3. Review Vercel deployment settings.

  • Open project env vars and confirm which values are set at build time vs runtime.
  • Check if any secret was accidentally prefixed with `NEXT_PUBLIC_`.
  • Review recent deployments for a version that introduced the leak.

4. Inspect logs and usage dashboards.

  • Check OpenAI usage for spikes, unfamiliar IP patterns, or abnormal token volume.
  • Review Vercel function logs for repeated unauthenticated requests.
  • Look for 401s, 403s, rate limit errors, or unusual prompt lengths.

5. Audit source files that handle chat.

  • Inspect route handlers, server actions, and any client components calling AI endpoints.
  • Search for hardcoded keys, copied `.env` values, or exposed config objects.
  • Verify that secrets are only read on the server.

6. Check auth and session flow.

  • Confirm whether login exists at all or is only cosmetic UI.
  • Test protected routes directly by URL.
  • Verify session expiry, cookie flags, and authorization checks on every request.

7. Freeze risky changes before touching code.

  • Pause new releases until access control is fixed.
  • Rotate any exposed API key immediately if it has been public.
  • Disable any high-cost model usage if abuse is ongoing.
## Quick local scan for accidental secret exposure
grep -R "sk-" . --exclude-dir=node_modules --exclude-dir=.next
grep -R "NEXT_PUBLIC_" . --exclude-dir=node_modules --exclude-dir=.next

Root Causes

1. The OpenAI key was used in client-side code.

  • Confirmation: search the frontend bundle and network tab for direct OpenAI requests or key-like strings.
  • Common sign: `NEXT_PUBLIC_OPENAI_API_KEY` or a similar variable appears anywhere outside server-only code.

2. The app has no real authentication layer.

  • Confirmation: open private routes in incognito and see if chat works without login.
  • Common sign: UI shows a login button but backend endpoints never check session state.

3. Authorization checks exist in UI only, not in API routes.

  • Confirmation: inspect server handlers for user/session validation before processing messages.
  • Common sign: blocked buttons on the page but direct POST requests still succeed.

4. Secrets were exposed through build artifacts or source maps.

  • Confirmation: inspect deployed JS bundles and sourcemaps for env values or endpoint details.
  • Common sign: debugging assets are publicly reachable in production.

5. Environment variables were misconfigured in Vercel.

  • Confirmation: compare local `.env`, Vercel project settings, preview envs, and production envs.
  • Common sign: build-time variables differ from runtime variables or were copied into public config.

6. Rate limiting and abuse controls were missing.

  • Confirmation: repeated refreshes or scripted requests generate unlimited completions with no throttling.
  • Common sign: one anonymous user can burn through budget within minutes.

The Fix Plan

My recommendation is simple: stop all public access to the AI endpoint first, then rebuild access control on the server side only. Do not try to patch this with frontend-only checks because those fail immediately once someone hits your route directly.

1. Rotate any exposed secrets right away.

  • Revoke the leaked OpenAI key and issue a new one.
  • Update all environments where it was used: local dev, preview, production, CI secrets manager if applicable.
  • Assume anything already deployed may have been copied.

2. Move all OpenAI calls behind a server-only boundary.

  • In a Vercel AI SDK app, keep model calls inside route handlers or server actions only.
  • Never expose provider keys to client components or public env vars.
  • Treat every client request as untrusted input.

3. Add real authentication before chat access.

  • Use a proper session system such as NextAuth/Auth.js, Clerk, Supabase Auth, or your existing identity layer if it already works well.
  • Require auth on both page render and API execution paths if this is not meant to be public-facing.
  • If this is a paid product, tie access to an account entitlement check rather than just login status.

4. Enforce authorization on every request to chat endpoints.

  • Check user identity server-side before creating completions or streaming responses.
  • Verify subscription state, org membership, workspace access, or trial limits as needed.
  • Return 401 for unauthenticated users and 403 for authenticated users without permission.

5. Add rate limits and abuse controls at the edge and application layer.

  • Limit requests per user, per IP, and per workspace where relevant.
  • Add basic prompt length caps so one request cannot create runaway cost exposure.
  • Block obvious automation patterns without harming normal users.

6. Sanitize logging so secrets do not end up in observability tools.

  • Never log raw API keys, full prompts containing personal data by default, or full auth tokens.

| Log | Keep | Drop | |---|---|---| | Request id | Yes | No | | User id | Yes | No | | Prompt length | Yes | No | | Full prompt text | Only when needed | Usually drop | | Authorization header | No | Yes |

7. Lock down deployment hygiene in Vercel and Cloudflare if used at the edge level later on as part of Launch Ready delivery: ```text Public pages -> auth check -> rate limit -> server route -> OpenAI ``` This order matters because once you let unauthenticated traffic reach model calls directly, you are paying for abuse even when nothing useful ships.

8. Remove accidental public exposure paths: + Delete source maps from production unless you truly need them publicly accessible + Audit static assets for embedded config + Confirm no secret values are baked into generated client code

9. Add environment separation properly: + Production key only in production + Preview key only in preview + Local dev uses developer-specific credentials where possible + Never reuse one shared high-privilege key across everything

Regression Tests Before Redeploy

I would not ship this fix until these checks pass:

1. Unauthenticated access test

  • Open chatbot pages in incognito without signing in.

Expected: blocked redirect to login or clear 401/403 response.

2. Direct endpoint test + Send a request directly to the AI route without cookies or session headers + Expected: denied before any model call occurs

3. Authorized happy path test + Sign in with a valid account + Send normal prompts + Expected: responses stream correctly with no broken UI states

4. Abuse test + Send repeated requests quickly from one account/IP + Expected: throttling activates before cost spikes

5. Secret leakage test + Search built assets and rendered HTML for `sk-`, bearer tokens, and env names + Expected: nothing sensitive appears client-side

6. Error handling test + Force an expired session and an invalid upstream response + Expected: user sees a safe error message; no stack trace leaks

7. Billing guardrail test + Confirm there is a hard cap alert on unexpected token usage + Expected: alert fires before runaway spend becomes material

Acceptance criteria I would use:

  • 100 percent of AI calls require valid server-side auth checks
  • Zero secrets visible in browser source or network responses
  • p95 API response time stays under 800 ms excluding model latency overhead where possible
  • No unauthenticated completion can be triggered from direct HTTP requests
  • Rate limiting triggers within 5 failed bursts per minute per user during testing

Prevention

The best prevention here is boring discipline applied early:

  • Security review before every deploy:

+ Check that no secret moved into client code + Check that every privileged route validates session plus authorization + Check that third-party packages did not introduce risky behavior

  • Code review rules:

+ Any file touching auth or AI calls needs senior review + No merge if environment variable scope is unclear + No merge if logs might contain secrets

  • Monitoring:

+ Alert on unusual token spend within 15 minutes + Alert on spikes in anonymous traffic hitting chat routes + Track function errors separately from model errors so failures are obvious

  • UX guardrails:

+ Make login state obvious before users start chatting + Show clear disabled states instead of letting unauthorized users hit dead ends + Explain quota limits upfront so users do not think the product is broken

  • Performance guardrails:

+ Cache non-sensitive pages at the edge where possible + Keep heavy dependencies out of client bundles so auth screens stay fast + Watch Core Web Vitals so security fixes do not create new conversion problems

  • Operational guardrails:

+ Use separate keys per environment + Rotate secrets on schedule every 60 to 90 days if practical + Maintain an incident checklist for leak response and rollback

When to Use Launch Ready

Use Launch Ready when you need me to turn a shaky AI prototype into something safe enough to ship publicly without creating support debt or surprise cloud bills.

This sprint fits best when:

  • Your chatbot already works but is not production-safe yet
  • You suspect exposed secrets or weak access control
  • You need domain setup, email DNS records, SSL, Cloudflare protection,

deployment hardening, and monitoring done fast instead of piecemeal over weeks

What I would want from you before starting:

  • Access to Vercel project settings and deployment history
  • Access to domain registrar and DNS provider like Cloudflare or Route53 if relevant
  • Current repo access plus any `.env.example` files you have already used internally
  • A list of who should have access to the product after launch
  • Any existing analytics tool so we can verify traffic after release

I handle DNS, redirects, subdomains, Cloudflare, SSL, caching, DDoS protection, SPF/DKIM/DMARC, production deployment, environment variables, secrets, uptime monitoring, and handover checklist so you are not guessing after launch.

If your issue includes exposed API keys plus missing auth, I would treat it as an urgent rescue rather than a normal polish task because every hour left open can mean more abuse, more cost, and more trust damage with users.

Delivery Map

References

  • https://roadmap.sh/cyber-security
  • https://roadmap.sh/api-security-best-practices
  • https://roadmap.sh/code-review-best-practices
  • https://sdk.vercel.ai/docs
  • 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.*

Next steps
About the author

Cyprian Tinashe AaronsSenior Full Stack & AI Engineer

Cyprian helps founders rescue, secure, deploy, and automate AI-built apps with production-grade engineering, launch systems, and AI integration.