5.9 KiB
Signature release Kazeia — gestion du keystore
Résumé en 3 lignes : les deux APK (patient + admin) sont signées en release avec une seule clé :
/opt/Kazeia/keystore/kazeia-release.jks. Si cette clé est perdue, aucune mise à jour in-place n'est plus possible (désinstallation forcée = perte des données patient). → Sauvegarder le dossierkeystore/hors machine, maintenant.
1. Ce qui existe
| Fichier | Rôle |
|---|---|
/opt/Kazeia/keystore/kazeia-release.jks |
Keystore (RSA 4096, alias kazeia, valide jusqu'en 2056) |
/opt/Kazeia/keystore/credentials.properties |
Chemin + mots de passe, lu par Gradle (chmod 600) |
docs/RELEASE_SIGNING.md |
Ce document |
Empreinte du certificat (référence pour vérifier qu'on signe avec la bonne clé) :
SHA256: 4B:40:8D:9D:40:09:FD:68:F7:FD:5B:E0:BD:64:2B:D3:EE:B8:F8:BD:7A:84:D3:9C:84:90:B8:63:21:AF:E4:90
Le dossier keystore/ est hors git (le .gitignore racine est en liste blanche : tout
ce qui n'est pas explicitement inclus est ignoré). C'est voulu : un keystore + ses mots de
passe ne vont jamais dans un dépôt.
2. Comment c'est câblé
app/build.gradle.kts et app-admin/build.gradle.kts lisent
/opt/Kazeia/keystore/credentials.properties :
- Présent →
assembleReleasesigne avec la clé release. - Absent (autre machine, CI sans secrets) → le build ne casse pas : release signé
en debug avec un warning
⚠ keystore release absent. Ces APK de repli ne doivent JAMAIS être distribuées.
Une seule clé pour les deux apps (patient com.kazeia + admin com.kazeia.admin) :
même identité → permettra de protéger le ContentProvider par une
signature-permission (prévu au plan admin, pas encore fait).
3. Construire et distribuer une release
cd /opt/Kazeia/kazeia-android
# 1) Bumper versionCode (OBLIGATOIRE sinon l'OTA ne se déclenche pas)
# app/build.gradle.kts : versionCode = N+1
# (app-admin pareil si distribuée)
# 2) Build
./gradlew :app:assembleRelease # → app/build/outputs/apk/release/app-release.apk
# 3) Vérifier la signature (DOIT afficher l'empreinte SHA256 ci-dessus)
/opt/Kazeia/android-sdk/build-tools/*/apksigner verify --print-certs \
app/build/outputs/apk/release/app-release.apk | grep SHA-256
# 4) Publier via le catalogue Nextcloud
cp app/build/outputs/apk/release/app-release.apk /opt/Kazeia/kazeia-dist/apk/kazeia.apk
# Éditer kazeia-dist/catalog.spec.json : app.version_code = N+1, bump catalog_version
python3 /opt/Kazeia/kazeia-dist-tools/make_catalog.py --dist-root /opt/Kazeia/kazeia-dist --upload
Les tablettes voient catalog.app.version_code > BuildConfig.VERSION_CODE → téléchargent,
vérifient le SHA-256, et proposent l'installation (dialogue système).
4. SAUVEGARDE — le point qui ne pardonne pas
La clé EST l'identité de l'app. Android n'accepte une mise à jour que si elle est signée par la même clé que la version installée.
À faire immédiatement et à chaque rotation de machine :
# Copier le dossier ENTIER (jks + credentials) vers AU MOINS DEUX emplacements hors machine :
tar czf kazeia-keystore-$(date +%Y%m%d).tar.gz -C /opt/Kazeia keystore/
# → Nextcloud (dossier PRIVÉ, pas le partage soft/), clé USB au coffre, gestionnaire de mots de passe…
Recommandé : déposer l'archive sur box.kazeia.com dans un dossier privé + une copie
hors-ligne (USB). Vérifier la restauration une fois (tar xzf + keytool -list).
Sur une nouvelle machine de build : restaurer keystore/ dans /opt/Kazeia/,
vérifier chmod 600, builder — rien d'autre à configurer.
5. Scénarios de panne
| Scénario | Conséquence | Procédure |
|---|---|---|
| Keystore perdu (aucune sauvegarde) | Plus AUCUNE mise à jour in-place possible | Générer une nouvelle clé, désinstaller/réinstaller sur chaque tablette → perte des données patient (SQLCipher lié à l'install). Exporter l'historique via l'admin AVANT si possible. À éviter à tout prix → §4. |
| Mot de passe perdu (jks présent) | Identique à la perte du keystore | Aucun recouvrement possible sur un .jks. Le mot de passe est dans credentials.properties — sauvegardé AVEC le .jks. |
| Machine de build morte (sauvegarde OK) | Aucun impact | Restaurer keystore/ sur la nouvelle machine (§4). |
| Clé compromise (fuite) | Un tiers peut signer des mises à jour | Distribution étant privée (Nextcloud authentifié), changer aussi les identifiants WebDAV ; planifier une migration de clé (réinstallation contrôlée). |
6. Migration des tablettes existantes (one-shot)
Les installs actuelles sont debug-signées → la première APK release sera refusée en mise à jour (mismatch). Une fois par tablette :
# 1) (si données à garder) export de l'historique via l'app admin
# 2) Désinstaller les builds debug
adb uninstall com.kazeia ; adb uninstall com.kazeia.admin
# 3) Installer les release
adb install app/build/outputs/apk/release/app-release.apk
adb install app-admin/build/outputs/apk/release/app-admin-release.apk
# 4) Re-provisionner (les modèles sur stockage externe/`/data/local/tmp` SURVIVENT à la
# désinstallation ; profils/conversations/config in-app sont PERDUS → re-créer le profil)
Après cette migration, toutes les mises à jour passent par l'OTA catalogue, sans perte.
⚠ Le dev quotidien reste en debug (assembleDebug + adb install -r) : debug et
release sont signés différemment, on ne peut pas écraser l'un par l'autre. La tablette
de dev reste en debug ; les tablettes patient passent en release.
7. Rotation / clés multiples (futur)
- Pas d'expiration avant 2056 ; pas de rotation préventive nécessaire pour une distribution privée.
- Si un jour publication sur un store : Google Play App Signing prendra cette clé comme « upload key » et gérera la clé de signature côté store (le risque de perte disparaît).