Secrets Management and API Key Protection in Mobile Apps: Why an API Key Inside an APK Is
1. The only real question is which keys are allowed to be in the binary at all. Google's own Android security guidance is explicit that this is not a matter of obfuscation: "When your app is compiled, and your app's source code includes API keys, it's possible for an attacker to decompile the app and find these resources." Treat every string in the APK, and every resource or asset packed into it, as published. Client-side keys may therefore only be low-privilege, quota-metered and scope-limited: maps, weather, read-only content feeds, public search. Anything that can move money, read another user's records, issue refunds, send mail or change server state never ships in the client - it lives behind your own endpoint that authenticates the user. (§https://developer.android.com/privacy-and-security/security-tips)
2. Play's User Data policy never says the words "API key" - it regulates outcomes, which is why a leaked key is a policy problem and not just an engineering one. The policy requires developers to "Handle all personal and sensitive user data securely, including transmitting it using modern cryptography (for example, over HTTPS)" and to "Protect all user data with appropriate security measures, including modern cryptography for data in transit." A hardcoded key is not itself a violation; a hardcoded key that lets an attacker read, write or exfiltrate user data is a User Data violation with removal risk stacked on top of the bill and the breach notification. §https://support.google.com/googleplay/android-developer/answer/10144311
3. A key restriction is not authentication, and the Google Cloud documentation says so plainly: "A standard API key doesn't authenticate a principal" - it associates a request with a project for billing and quota. Application restrictions (websites, IP addresses, Android apps, iOS apps - one type at a time) and API restrictions are damage limitation, not secrecy, and the Android-app restriction comes with a documented caveat: "Bypassing this restriction is straightforward. If you use this restriction, you should also add API restrictions and monitor usage." The recommendation in the same document is to set both API restrictions and application restrictions, then watch what the key actually calls. §https://cloud.google.com/docs/authentication/api-keys
4. The hygiene list that carries the real weight. Never commit keys to the repository - Android's guidance points at Gradle plugins such as secrets-gradle-plugin instead of checked-in files. Use separate keys for development, testing and production, and separate keys per app, so a compromised key can be disabled without taking production down. Where a caller is a server, restrict by IP. Where you must keep a secret on the device (tokens, refresh material), keep it in the Android Keystore and encrypt it with a reviewed library such as Tink rather than a string constant, an asset file or plain SharedPreferences. Always HTTPS, and consider certificate pinning as an extra layer, not as a substitute. §https://developer.android.com/privacy-and-security/security-tips
5. Rotation is a calendar item, not an incident-only reflex. Android's guidance cites ISO 27001 and states that "for most cases, a key rotation period between 90 days to 6 months should be adequate"; Google Cloud's rotation operation creates a new key with the same restrictions, and the old key keeps working until you delete it. That overlap window is the whole point: installs in the field update over weeks, so you need a migration window with both keys valid, then disable, then delete. Keep an inventory of key ID, owner, package, scopes and rotation date - a project holds up to 300 keys, which is enough rope to lose track. §https://cloud.google.com/docs/authentication/api-keys
6. Detection decides whether a leak is a Tuesday or a quarter. Turn on per-key usage logging and quota/billing alerts, and watch for the three shapes that matter: a volume spike from an unexpected referrer or IP, quota exhausted at hours your users are asleep, and calls to endpoints the app never calls. On a confirmed exposure, treat it as an incident with a fixed order: create the replacement key with identical restrictions, ship the client update, watch old-key traffic fall, revoke the old key, then review access logs and the billing statement for the whole exposure window. Also check that the Data safety declaration in Play Console still matches reality - "encrypted in transit" is a declaration about actual runtime behaviour, and a leaked key that downgraded a path to plaintext makes that declaration false. §https://cloud.google.com/docs/authentication/api-keys