Why Your Vercel Preview URLs Are Broadcasting API Keys
You share a preview URL—and broadcast your secrets
You’re demoing a new feature to your team via Vercel preview. A developer clicks the link, opens DevTools, and scrolls through the Network tab. There it is: your Stripe API key, database password, AWS credentials—embedded in the response headers or buried in the build logs. Anyone with that URL now has live access to your production APIs. Within an hour, someone could be running test transactions, exfiltrating user data, or burning through your cloud credits.
You never intended to ship those. They’re not in your code. But they’re there anyway.
How environment variables leak into previews
Vercel’s preview deployments are a superpower: every PR gets its own live URL instantly, making code review visual and immediate. But they come with a sharp edge. If you’re using environment variables for API keys, database URLs, or third-party tokens—and you are—those variables get baked into the build output unless you explicitly prevent it.
Here’s the mechanics:
- Build-time exposure: Environment variables referenced in your code get embedded during the build. If you’re using them in client-side code (even conditionally), they end up in your JavaScript bundle—public, accessible to anyone with the URL.
- Headers and metadata: Server-side env vars sometimes leak into response headers, error messages, or debug logs, especially in development or when logging too much.
- Source maps and build artifacts: If your preview includes source maps (which it shouldn’t, but often does), someone can reverse-engineer your setup and find where secrets are stored.
- GitHub Actions logs: If you’re building from a GitHub action, those logs are often public. Anyone watching the repo can see which variables got passed to the build.
Why it’s invisible until it’s too late
The insidious part: you won’t notice until someone does. You’re focused on the feature changes, not on which variables made it through. The DevTools interface doesn’t scream “your API key is here.” The error logs look normal. The site loads, works, and looks right.
Meanwhile: - A curious developer on your team right-clicks “Inspect.” - A contributor from a third-party library tests the preview. - Someone scrapes PR URLs from your GitHub and checks them for exposed secrets. This happens with bots, constantly.
By the time you realize what happened, the damage might already be done.
What’s actually at risk
If an attacker gets your preview environment variables, the damage is immediate:
- API key abuse: Run thousands of API calls against your Stripe, SendGrid, or Twilio accounts—racks up charges within hours.
- Database access: Expose a database connection string and they have direct access to customer data.
- Third-party impersonation: OAuth tokens, webhook signing keys, admin tokens for SaaS tools—all become exploitation surface.
- Cloud credential theft: AWS keys, GCP service accounts, Azure credentials—direct access to your infrastructure.
None of this requires sophisticated attacks. A curl command and grep is enough.
The fix: three layers
Layer 1: Never commit secrets. This is table stakes. Use .env.local and add it to .gitignore. Git history is permanent—if you’ve ever committed a secret, rotate it immediately and assume compromise.
Layer 2: Use Vercel’s environment variable UI. Instead of passing secrets through GitHub or build scripts, add them directly in Vercel’s project settings:
- Go to Settings → Environment Variables
- Mark them as “Production” only if they should never hit preview deployments
- Mark them as “Preview” only if preview builds need them
Vercel isolates these per environment automatically.
Layer 3: Sanitize what reaches the client. If a variable must be accessible to your browser code, use a public prefix:
NEXT_PUBLIC_API_URL=https://api.example.com // safe to expose
STRIPE_SECRET_KEY=sk_live_abc123 // never expose
Vercel and other build tools strip un-prefixed secrets from client builds automatically. Use this convention religiously.
Proof: audit your own previews right now
If you have a preview URL running, test it:
- Open the preview link in a browser.
- Open DevTools (F12 → Network tab).
- Reload the page and look for API requests.
- Check the headers, especially
Authorization, custom headers, and cookies. - Check the HTML source (Ctrl+U) for inline
window.configor similar scripts.
If you see API keys, database URLs, or tokens, fix it today. It’s not theoretical.
Why this matters at scale
When you’re building SaaS software—whether custom tools for your business or products for customers—this security blind spot is critical. A professional software development workflow catches this during the architecture review phase, before code ships. Security isn’t a feature; it’s a checkpoint. The kind of rigor that prevents expensive breaches and keeps user data protected.
If you’re managing custom software or want a second opinion on your security posture, Trove Deck Solution can audit your entire pipeline from build to production. Reach out if you’d like to walk through your setup and tighten the gaps.