Sign the messenger with its own key, not Files'

Every release build before this went out as CN=Flamenet Files. Not a decision —
app/build.gradle.kts read ~/.flamenet-android-signing.properties, a path with no
app in its name, so any Flamenet Android app built on that Mac inherited the
Files identity.

It matters because an Android signing key is permanent. Once a device installs a
build signed with one key it REFUSES every later build signed with another, so
the only remedies after the fact are a new package name — a different app,
orphaning every install — or Play App Signing, which has to be set up before
first publication. Sharing one key across products also means one compromised
keystore takes out both.

Now prefers ~/.flamenet-messenger-signing.properties and falls back to the
shared file, so a machine with only the old setup still produces a signed build
rather than failing in a confusing way.

Verified in the artifact:

    Signer #1 certificate DN: CN=Flamenet Messenger, O=Extant 2000 LLC, C=US
    RSA 4096, SHA-256 791fc826d572a70abfaf7db7fa7784dad0f86f204bb313f0d75ee676df8d3a1d

⚠️ The keystore and its password live outside the repo and there is NO recovery
for either. Losing them means the app can never be updated again.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Paul Hitt
2026-08-25 19:15:36 -04:00
co-authored by Claude Opus 5
parent 3ef8de63b9
commit 103a2dda23
+24 -4
View File
@@ -43,11 +43,31 @@ android {
// Read from a properties file outside the repository, so the keystore and
// its password are never in git and a checkout without them still builds
// (unsigned, which is exactly what an unsigned build should be).
// 🔴 **This app's OWN key, not the one every Flamenet Android app shares.**
// `.flamenet-android-signing.properties` was made for Flamenet Files, and
// because the path is app-agnostic this app silently inherited it — every
// release before 2026-08-25 went out as `CN=Flamenet Files`. Nobody chose
// that for a messenger; it fell out of the layout.
//
// It matters because **an Android signing key is permanent**: once a device
// installs a build signed with one key, it REFUSES every later build signed
// with another. Sharing one key across products also means one compromised
// keystore takes out both.
//
// So: prefer this app's own file, fall back to the shared one so a machine
// that only has the old setup still produces a signed build rather than
// failing confusingly.
//
// ⚠️ Both files live outside the repo and hold a password in the clear. They
// are never in git, and a checkout without them still builds — unsigned,
// which is exactly what an unsigned build should be.
val signingProperties = Properties()
val signingFile = File(System.getProperty("user.home"), ".flamenet-android-signing.properties")
if (signingFile.exists()) {
signingFile.inputStream().use { signingProperties.load(it) }
}
val home = File(System.getProperty("user.home"))
val signingFile = listOf(
File(home, ".flamenet-messenger-signing.properties"),
File(home, ".flamenet-android-signing.properties"),
).firstOrNull { it.exists() }
signingFile?.inputStream()?.use { signingProperties.load(it) }
signingConfigs {
if (signingProperties.isNotEmpty()) {