What Not To Put In Your Repo

The recent flurry of concern about GitHub searches turning up RSA keys and the like is really nothing new. We have always needed to ponder what files we actually put into our public repositories, whether those are GitHub or something else. The GitHub escapades simply heightened awareness of this issue for a while.

So, what specific things native to Android application development should you avoid publishing in public, such as an open GitHub repo? Here are three categories to consider:

Your Keystores

Your signing keystores should not be published for all comers, particularly your production keystore. If others have access to your production keystore, all they need to do is hack your Google account, and they can then replace your app with something else that you, and your users, probably do not want.

Collaborative open source projects for creating published Android apps will need to strike a balance. Ideally, the production keystore is known by more than one person, so one disgruntled developer cannot stymie publishing updates. However, allowing everyone to get to the production keystore is dangerous. Have some out-of-repo way of getting the keystore to trusted team members, possibly involving some sort of formal ceremony involving swords and stuff.

Your API Keys (Except…)

If you have signed up for some Web service that issues an API key, and that API key is not tied to your keystores, you do not want to have that API key in your repo. Others can use that API key to masquerade as you, performing operations with the Web service on your behalf.

The Google Maps V1 and Maps V2 APIs for Android have API keys, but those keys are tied to your signing key. The API keys are useless unless they are employed by an app signed by the signing key tied to the API key. Hence, these are safer to release into a repo, so long as you feel confident that you have not leaked the associated signing keys.

If you need API keys in your open source app, and you do not want them in your repo, one pattern is to store them in a dedicated string resource file.

For example, I use ACRA in conjunction with BugSense for some apps, until I get around to hosting my own ACRA server component. BugSense uses a API key for tying ACRA to BugSense, and their sample code looks something like this:

@ReportsCrashes(formUri = "http://www.bugsense.com/api/acra?api_key=YOUR_API_KEY", formKey="")

While that works, using an ACRA annotation pretty much forces you to put your API key right in the source code.

An alternative, for recent versions of ACRA, is to do this configuration at runtime:

public class AcraApplication extends Application {
  @Override
  public void onCreate() {
    super.onCreate();

    if (!BuildConfig.DEBUG) {
      ACRAConfiguration config=ACRA.getNewDefaultConfig(this);
      config.setFormUri(getString(R.string.acra_form_uri));
      ACRA.setConfig(config);
      ACRA.init(this);
    }
  }

Here, the formUri is set in Java code, from a string resource. You can keep that string resource in its own file (e.g., res/values/acra.xml) and exclude that individual file from the repo (e.g., via .gitignore). Include in the project README a note of what needs to go in this file, so that those checking out the project know why it will not build cleanly out of the box.

Your Personal Information

Be judicious about putting contact information in your repo that might be used for spam, phishing, etc. Information that is already readily available from other sources is not a big deal (e.g., an email address you use for business). You might have some of this in your app in an about dialog, or some form of technical support documentation, or the like.