ReadYou icon indicating copy to clipboard operation
ReadYou copied to clipboard

Release keystore available in version control

Open V4ldum opened this issue 3 months ago • 2 comments

The keystore used to sign the application in release is available in version control inside the signature folder. This file, as well as the keystore.properties are secrets and should be stored securely, and not available publicly in the repository. Having those files accessible enables someone to build a new version of the app with malware and promote it as an update, potentially puting users at risk.

To test this, I installed the current most up to date version inside an emulator (versionName 0.15.2, versionCode 43) from GitHub releases. I then changed app/build.gradle.kts to versionCode 44 and versionName 0.20.0 and built a release APK with ./gradlew assembleGithubRelease. The installation process worked properly and the app was updated as version 0.20.0.

Image

To enable automatic builds with Github Actions, you need to save the keystore and the properties in Github Secrets and regenerate the files in the pipeline. The properties files can be pasted in as is but the keystore will need to be base64 encoded before being added to the secrets since it's a binary file. Here is an example of a Github Action step to use those files during the build process:

- name: Decode files
  env:
    KEYSTORE: ${{ secrets.KEYSTORE }}
    KEYSTORE_PROPERTIES: ${{ secrets.KEYSTORE_PROPERTIES }}
  run: |
    echo $KEYSTORE | base64 -di > "$PWD/signature/reader.keystore"
    echo $KEYSTORE_PROPERTIES > "$PWD/signature/keystore.properties"

Debug builds don't need to use a keystore because Gradle will generate a default one, enabling people to collaborate on the app without the need to have the release keystore.

How to fix the keystore

Since the keystore is currently available in the Git history, and most likely downloaded in other peoples' forks or clones, you will need to rotate the keystore entirely, as well as change the password in the properties. Sadly, this will break any update after you rotate it and everybody will need to uninstall and reinstall the app manually. This is the only way you could guarantee no new release could be signed by a third-party.

First, you want to git rm the signature folder. Then you want to add the folder to .gitignore to avoid commiting the keystore in the future. After that, you create a new keystore from scratch with a new password and back it up somewhere private. Then, you can add the keystore and properties files to the repository's secrets to use in Github Actions.

If you think rotating the keystore is too much of a pain, you can skip that part and hope for the best. The file will not be available when browsing the most recent files, but will still be retrievable from Git history. Feel free to hard delete this issue (if that's even possible) if you go this route to avoid giving people a bad idea.

V4ldum avatar Oct 11 '25 17:10 V4ldum

This is a long story iykyk. We'll probably rotate the signature for distributing new releases of the app (after we reach the v1.0 milestone), which would need a clean install. but we're working on a migration process to make this not that painful for everyone

JunkFood02 avatar Oct 18 '25 08:10 JunkFood02

That's reasonable 👍

V4ldum avatar Oct 18 '25 17:10 V4ldum