security: move signing key out of source (rotated), add local replay guard

- Remove committed release keystore + hardcoded signing password
- Load signing config from gitignored app/keystore.properties
- Add single-use token guard (fail-open) to block on-device approval replay
This commit is contained in:
2026-07-10 09:31:13 +00:00
parent 336893ffa6
commit 093ddb7fce
3 changed files with 62 additions and 6 deletions
+20 -6
View File
@@ -1,8 +1,16 @@
import java.util.Properties
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}
// Signing secrets live in app/keystore.properties (gitignored), never in source control.
val keystorePropsFile = rootProject.file("app/keystore.properties")
val keystoreProps = Properties().apply {
if (keystorePropsFile.exists()) keystorePropsFile.inputStream().use { load(it) }
}
android {
namespace = "me.khodak.mfa"
compileSdk = 34
@@ -15,12 +23,15 @@ android {
versionName = "1.2"
}
val hasReleaseSigning = keystoreProps.getProperty("storePassword") != null
signingConfigs {
create("release") {
storeFile = file("homelab-mfa-release.keystore")
storePassword = "HomelabMFA2026!"
keyAlias = "homelab-mfa"
keyPassword = "HomelabMFA2026!"
if (hasReleaseSigning) {
create("release") {
storeFile = file(keystoreProps.getProperty("storeFile", "homelab-mfa-release.keystore"))
storePassword = keystoreProps.getProperty("storePassword")
keyAlias = keystoreProps.getProperty("keyAlias")
keyPassword = keystoreProps.getProperty("keyPassword")
}
}
}
@@ -29,7 +40,10 @@ android {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
signingConfig = signingConfigs.getByName("release")
// Only attach the release signing config when keystore.properties is present.
// Without it (e.g. a fresh clone), the release build stays unsigned rather than
// failing the whole configuration.
if (hasReleaseSigning) signingConfig = signingConfigs.getByName("release")
}
debug {
applicationIdSuffix = ".debug"