๐Ÿ” Android Security and Privacy

Secure API Keys and Secrets in Android Apps

'How do I hide my API key in Android?' is one of the most asked questions, and the honest answer is that you can't hide a secret in an APK. What you can do is decide which keys may live in the app, restrict them, and keep real secrets on a server.

โœ๏ธ Yunok Tech ๐Ÿ“… Updated โฑ 3 min read ๐ŸŽฏ Intermediate
On this page
  1. Classify your keys
  2. Keeping keys out of source control
  3. Restrict client keys
  4. Real secrets: use a backend
  5. If a secret leaks
  6. Common keys and where they go
  7. Frequently asked questions
  8. Conclusion

An APK is a zip file. Its strings, BuildConfig constants, resources and even native libraries can be extracted with free tools in minutes. Obfuscation and NDK tricks slow attackers slightly, and runtime interception defeats them anyway. Design as if every key in the app is public.

Classify your keys

Which keys can ship in an Android app Identifiers meant to be public, such as Firebase configuration or a Maps key restricted to your app, can ship in the app. Restricted keys should be limited by package and certificate and by API. Secrets that grant spending or data access, such as AI provider keys, payment secret keys, database credentials and admin tokens, must stay on servers. OK in apppublic identifiers(e.g. Firebase config) OK if restrictedclient keys (Maps)package + SHA + API limits Server onlyAI provider keys, paymentsecrets, DB creds, admin
If misuse of a key costs money or exposes data, it's a secret, and secrets don't ship.

Keeping keys out of source control

Even for keys that are allowed in the app, avoid committing them to Git, where they're scraped quickly from public repos. The Secrets Gradle Plugin reads values from local.properties (which is ignored by Git) and exposes them as BuildConfig fields and manifest placeholders:

local.properties (not committed)Properties
MAPS_API_KEY=your-restricted-maps-key
app/build.gradle.ktsGradle KTS
plugins {
    id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
}
android {
    buildFeatures { buildConfig = true }
}
AndroidManifest.xmlXML
<meta-data android:name="com.google.android.geo.API_KEY" android:value="${MAPS_API_KEY}" />
This hides keys from Git, not from the APK

The value still ends up in the built app. That's fine for restricted client keys, and never acceptable for real secrets.

Restrict client keys

  • Application restrictions: limit to your package name and signing certificate SHA-1 (include the Play App Signing certificate).
  • API restrictions: allow only the APIs the app uses.
  • Quotas and alerts: cap usage and alert on spikes.

Remember that app restrictions rely on request metadata that a determined attacker can spoof. They limit casual abuse, not targeted attacks.

Real secrets: use a backend

Backend holds the secret The app authenticates the user and calls your backend with a short-lived user token, optionally with an App Check or Play Integrity token. The backend validates them, applies quotas, and calls the third-party API with the secret key from a secret manager. Appuser token Your backendauth ยท quotas Third-party APIsecret key ๐Ÿ”’ Compromising the app yields, at most, one user's short-lived token.
The blast radius of a compromised app shrinks from "everyone's money" to "one session".

For Gemini specifically, Firebase AI Logic with App Check provides this mediation without your own server. See Integrating Cloud AI APIs Securely.

If a secret leaks

  1. Revoke or rotate the key immediately in the provider console.
  2. Check usage logs and billing for abuse.
  3. Remove it from history (rewrite Git history if needed) and from any published APKs, by releasing an update.
  4. Fix the architecture so the secret no longer needs to be in the app.
  5. Enable secret scanning on your repositories.

Common keys and where they go

KeyWhere
google-services.json (Firebase config)App: identifiers, protected by Security Rules and App Check
Maps SDK keyApp, restricted by package, SHA and API
Gemini / OpenAI / other AI keysServer (or Firebase AI Logic)
Payment gateway secret keyServer only (publishable keys may ship)
Signing keystore passwordsCI secrets only

Frequently asked questions

What about storing keys in native (C++) code?

It adds a small amount of effort for attackers, who can still extract them from the binary or intercept them at runtime. It isn't a substitute for keeping secrets server-side.

Can I fetch the key from my server at runtime?

Then it's in device memory and network traffic, so still exposed. Instead, have the server make the call that needs the key.

Is google-services.json a secret?

It contains project identifiers meant to be in the app. Protect your Firebase data with Security Rules and App Check instead.

Conclusion

You can't hide secrets in an APK. Ship only public or restricted client keys, keep them out of Git with the Secrets Gradle Plugin, put real secrets behind a backend (or Firebase AI Logic with App Check for Gemini), and have a rotation plan for leaks.

Next step: decide whether pinning is right for your API in Certificate Pinning: Benefits and Limitations.

Official references

๐Ÿ“ฑ Apps built by Yunok Tech

Real Android apps on Google Play, free to download.

See all our apps โ†’

Ready to build real Android applications?

Security is easiest to get right when it is part of how you build from the first screen. Strengthen the Android fundamentals that secure, privacy-respecting apps are built on.

Move beyond theory and strengthen your Android development skills with Yunoktech's Android course. Learn core concepts, practical implementation, modern Android development techniques, and the reasoning behind building maintainable applications.

Explore the Android course and take your next step as an Android developer.

Share: LinkedIn X / Twitter WhatsApp