Storing Android Signing Config Credentials: Secure and Platform Independent
In android app development, ownership of the app is verified by signing it with a keystore which the developer owns. The keystore and its credentials, they act like an identity of the developer for the app in Playstore, Android OS and any other 3rd party API used in app, so it should be kept safe and secure.
Using the gitignore file like this allows to remove any keystore in git version control system, but what about keystore credentials? Sometimes we need to use the credentials in
build.gradlefile, when multiple developers are working on a same project or during CI/CD build, where we cannot use the GUI of Android Studio to generate APK. Let’s have a look at the signing config part of the gradle file:
As you can see, we need to include the actual credentials of the keystore to automate the APK generation. This can get committed on VCS and compromise the security of keystore. Incase this happens you can undo it by rewriting the history which can lead to other issues if not performed carefully.
How to avoid it?
The available solutions include using environment variables or use git ignore properties file to takeout the values from the gradle file so they get injected on the run time.
The environment variables technique works well with Linux and Mac but breaks on Windows, so if your developers have different operating systems, this setup can break (Yes, many people use windows for development 😛). This forces the Windows users to change the gradle file locally and accidentally put credentials in VCS if not changed back.
The other option is to use aproperties file, like local.properties in the project and put it in git ignore. Then you read this file in gradle script and extract the values during build. The issue with this approach is that it can get deleted (project corruption, new copy from VCS etc.) so, you will be maintaining a copy of it locally.
Remeber, both of the above options can work on CI/CD as they usually have docker images of ubuntu and you can easily set environment or generate a properties file based on docker environment in CI/CD scripts. For android CI/CD setup, you can look here.
Now an easy solution to the problems in above scenarios is to use
gradle.propertiesnot at the project level, but at the top level i.e gradle home . The gradle home location, if you have not altered it manually, will be:
Now gradle.properties file can contain credentials or values which will remain same across all your projects. An example of the file is:
Now, after using global properties, your signing config will become as shown below. The if check before accessing the properties is to ensure that properties are present globally or the build will fail.
This method will work across all three platforms. Only adding credentials to ~/.gradle/gradle.properties once will make them available across all android projects during build time and will avoid leaking of the sensitive credentials.
Hopefully, this article will help you, especially in CI/CD integration in your work flow.
Suggestions to improve this article are welcome. Thanks!
This article is inspired by react native documentation to store signing credentials globally : https://facebook.github.io/react-native/docs/signed-apk-android#setting-up-gradle-variables