
For years Google told developers that API keys for Maps and Firebase could be shipped in client-side JavaScript, because they identify a project rather than authorize access to private data. Truffle Security showed that this stops being true the moment someone enables the Gemini API on the same Google Cloud project. Every existing unrestricted key in that project, including the ones already sitting in your public bundle, can then call Gemini. That exposes uploaded files and cached context, and lets anyone run up your bill.
What happened
On 25 February 2026 Joe Leon of Truffle Security published research showing that Google Cloud uses a single key format (strings beginning AIza) both for public project identification and for authenticating to sensitive services. When the Generative Language API (Gemini) is enabled on a project, existing keys in that project get access to it with no warning or notification. New keys default to "Unrestricted", which means they work with every API enabled on the project.
The team scanned the November 2025 Common Crawl snapshot (CC-MAIN-2025-47, about 700 TiB of public web pages) and found 2,863 live Google API keys that could reach Gemini. Truffle says the owners included major financial institutions, security companies, global recruiting firms and Google itself. One Google key embedded in a public product page, live since at least February 2023, returned 200 OK from the Gemini /models endpoint.
Truffle reported the issue to Google's Vulnerability Disclosure Program on 21 November 2025. Google first called the behaviour intended, then reclassified it as a bug in early December and asked for the list of keys. By January 2026 it had rated the issue "Single-Service Privilege Escalation, READ". Google said it was working on scoped defaults for new AI Studio keys (Gemini-only), on blocking leaked keys from Gemini, and on notifying key owners. When the 90-day disclosure window closed on 19 February, Truffle said it had not yet seen a root-cause fix.
Who is affected
- Any GCP project where the Generative Language API is enabled and an unrestricted (or Gemini-allowed) API key has ever been exposed: in web JavaScript, mobile app binaries, public repositories or CI logs.
- Teams that added Gemini to an existing project that already used Maps, Places, YouTube or Firebase keys in the browser. This is the scenario people miss most often.
- Finance owners, because heavy Gemini use on a stolen key can cost thousands of dollars a day and exhaust quotas for real users.
What it means for developers and engineering teams
This is privilege escalation through configuration drift, not a leaked secret in the usual sense. Nobody leaked anything new. The key's power changed after it was published, because a key's permissions are effectively "every enabled API in the project" unless you restrict them. Truffle maps this to CWE-1188 (insecure default) and CWE-269 (improper privilege management).
The Gemini endpoints at risk are not just inference. With a working key, an attacker can list and read /files (uploaded datasets and documents) and /cachedContents (cached prompt context). A browser key for a Maps widget can therefore turn into read access to whatever another team in the same project uploaded for an AI feature.
Design lessons that apply beyond Google:
- Keep public and secret credentials in separate projects. Put browser-exposed keys in a project that only has public APIs enabled. Put AI and data APIs in another project.
- Restrict every key by API and by caller (HTTP referrer, Android package and certificate, or iOS bundle ID). An unrestricted key is a wildcard that keeps growing.
- Treat "enable a new API" as a security change. Review it the way you review an IAM change, because it widens what every existing key in the project can do.
- Call Gemini from your backend. Keep model credentials server-side and expose your own narrow endpoint to the client.
What to do now
- For each GCP project, open APIs & Services > Enabled APIs & services and check whether the Generative Language API is enabled.
- Where it is, open Credentials and find keys marked unrestricted or that allow the Generative Language API. Starting with the oldest, check whether any of them are public.
- Test a key you found in client code (only keys you own):
Acurl -s -o /dev/null -w "%{http_code}\n" \ "https://generativelanguage.googleapis.com/v1beta/files?key=$API_KEY"200means the key can reach Gemini. A403means it can't. - Rotate exposed keys, then add API and application restrictions to the replacements. Move Gemini to a separate project or a server-only key.
- Scan your code, build output and CI for keys, and confirm which are live:
trufflehog filesystem ./ --only-verified - Set billing budgets and alerts on projects that have Gemini enabled, and review Gemini usage metrics for traffic you don't recognize.
Related on TechLogHub
- OpenAI API vs Anthropic API vs Gemini API
- What is an API?
- Authentication explained
- PromptBrake, LLM API security testing

