tezvyn:

How do you manage API keys across Gradle build variants securely?

AI-drafted, machine-checkedSource: github.comadvanced
WHAT IT TESTS

Gradle secret injection per build variant without committing credentials.

ANSWER OUTLINE

Gitignore a properties file, load it in build.gradle, map secrets to BuildConfig or manifest placeholders by flavor, and commit safe defaults.

WHAT THIS TESTS: This question tests your depth with the Android Gradle build system, specifically how you handle configuration that must vary by build variant without leaking secrets into version control. The interviewer cares about three layers: where secrets live on disk, how they flow into the build, and how you handle the fact that they still end up in the binary. A senior candidate should also discuss CI integration and runtime limitations.

A GOOD ANSWER COVERS: First, the storage layer: keep real secrets in a properties file such as local.properties or a variant-specific file like secrets.properties, and ensure that file is listed in .gitignore so it never reaches the repository. Second, the injection layer: in the module-level build.gradle or build.gradle.kts, read the properties file using java.util.Properties, then assign values to buildConfigField for code access or manifestPlaceholders for the manifest, using conditional logic inside productFlavors or buildTypes when different variants need different keys. Third, the fallback layer: commit a version-controlled defaults file, such as secrets.defaults.properties, containing non-functional placeholder values so that CI and fresh clones can compile without the real file. Fourth, tooling awareness: mention the Google secrets-gradle-plugin, which automates reading from local.properties and generating BuildConfig fields, but note that it still requires the file to be gitignored. Fifth, security context: acknowledge that any key embedded in BuildConfig or the manifest is still recoverable by decompiling the APK, so API key restrictions and backend validation remain essential.

COMMON WRONG ANSWERS: Hardcoding API keys directly inside build.gradle files is the most common red flag because those files are committed. Another mistake is using flavor-specific source folders to hold different keys in XML or Java files, which also ends up in version control. Some candidates suggest ProGuard or R8 obfuscation as a way to hide keys, which is ineffective for string literals in BuildConfig. Finally, stopping at the local.properties pattern without explaining how different build variants receive different values shows shallow Gradle knowledge.

LIKELY FOLLOW-UPS: How would you supply secrets in a CI environment where local.properties does not exist? How do you rotate a key without pushing a new commit? What would you do if a secret were accidentally committed to the repository? How do you handle secrets in Compose or library modules that do not expose BuildConfig? The interviewer may also ask about the trade-offs between BuildConfig injection and fetching configuration from a remote server at runtime.

ONE CONCRETE EXAMPLE: Suppose you have staging and production API keys. You create local.properties in the project root with API_KEY_STAGING=abc123 and API_KEY_PROD=xyz789, then add local.properties to .gitignore. In build.gradle.kts, you load the file with Properties().apply { load(rootProject.file("local.properties").inputStream()) }. Inside the productFlavors block, the staging flavor sets buildConfigField("String", "API_KEY", "\"${properties["API_KEY_STAGING"]}\""), while the production flavor uses API_KEY_PROD. You also create secrets.defaults.properties with dummy values and commit it so CI builds do not fail. You then note that the Google secrets-gradle-plugin can replace the manual Properties loading by applying the plugin and letting it read local.properties automatically.

Read the original → github.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.