From 103a2dda235fbdea62121091990ec27d94b1e36e Mon Sep 17 00:00:00 2001 From: Paul Hitt Date: Tue, 25 Aug 2026 19:15:36 -0400 Subject: [PATCH] Sign the messenger with its own key, not Files' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- app/build.gradle.kts | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index da6c621..12bbcfe 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -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()) {