A Google Maps API key is a public credential by design — Google's own docs tell you to embed it in browser JavaScript. The problem: if the same Google Cloud project has the Generative Language API (Gemini) enabled, that unrestricted Maps key can also call paid Gemini endpoints like Gemini 3 Pro Image, Veo 3, and Nano Banana Pro. Anyone who scrapes the key from your page source or a public repo can run up the bill. Truffle Security found 2,863 live keys this way in a single Common Crawl scan, and one developer woke up to a $82,314 charge after his key was stolen. The two-line fix: add an API restriction that limits each Maps key to only the Maps APIs, add an application restriction (HTTP referrer or IP), and set a billing budget plus a hard per-API quota cap so a leak can never become a five-figure invoice. This guide covers the mechanism, how to lock keys down, and what to do if you already got a surprise bill or account suspension.
Why can a Google Maps API key now call Gemini?
Google Cloud API keys are scoped to a project, not to a service. A brand-new key defaults to Don't restrict key, meaning it can call every API that is enabled on that project. When the Gemini API launched (late 2023) and developers enabled the Generative Language API on a project to experiment — often in Google AI Studio — every pre-existing key in that project silently gained the ability to call Gemini. A Maps key created years earlier, designed to be public, retroactively became a credential for expensive generative-AI endpoints. Google sent no notification that the key's capabilities had changed.
Truffle Security disclosed this on November 21, 2025. Google first called it intended behaviour on November 25, then reclassified it as a Tier-1 privilege-escalation bug on January 13, 2026 after researchers demonstrated that Google's own keys were exposed. This is distinct from Grounding with Google Maps, a legitimate Gemini feature launched in September 2025 — the issue here is the silent coupling of old keys to paid APIs, not any single product.
How does a leaked key get abused?
A Maps key (the AIza… prefix) is trivially harvested: it sits in your page source, in compiled JavaScript bundles, in mobile app binaries, and in committed config files. Attackers run bots that scan GitHub commits and Common Crawl for the pattern, then probe each key to see which APIs it can reach:
# If this returns a 200 instead of a 403, the key can reach Gemini —
# and so can whoever found it. (Shown so you can test your OWN keys.)
curl -s -o /dev/null -w "%{http_code}\n" \
"https://generativelanguage.googleapis.com/v1beta/models?key=$KEY"
# 403 PERMISSION_DENIED -> key is restricted away from Gemini (good)
# 200 -> key can call paid Gemini APIs (bad)Once a key passes the probe, an automated script fires thousands of image- and video-generation requests. At $0.134 per Nano Banana Pro image and up to $0.50 per second of Veo 3 video, abuse compounds to thousands of dollars a day. Critically, the requests hit Google's servers directly using your key — nothing appears in your application logs, so the first signal is usually the bill itself.
What are developers reporting?
The pattern is consistent across r/googlecloud and other communities: a small, steady monthly bill for years, then a sudden five- or six-figure spike from Gemini, Veo 3, or Nano Banana once a key is found — often followed by a frustrating refund fight or a project suspension. A few representative threads:
- r/googlecloud — "[Urgent] Huge bill in GCP…" — a surprise invoice and the scramble to dispute it with billing support.
- r/googlecloud — "GCP suspended my account due to 'suspicious activity'" — the suspension-and-appeal experience after abuse is flagged.
- r/googlecloud — "So you got a huge GCP bill by accident, eh?" — the community's standing playbook for fighting an unexpected bill.
How do I lock down a Google Maps API key?
Open Google Cloud Console → APIs & Services → Credentials and edit each key. Two independent restrictions matter, and you want both.
- API restrictions — under API restrictions, switch from
Don't restrict keytoRestrict keyand select only the Maps APIs the key actually uses (Maps JavaScript API, Maps Static API, Geocoding API, etc.). This is the control that strips Gemini access away. Never leave a public key unrestricted. - Application restrictions — limit who can use the key: HTTP referrers for browser keys, IP addresses for server keys, or app package name + SHA-1 (Android) / bundle ID (iOS) for mobile keys.
- Disable APIs you don't use — in APIs & Services → Enabled APIs & services, disable the Generative Language API, Vertex AI API, and any other paid API you aren't actively calling, so no key on the project can reach them.
- One key per surface — keep your public Maps key separate from any AI or server key, ideally in a separate project, so a browser leak never touches your AI billing.
You can verify and apply API restrictions from the CLI:
# List your keys and their current restrictions
gcloud services api-keys list --project=my-project
# Restrict a key to specific Maps services only (this removes Gemini access)
gcloud services api-keys update KEY_ID --project=my-project \
--api-target=service=maps-backend.googleapis.com \
--api-target=service=geocoding-backend.googleapis.com \
--allowed-referrers="https://example.com/*,https://*.example.com/*"API restrictions vs application restrictions — what's the difference?
They are different axes and you need both. Application restrictions control where a request comes from (a referrer, an IP, a signed app). API restrictions control which APIs the key may call. A referrer restriction alone does not stop Gemini abuse, because referrer headers are trivially spoofed in a server-to-server curl call — only the API restriction reliably keeps a Maps key away from the Generative Language API.
How do I cap the financial blast radius?
Restrictions stop the common attack; budgets and quotas bound the worst case. There is a crucial distinction most developers miss:
- Billing budgets only notify — they do not stop spend. A budget alert (Billing → Budgets & alerts) emails you at 50/90/100%, but the meter keeps running. By the time the 100% email lands, an automated attack may already be far past it.
- Per-API quota caps actually enforce a hard stop. In APIs & Services → Generative Language API → Quotas & system limits (or IAM & Admin → Quotas), lower the requests-per-minute and per-day limits to your real usage — or to zero on APIs you never call. When the cap is hit, further requests are rejected, not billed.
Set a budget so you find out fast, and set quota caps so the bill can't run away while you sleep:
gcloud billing budgets create \
--billing-account=0X0X0X-0X0X0X-0X0X0X \
--display-name="Hard ceiling alert" \
--budget-amount=50USD \
--threshold-rule=percent=0.5 \
--threshold-rule=percent=0.9 \
--threshold-rule=percent=1.0
# A budget does NOT cap spend. Lower per-API quotas in the Console to enforce
# an actual stop on the Generative Language API and Vertex AI.What do I do if I already got a surprise bill or suspension?
Already hit by a surprise invoice?
Read Unexpected Large Invoice — what to do next for the step-by-step playbook on disputing the charge and getting it resolved.
Speed matters — abuse compounds by the hour. Work the incident in three phases.
1. Contain (minutes).
- Delete or disable the compromised key in APIs & Services → Credentials. Disabling stops it immediately; you can investigate after.
- Disable the Generative Language API, Vertex AI API, and Veo on the affected project.
- Rotate any still-needed keys and update your apps, then scan your repos and bundles for other exposed keys (GitHub Secret Scanning with push protection, or
trufflehog).
2. Recover the money (hours to weeks). Pull the Cloud Audit Logs / Cloud Billing reports that show the spike, screenshot the timeline, and open a billing case (Billing → Help & support) stating clearly that the usage was unauthorized due to a leaked key. Be honest that refunds are case-by-case: Google's shared- responsibility stance means denials are common, and several widely reported victims — including the $82,314 case and a ~AUD$17,000 case — were only reimbursed after press coverage. If support denies the claim, escalate for supervisor review, and a credit-card chargeback is a last resort (outcomes vary).
3. Appeal a suspension. If the project was suspended for the abuse, the notification email contains an appeal link. Include evidence the key was compromised (audit logs, the public commit), proof you've secured it (deletion/rotation plus API restrictions), and a short remediation summary. Reinstatement has ranged from ~36 hours to several weeks, so file immediately and keep the case number.
When does this not apply?
Not every key is at risk, and restrictions aren't a cure-all:
- Server-only keys behind your backend that never ship to a browser have a far smaller exposure surface — though they still need API restrictions in case the server is breached or the key is committed.
- Projects with no paid AI APIs enabled can't be billed for Gemini through a Maps key — but a future "let me just try Gemini" in the same project re-opens the door, so isolate AI work in its own project.
- Budgets are not protection. They tell you after the fact. Treat API restrictions and quota caps as the real controls; the budget is just the smoke alarm.
This is one specific case of a general truth: an environment variable or key embedded client-side is never a secret. See the broader guide on environment variable security for rotation and leak-detection practices, and Gemini API environment variables for why GEMINI_API_KEY must stay server-side.
References
- Truffle Security — Google API keys weren't secrets, but then Gemini changed the rules — the primary disclosure, including the 2,863-key Common Crawl scan and the reclassification timeline.
- The Register — Dev stunned by $82K Gemini API key bill after theft — the Rod Danan case and Google's initial refund denial.
- The Register — Google users fight for refunds as unauthorized API usage bills soar — multiple victims and the realistic refund outcome.
- Google Maps Platform — API security best practices — official guidance on application and API restrictions for Maps keys.
- Google Cloud — adding restrictions to API keys — the difference between application restrictions and API restrictions.
- Google Cloud — create and manage budgets — note that budgets alert but do not cap spend.
Audit your project's environment configuration with the env validator, then read environment variable security for rotation and leak detection.