"Hide Your Gemini API Key: a Flutter Backend Proxy"

"The only real way to hide a Gemini API key in a Flutter app is to never ship it. This guide builds a one-file Cloudflare Worker proxy that holds the key server-side, wires it to a Flutter client with streaming support, and covers the no-backend alternative."

Here's the direct answer: you cannot hide a Gemini API key inside a Flutter app. Anything shipped to a device — a .env file, a --dart-define constant, an obfuscated string — can be extracted in minutes with a decompiler. If the key is on the device, it's public. The real fix is architectural: the key lives on a server you control, and your app talks to that server. The server — a tiny proxy — attaches the key and forwards the request to Gemini. This guide builds exactly that: a one-file Cloudflare Worker proxy holding your key as a secret, a Flutter client that calls it, hardening so the proxy itself can't be abused, and the no-backend alternative for when you'd rather not run infrastructure. What you'll learn Why .env , --dart-define , and obfuscation all fail to hide a key (with the actual extraction commands) How to build a one-file Cloudflare Worker proxy that keeps the Gemini key server-side How to call the proxy from Flutter with the http package, including a streaming variant How to harden the proxy: a shared app token, rate limits, and sanitized errors The no-backend alternative: Firebase AI Logic + App Check, in Flutter terms What to do in the first 10 minutes after a key leaks The rule: how to hide a Gemini API key in a Flutter app The rule has one sentence: the key must never leave infrastructure you control. A Flutter app compiles to a binary that ships to a stranger's phone. That binary can be unzipped, decompiled, and grepped. Researchers have repeatedly found live Gemini keys in shipped Android apps by doing nothing fancier than scanning APKs — keys that then get abused to burn through quotas and get projects suspended. So "hide the key in the app" is the wrong goal. The right goal is "the app never has the key." Your app…

Explore