fixes / launch-ready

How I Would Fix exposed API keys and missing auth in a Bolt plus Vercel internal admin app Using Launch Ready.

The symptom is usually obvious: an internal admin app is live, someone can open it without signing in, and secrets are sitting in the client bundle,...

How I Would Fix exposed API keys and missing auth in a Bolt plus Vercel internal admin app Using Launch Ready

The symptom is usually obvious: an internal admin app is live, someone can open it without signing in, and secrets are sitting in the client bundle, network calls, or public repo history. In practice, the root cause is almost always the same: the app was built fast in Bolt, deployed to Vercel, and shipped before auth, secret handling, and environment boundaries were hardened.

The first thing I would inspect is not the UI. I would check the deployed Vercel environment, the client-side code for any hardcoded keys or public env vars, and whether every admin route has server-side authorization enforced before any data loads.

Triage in the First Hour

1. Confirm exposure scope.

  • Open the live app in an incognito window.
  • Check whether admin pages load without login.
  • View page source and browser devtools for API keys, tokens, or internal endpoints.

2. Inspect Vercel environment variables.

  • Review Production, Preview, and Development env vars.
  • Look for secrets accidentally prefixed with `NEXT_PUBLIC_` or equivalent client-exposed naming.

3. Check recent deploys and previews.

  • Identify the last deployment that introduced the leak.
  • Review preview URLs because they often expose unfinished auth paths.

4. Audit Bolt-generated files.

  • Search for hardcoded credentials in components, hooks, server actions, and utility files.
  • Check whether auth logic exists only in UI state instead of on the server.

5. Review logs and analytics.

  • Look for unauthorized access patterns.
  • Check Vercel logs, backend logs, and any API provider usage spikes.

6. Rotate anything exposed.

  • Revoke compromised API keys immediately.
  • Replace them before touching frontend code if there is any chance they were public.

7. Verify data access boundaries.

  • Confirm whether exposed keys can read or mutate production data.
  • If yes, treat this as a security incident, not just a bug.

8. Check DNS and deployment surface.

  • Make sure no staging subdomain or preview route is indexed or linked publicly.

A quick command I would run locally during diagnosis:

grep -RInE "sk-|api_key|secret|token|NEXT_PUBLIC_" .

That does not fix anything by itself. It just tells me how much cleanup I am dealing with before I change production behavior.

Root Causes

1. Secrets were placed in client-exposed variables.

  • How to confirm: search for `NEXT_PUBLIC_`, `VITE_`, or similar prefixes on values that should stay server-only.
  • Common pattern: a third-party API key works in development because it was copied into frontend code.

2. Auth exists only as a visual gate.

  • How to confirm: refresh a direct admin URL while logged out and see if data still loads from APIs.
  • Common pattern: the button says "Sign in", but backend routes return data regardless of session state.

3. Server-side authorization checks are missing.

  • How to confirm: inspect API routes or server actions for user/session validation before database queries or external calls.
  • Common pattern: any authenticated user can hit privileged endpoints because role checks were skipped.

4. Preview deployments inherited production secrets too broadly.

  • How to confirm: compare env vars across Production and Preview in Vercel.
  • Common pattern: every branch gets full access to live keys when only a limited test key should exist.

5. Bolt scaffolded insecure defaults into a rushed build.

  • How to confirm: look for placeholder auth wrappers, mock middleware, or client-only guards that never reached production quality.
  • Common pattern: the app "looked secure" during demo but never enforced security on the server.

6. Sensitive values were committed before secret scanning existed.

  • How to confirm: search git history and deployment artifacts for old key strings or config files.
  • Common pattern: even after deleting the file, the secret remains recoverable from history unless rotated.

The Fix Plan

My approach is simple: stop exposure first, then add real authorization, then redeploy with guardrails so this does not happen again.

1. Rotate every exposed secret immediately.

  • Revoke old API keys at the provider level.
  • Issue new keys with least privilege only.
  • If one key had broad access, split it into separate read-only and write-only credentials where possible.

2. Remove secrets from all client-facing code paths.

  • Move private keys into server-only environment variables.
  • Replace any frontend direct calls with server routes or server actions that proxy requests safely.

3. Add real authentication at the edge of protected routes.

  • Block access before rendering sensitive pages or fetching protected data.
  • Do not rely on hidden buttons or client redirects alone.

4. Add role-based authorization for admin functions.

  • Require an explicit admin role for destructive actions like edits, deletes, exports, billing changes, and integrations management.
  • Verify role claims on the server every time.

5. Lock down Vercel environment configuration.

  • Separate Production from Preview secrets clearly.
  • Use test-only credentials in preview environments whenever possible.
  • Remove anything public that should be private.

6. Add middleware or route protection where appropriate.

  • Protect `/admin`, `/dashboard`, `/api/admin/*`, and similar surfaces consistently.
  • Deny by default if session validation fails.

7. Harden third-party integrations behind your backend only.

  • If Bolt generated direct browser-to-provider calls, replace them with backend-mediated requests so keys never reach users' browsers.

8. Clean up deployment artifacts and caches after rotation.

  • Redeploy after invalidating old builds where needed because cached bundles can keep leaking old values briefly.

9. Add monitoring for suspicious access patterns now, not later.

  • Track 401s, 403s, unexpected admin traffic spikes, failed login bursts, and unusual API usage costs.

10. Document what changed in a handover checklist.

  • Record which secrets were rotated, which routes are protected, and who owns future key management.

Here is how I would think about it operationally:

The main trade-off is speed versus certainty. I would rather ship a slightly smaller fix that closes access control properly than keep risky functionality live while polishing unrelated UI issues.

Regression Tests Before Redeploy

I would not redeploy until these pass:

  • Anonymous user cannot open any admin page directly.
  • Anonymous user cannot call protected APIs successfully from devtools or curl without valid session context.
  • Non-admin user can sign in but cannot perform privileged actions like delete/export/settings changes.
  • Old exposed keys no longer authenticate anywhere after rotation complete over 100 percent of known services used by the app process flow; practically this means zero successful calls using retired credentials during verification windows).
  • Preview deployment uses safe test credentials only if it needs external integration access at all
  • Production build contains no `NEXT_PUBLIC_` values that should be private
  • Logout invalidates access cleanly
  • Reloading protected pages after session expiry sends users back to sign-in
  • Error states do not reveal stack traces or internal endpoint details
  • Logging captures denied attempts without exposing tokens or PII

Acceptance criteria I use:

  • 0 unauthorized reads of admin data
  • 0 unauthorized writes
  • 100 percent of privileged routes checked on server side
  • 100 percent of exposed secrets rotated
  • No secret values visible in browser network payloads or page source
  • p95 page load under 2 seconds on admin screens after fixes are applied
  • Build passes with no secret-scanning warnings left unresolved

I also want one manual QA pass from an incognito browser plus one scripted check against key endpoints before launch day ends.

Prevention

If this happened once in Bolt plus Vercel, it can happen again unless you put guardrails around delivery speed.

1. Security review before deploys

  • Every admin feature should get a quick auth review before merge or publish.
  • I look specifically for "UI-only security", leaked env vars, and missing role checks.

2. Secret scanning in CI

  • Add automated scanning so hardcoded tokens fail builds early instead of reaching Vercel logs or public bundles.

3. Least privilege by default

  • Use separate credentials per environment and per service purpose whenever possible:

read-only analytics, restricted production API, local development test keys, preview-only sandbox keys

4. Middleware protection on sensitive routes

  • Protected areas should fail closed if session validation breaks instead of showing partial content.

5. Better UX around auth states

  • Users should see clear loading states while session checks happen so they do not get brief flashes of protected content.

6. Monitoring that catches abuse early ``` p95 auth failure rate > baseline + 30 percent -> alert admin route hits without session -> alert secret-related build warning -> block deploy new preview deployment with prod key -> block release

7. Safer performance habits
   - Do not fetch sensitive data until auth is confirmed server-side because wasted requests increase both leak risk and backend load.

8. Code review rules for AI-built apps
| Area | What I check | Why it matters |
|---|---|---|
| Auth | Server enforcement | Stops bypasses |
| Secrets | No client exposure | Prevents leaks |
| Logs | No token dumping | Reduces blast radius |
| Roles | Admin vs user separation | Limits damage |
| Deploys | Prod vs preview split | Avoids accidental release |

My opinionated rule: if an internal app handles customer data or operational controls, assume it needs real auth from day one even if only three people use it today.

## When to Use Launch Ready

Use Launch Ready when you need me to stop the bleeding fast and make the app safe enough to run publicly without babysitting it all day.

- domain setup
- email setup
- Cloudflare configuration
- SSL
- deployment hardening
- secrets cleanup
- monitoring setup

It includes DNS updates, redirects, subdomains, Cloudflare protection settings, SSL issuance, caching basics if appropriate, DDoS protection settings where available on your plan stack), SPF/DKIM/DMARC email records,
production deployment,
environment variables,
secrets handling,
uptime monitoring,
and a handover checklist so you know what changed

What you should prepare before I start:
- Vercel account access
- Domain registrar access
- Cloudflare access if already connected
- List of all third-party services used by Bolt app flows
- Current env var names without posting secret values in chat if avoidable)
- A clear list of who should have admin access on day one

If your issue is exposed keys plus missing auth on an internal admin app built with Bolt and deployed on Vercel", this sprint fits well because it focuses on containment first rather than redesigning everything from scratch."

## References

1. Roadmap.sh Cyber Security: https://roadmap.sh/cyber-security
2. Roadmap.sh API Security Best Practices: https://roadmap.sh/api-security-best-practices
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. OWASP Authentication Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html

---

## 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.