How to hide your Gemini API key in Next.js
The Problem
This is what most Next.js codebases look like today. The GOOGLE_AI_API_KEY key (AIza...) lives directly in the process environment. If your repo, your CI logs, or your deployment config leaks — so does your key.
// app/api/generate/route.ts — real Google AI key in environment
import { GoogleGenerativeAI } from "@google/generative-ai";
const genAI = new GoogleGenerativeAI(process.env.GOOGLE_AI_API_KEY!);
const model = genAI.getGenerativeModel({ model: "gemini-3.5-flash" });
export async function POST(req: Request) {
const { prompt } = await req.json();
const result = await model.generateContent(prompt);
const response = await result.response;
return Response.json({ text: response.text() });
}The Fix
Send the request to the KeyVault Edge proxy at https://proxy.keyvaultedge.com with the provider's usual path, your kvt_ token in X-KV-Token and the provider's base URL in X-KV-Target. The proxy refuses requests whose Origin isn't on the token's allowed hosts, then injects your real GOOGLE_AI_API_KEY, so it never sits in your app's environment.
// app/api/generate/route.ts — KVE_TOKEN is host-bound; AIza... key not here
export async function POST(req: Request) {
const { prompt } = await req.json();
const response = await fetch("https://proxy.keyvaultedge.com/v1beta/models/gemini-3.5-flash:generateContent", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-KV-Token": process.env.KVE_TOKEN!, // kvt_... token, server-side only
"X-KV-Target": "https://generativelanguage.googleapis.com",
// Must match one of the token's allowed hosts
Origin: process.env.APP_ORIGIN!,
},
body: JSON.stringify({
contents: [{ parts: [{ text: prompt }] }],
}),
});
const data = await response.json();
return Response.json({
text: data.candidates[0].content.parts[0].text,
});
}Setup in 4 steps
Create a KVE token for Google AI
Sign in at keyvaultedge.com, create a new token with your AIza... key from Google AI Studio. Bind it to your Vercel deployment domain (e.g. myapp.vercel.app).
Update Next.js environment variables
Replace GOOGLE_AI_API_KEY with KVE_TOKEN. Critically — do not add NEXT_PUBLIC_ prefix. KVE_TOKEN must be server-only.
# .env.local
KVE_TOKEN=kvt_...your_token
APP_ORIGIN=https://yourdomain.com # one of the token's allowed hosts
# Optional: remove the SDK
npm uninstall @google/generative-aiReplace @google/generative-ai with native fetch
Remove the GoogleGenerativeAI import. Point the request at https://proxy.keyvaultedge.com with the provider's usual path (e.g. /v1beta/models/gemini-3.5-flash:generateContent), send your token in X-KV-Token, the provider's base URL (https://generativelanguage.googleapis.com) in X-KV-Target, and an Origin header matching one of the token's allowed hosts. The body is the provider's normal request body; the proxy sets the provider's auth header with your real key and forwards it. Responses are passed through unchanged.
Set a rate limit matching your feature's expected usage
In the KeyVault Edge dashboard, set requests per minute, hour and day, a monthly cost cap and an endpoint scope on your Gemini token. That bounds what anyone can run through your endpoint, including via prompt injection, and you can revoke the token in one click.
What this protects, and what it doesn't
- Your real GOOGLE_AI_API_KEY stays at the edge, so it can't leak from your repo, logs, bundle or server environment.
- The kvt_ token is still a credential. A copied token can be replayed by anyone who can send the right headers, including a fake Origin from a server. The protection is that each token has its own rate limits, monthly cost cap and endpoint scope, and you can revoke it in one click without rotating the provider key.
- The cost cap is estimated from the usage the provider reports, so a request already in flight can overshoot it slightly.
Already leaked a Gemini key? Read what to do in the first hour. Plans and limits are on the pricing page.
More Google AI guides
Start protecting your keys
Your Google AI key is one leaked .env file away from being exploited. With KeyVault Edge the real key stays at the edge, and the token that replaces it is capped, scoped and revocable in one click.