{"slug": "your-vite-api-key-is-public-here-s-what-happens-next-and-three-ways-to-fix-it", "title": "Your VITE_ API key is public. Here's what happens next, and three ways to fix it", "summary": "A developer is warning that API keys stored in frontend environment variables such as VITE_, NEXT_PUBLIC_ and REACT_APP_ are baked into the public JavaScript bundle and can be scraped by automated scanners, citing public reports of roughly $6,000 in unauthorized Gemini API charges within about 40 minutes and another $2,200 from a leaked VITE_GEMINI_API_KEY. The writeup outlines three mitigations: a serverless or edge backend endpoint holding the key as a secret, provider client-side options like Firebase App Check with Firebase AI Logic, and an edge proxy with per-token rate limits, spend caps and revocation. The developer notes that any browser-visible token can still be copied and replayed, so the goal is bounding the damage rather than preventing theft.", "body_md": "If your frontend reads an AI or payments key from `import.meta.env.VITE_SOMETHING`, that key is in the JavaScript bundle every visitor downloads. Same for `NEXT_PUBLIC_*` in Next.js and `REACT_APP_*` in Create React App. Putting it in a `.env` file changes where it's stored on your laptop, not where it ends up.\n\nYou can check in ten seconds: open your deployed site, open DevTools → Sources, and search the bundle for your key's prefix (`sk-`, `AIza`, `sk_live_`).\n\nAutomated scanners crawl deployed sites and public repos for those prefixes. Developers have described the results publicly this year on Google's own forum, for example [about $6,000 in roughly 40 minutes](https://discuss.ai.google.dev/t/6-000-in-unauthorized-gemini-api-charges-from-a-vite-built-client-bundle-requesting-billing-review/142877) from an AI Studio sample exported to Vite, and [about $2,200](https://discuss.ai.google.dev/t/urgent-2200-in-unauthorized-gemini-api-charges-from-leaked-client-side-key-requesting-refund/141634) from a `VITE_GEMINI_API_KEY` used as a shared fallback.\n\nProviders have added protections (Google now rejects unrestricted Gemini keys and offers project spend caps; OpenAI has project limits), but those work per project or account, not per key, and they don't stop the key from being copied.\n\n**1. A small backend endpoint.** A serverless or edge function holds the key as a secret; your frontend calls the function. Free, and the right answer if you'll also add rate limiting and per-user budgets.\n\n**2. The provider's own client-side option, if it has one.** For example, Firebase App Check with Firebase AI Logic for Gemini on mobile and web.\n\n**3. An edge proxy with per-key limits.** You store the real key once and your app sends a stand-in token instead. The proxy adds the real key and forwards the call, and each token carries its own rate limit, allowed endpoints, spend cap and an off switch. I build one of these, [KeyVault Edge](https://keyvaultedge.com/?utm_source=devto&utm_medium=social&utm_campaign=vite-key-public). You can watch it allow one request and block two misuse attempts on a [live demo, no signup](https://keyvaultedge.com/demo?utm_source=devto&utm_medium=social&utm_campaign=vite-key-public).\n\nOne honest limit for option 3 (and for any token a browser can see): the token can still be copied and replayed from a server. The point is that a leaked token has hard limits and can be revoked in one click without rotating the provider key, so the damage is bounded.\n\n`VITE_`, `NEXT_PUBLIC_` or `REACT_APP_` variable\nHow did your key end up in the frontend? I'd like to hear what made it the easiest option at the time.", "url": "https://wpnews.pro/news/your-vite-api-key-is-public-here-s-what-happens-next-and-three-ways-to-fix-it", "canonical_source": "https://dev.to/keyvault_edge/your-vite-api-key-is-public-heres-what-happens-next-and-three-ways-to-fix-it-2p1b", "published_at": "2026-10-23 12:32:43+00:00", "updated_at": "2026-10-23 12:41:55.264006+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "ai-infrastructure"], "entities": ["Google", "Gemini", "OpenAI", "Firebase", "Firebase AI Logic", "KeyVault Edge", "Vite", "Next.js"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/your-vite-api-key-is-public-here-s-what-happens-next-and-three-ways-to-fix-it", "markdown": "https://wpnews.pro/news/your-vite-api-key-is-public-here-s-what-happens-next-and-three-ways-to-fix-it.md", "text": "https://wpnews.pro/news/your-vite-api-key-is-public-here-s-what-happens-next-and-three-ways-to-fix-it.txt", "jsonld": "https://wpnews.pro/news/your-vite-api-key-is-public-here-s-what-happens-next-and-three-ways-to-fix-it.jsonld"}}