Removing API secrets from your public Android source code

(Cross posted from the Teddy Hyde blog)

A few weeks ago I open sourced Teddy Hyde on GitHub. I had forgotten, however, that my source code included the private GitHub API client secret. I reset them on GitHub so the client secret I had accidentally publicized was no longer valid. Then, I began modifying the source code to make sure that I build with the new secret but don’t include that in the source code.

The way to do this is to use a buildConfigField inside your Gradle build file. If you add variables using this method, Gradle creates and builds a special class for you called BuildConfig which you can reference inside your other classes. I wanted to make sure that when I build the app I specify the secret from the command line to avoid checking it into the source code.

The relevant lines inside the build.gradle look like this:

     buildTypes {
          release {
              signingConfig signingConfigs.release
            buildConfigField "String", "GITHUB_CLIENT_ID",
            buildConfigField "String", "GITHUB_CLIENT_SECRET",

These pull the variable from the environment and stick them inside a string. I can then reference them inside my class files using the identifier BuildConfig.GITHUB_CLIENT_SECRET;

The command line to build my app then looks like this:

    GITHUB_CLIENT_SECRET=abcdef34545 GITHUB_CLIENT_ID=12332123123 PASSWORD=MyKeyPassPwd STORE_FILE=~/android/keystore gradle assembleRelease

I could optimize this by pulling from a file outside of the source root and avoid even having the client secret and password inside my bash history file, but this works for now.

Here is the full diff of the code on GitHub.