Any secret embedded in a mobile app binary should be treated as public the moment the app ships — because functionally, it is.
Why "it's compiled" doesn't mean "it's hidden"
Mobile app binaries (APKs, IPAs) are straightforward to decompile and inspect with widely available, free tooling. A hardcoded API key, even inside compiled bytecode, typically shows up as a plain string when the binary is inspected — no advanced reverse engineering skill required.
The most common mistake
Third-party service API keys (analytics, maps, backend APIs) hardcoded directly into client-side app code, often because it's the fastest way to get a feature working. This works fine functionally, but means anyone who downloads the app has that key.
What actually needs to stay server-side
Any credential that grants meaningful access — write access to a backend, a key with a paid usage quota attached to your account, anything scoped beyond what a single anonymous client action needs — belongs behind your own API, not embedded in the client.
Architectural patterns that avoid the problem
- Proxy through your own backend. Instead of the app calling a third-party API directly with an embedded key, have the app call your backend, and your backend calls the third-party API using a key that never leaves your servers.
- Short-lived, scoped tokens issued per session. Where a client genuinely needs some direct access, issue a narrowly-scoped, short-lived token at runtime (after your backend authenticates the user) rather than a static, long-lived key baked into the build.
- Public, restricted keys where the platform supports it. Some services (like certain mapping or analytics APIs) support keys explicitly designed to be public, restricted by platform, bundle ID, or domain. These are meaningfully different from a general-purpose secret key and are fine to embed — check the provider's documentation for which category a given key falls into.
Don't rely on obfuscation as protection
Obfuscating or lightly encrypting an embedded key adds friction to extraction, but doesn't change the fundamental fact that the decryption logic ships in the same binary. Treat obfuscation as a minor deterrent at best, never as the actual control protecting a genuinely sensitive secret.
The fix isn't hiding the secret better inside the app — it's not putting genuinely sensitive secrets inside the app at all.