| name | security |
| description | Android app security for AI agents. Use this skill whenever implementing secure data storage,
EncryptedSharedPreferences, EncryptedFile, Android Keystore, ProGuard/R8 code obfuscation,
certificate pinning, network security config, root detection, SSL/TLS, token storage,
preventing reverse engineering, securing API keys, BuildConfig secrets, environment variables,
cleartext traffic, backup rules, screenshot prevention, overlay attack prevention, or any
Android security hardening. Always apply when handling user credentials, payments, or PII.
|
Android Security
Rule 1: Never store secrets in source code or BuildConfig
const val API_KEY = "sk-1234567890abcdef"
buildConfigField("String", "API_KEY", "\"sk-1234567890abcdef\"")
val apiKey = gradleLocalProperties(rootDir, providers).getProperty("API_KEY") ?: ""
buildConfigField("String", "API_KEY", "\"$apiKey\"")
Rule 2: Encrypted storage for sensitive data
class SecureStorageImpl @Inject constructor(
@ApplicationContext context: Context
) : SecureStorage {
private val masterKey = MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
private val encryptedPrefs = EncryptedSharedPreferences.create(
context,
"secure_prefs",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
override fun saveToken(token: String) {
encryptedPrefs.edit().putString("auth_token", token).apply()
}
override fun getToken(): String? = encryptedPrefs.getString("auth_token", null)
override fun clearAll() = encryptedPrefs.edit().clear().apply()
}
Rule 3: Network Security Config
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
<debug-overrides>
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</debug-overrides>
</network-security-config>
<application
android:networkSecurityConfig="@xml/network_security_config"
android:usesCleartextTraffic="false">
Rule 4: Certificate pinning
val certificatePinner = CertificatePinner.Builder()
.add("api.myapp.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.add("api.myapp.com", "sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=")
.build()
OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
Rule 5: Prevent screenshots and screen recording
@Composable
fun SecureScreen(content: @Composable () -> Unit) {
val activity = LocalContext.current as? Activity
DisposableEffect(Unit) {
activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
onDispose {
activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
}
}
content()
}
Rule 6: Backup rules — exclude sensitive files
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<exclude domain="sharedpref" path="secure_prefs.xml" />
<exclude domain="database" path="app_database" />
<exclude domain="file" path="." />
</full-backup-content>
<application
android:allowBackup="false"
android:dataExtractionRules="@xml/backup_rules">
Common Mistakes
❌ Storing tokens in plain SharedPreferences — use EncryptedSharedPreferences
❌ API keys in BuildConfig — visible by decompiling APK
❌ android:allowBackup="true" without backup rules — sensitive DB backed up to Google
❌ android:usesCleartextTraffic="true" in production — all traffic unencrypted
❌ Logging tokens or PII in debug — Log.d("token", userToken) visible in logcat
❌ No root detection for banking/payment apps — use Play Integrity API