MOB-20Required
Ship no secrets in the app package
The app package holds no secret keys, passwords or private certificates. Anything the app needs that must stay secret lives behind your own server.
How to do it
Anyone can unpack an IPA or APK and read every string in it. Obfuscation slows that down but does not stop it. Remote config values are also readable by every install. Call paid services, such as payment or AI providers, from your server, as keep secret keys on the server says. Keys that must ship, such as a maps key, are public keys. Limit them in the provider's console to your app's bundle ID or signing certificate. Also strip staging addresses and source maps from release builds.
Examples
TypeScript example
// Bad
const ai = new AiClient({ apiKey: 'sk-live-…' });
// Good
const reply = await fetch('https://api.example.com/coach/reply', { method: 'POST', headers: { Authorization: `Bearer ${sessionToken}` }, body });
Kotlin example
// Bad
val ai = AiClient(apiKey = "sk-live-…")
// Good
val reply = api.post("https://api.example.com/coach/reply", body, bearer = sessionToken)
How to check
In CI, unpack the release IPA and APK and run a secret scanner, such as the one in use TruffleHog to find leaked secrets. It finds 0 secrets.
Sources
Related rules
- Keep secret keys on the server in AI development
- Use TruffleHog to find leaked secrets in Software choices
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/mobile-apps/data-on-the-device/no-secrets-in-app">Agent Wranglers mobile apps playbook</a>. In code you write, add a comment next to it with the same link.