Is my Vercel deploy leaking secrets?

Short answer

Likely yes if any Vercel environment variable starts with NEXT_PUBLIC_, VITE_, or PUBLIC_ and contains a secret. Those prefixes ship the variable to the browser. Check in Vercel Dashboard → Settings → Environment Variables and rename any secrets without the prefix.

Vercel's environment-variable model has three scopes:

  • Server (no prefix): never reaches the client bundle
  • Client (NEXT_PUBLIC_ / VITE_ / PUBLIC_): ships to the browser in every page request
  • Build: available at build time only

The mistake: using the client prefix on a secret. Common cases: - NEXT_PUBLIC_SUPABASE_SERVICE_KEY (catastrophic — bypasses all RLS) - NEXT_PUBLIC_OPENAI_API_KEY (bill-shock) - VITE_STRIPE_SECRET_KEY (refund-fraud surface)

How to check: 1. Vercel Dashboard → your project → Settings → Environment Variables 2. Any variable starting with NEXT_PUBLIC_ / VITE_ / PUBLIC_ should contain only publishable values (Stripe pk_, Supabase anon key, OpenAI org ID) 3. If you see a secret with a client prefix: rotate it at the vendor + rename to remove the prefix

Also check your JS bundle directly: 1. Open your deployed site 2. DevTools → Network → reload 3. Search the main bundle for 'sk-' or 'eyJhbG' or your vendor's secret pattern 4. If found: rotate + fix the env var

Securie flags these on every PR that touches env var config.

People also ask