For years, Google’s approach to API keys was unusual compared to the rest of the industry. Keys for Maps, Places, YouTube Data, and similar services were routinely embedded in client-side JavaScript and shipped directly to browsers. This was intentional. Google designed those keys to be restricted by HTTP referrer headers, application identifiers, or IP addresses rather than by secrecy. The key itself was not the secret; the restrictions attached to it were the guard.
That philosophy made practical sense for browser-based products. You cannot hide a secret in client-side code, so Google built a system that did not require you to. Developers internalized the lesson: Google API keys are not secrets, handle them accordingly.
Gemini changed the rules.
Gemini API keys, unlike Maps or Places keys, are server-side credentials that grant access to expensive generative AI capabilities billed directly per token. They are not designed to be restricted by referrer. There is no browser-safe variant. A leaked Gemini key is a leaked secret in the traditional sense, the same as an AWS access key or a Stripe secret key. Anyone who finds it can run up charges against your account.
Simon Willison documented this shift and the confusion it creates for developers who have years of muscle memory telling them that Google API keys are safe to commit to a public repo or paste into a tutorial. The problem is not that developers are careless; it is that they are applying a learned pattern that was correct for a long time and is now wrong for a specific, increasingly important product category.
This kind of implicit API contract change is genuinely hard to communicate. Google could have named the credential something other than “API key,” something that did not carry the existing mental model. They did not. So now there are Gemini keys in public GitHub repositories, in StackOverflow answers, in blog post screenshots, placed there by developers who thought they were following established Google conventions.
What the Two Models Actually Look Like
With the old model, a Maps key in your frontend code was acceptable:
// This was fine for Maps - key restricted to your domain
const map = new google.maps.Map(el, {
apiKey: "AIzaSy..."
});
With Gemini, that same pattern is a security incident:
// Do NOT do this - Gemini keys are server-side secrets
const genAI = new GoogleGenerativeAI("AIzaSy...");
Both keys start with AIzaSy. Both look identical at a glance. The difference is entirely in what they authorize and how Google enforces boundaries.
The Takeaway
If you are building anything with the Gemini API, treat the key with the same discipline you would apply to any other server-side secret: environment variables, secret managers, never in version control. The fact that it looks like a Maps key does not mean it behaves like one.
For teams with existing Google API key handling policies, this is worth an explicit conversation. The old guidance was probably written when all Google keys were referrer-restricted. It needs an update.