Nøbody v1.6.0 boucle une refonte de 6 mois pour faire de l'app un logiciel libre : passage sous AGPL-3.0, Firebase remplacé par UnifiedPush, 3 services Tor .onion, fin de la dépendance aux Google Play Services.
Le coût : ~6 mois de travail. Le bénéfice : une app vérifiable, redistribuable, et utilisable sans aucun service Google. Cet article raconte le pourquoi, le comment et le ce-qui-suit.
Pourquoi il fallait passer en FOSS
Nøbody est une app de réseau social anonyme : pas de numéro de téléphone, pas d'email, pas de Google ID. Le pitch tient en une phrase, et le code l'a respecté depuis le début. Sauf que l'app reposait sur trois choses qui faisaient tousser tout développeur sensible à la liberté logicielle :
- Firebase Cloud Messaging (FCM) pour les notifications push. C'est-à-dire un SDK propriétaire de Google déclenchant un appel réseau vers les serveurs de Google — sur une app vendue comme « sans Google ».
- Un dépôt F-Droid secondaire (notre propre repo). Fonctionnel, mais pas dans la liste de packages F-Droid « principale », donc invisible à 99 % des utilisateurs F-Droid.
- Une licence trop permissive (MIT) qui aurait permis à un acteur malveillant de fork le code, l'incorporer dans une app surveillée, sans rendre les modifications.
L'objectif était simple : corriger les trois en même temps. Pas une fonctionnalité, mais un nettoyage architectural complet.
Le choix AGPL-3.0
Pourquoi AGPL et pas MIT ou GPLv3 ? Le modèle client-serveur de Nøbody voulait du copyleft réseau. La GPLv3 ne couvre que la distribution du binaire : si quelqu'un héberge un fork modifié sans jamais distribuer l'app, la GPLv3 ne l'oblige à rien.
L'AGPL ferme cette « ASP loophole » : même un service réseau qui n'est jamais distribué doit publier ses modifications. C'est exactement ce qui protège un projet de surveillance contre le vol par un hébergeur malveillant.
Le bonus, peut-être le plus important : une licence forte, c'est aussi une assurance pour les utilisateurs. Si je disparais, le code reste libre et copyleft. Personne ne peut le re-fermer en post-mortem.
La migration Firebase → UnifiedPush
Firebase Cloud Messaging, c'est facile. Trop facile. Trois lignes de Gradle et un onMessageReceived() et c'est fini. C'est aussi un appel non-désiré vers Google, même sur une app qui prétend ne pas en faire.
UnifiedPush est la spécification du Fediverse pour le push. Un protocole simple : un « distributor » (NTfy, ntfy.sh, Conversations) reçoit un POST HTTP du serveur, et réveille l'app correspondante. Pas de SDK, pas de tracker, pas de Google.
Le côté client (Flutter / Android)
Côté app, le paquet Flutter unifiedpush s'occupe de tout : l'app s'enregistre une fois auprès du distributeur, reçoit une adresse HTTPS (l'endpoint) et la transmet au serveur de Nøbody.
Subtilité importante : aujourd'hui (v1.8.0), une notification ne transporte ni le contenu des messages ni de pseudo. Le texte affiché, générique, est écrit par l'app sur le téléphone. Un distributeur, même compromis, apprend qu'une notification arrive — pas ce qu'elle dit.
Le côté serveur
Avant : le serveur appelait l'API FCM de Google avec une clé de service. Après : il envoie directement une requête HTTPS à l'adresse fournie par votre distributeur. L'intermédiaire n'est plus Google, mais le distributeur que vous avez choisi — et que vous pouvez héberger vous-même.
Le compromis : les utilisateurs doivent installer un distributor (NTfy en plus, à quelques Mo). En contrepartie, ils choisissent leur fournisseur de push, qui peut être auto-hébergé ou tournant sur Tor. C'est plus de liberté, pas moins.
Ajout de Tor : 3 hidden services
Ne pas garder les adresses IP dans ses journaux, c'est bien. Empêcher le serveur de les voir, c'est mieux. v1.6.0 ajoute trois hidden services Tor : l'API, le site web public, et le dépôt F-Droid. Pas de proxy, pas de bridge, pas de magie : tor tourne sur le même VPS et écoute en local sur les sockets onion.
L'architecture en ASCII
Concrètement, dans /etc/tor/torrc :
# API hidden service
HiddenServiceDir /var/lib/tor/nb-api/
HiddenServicePort 443 127.0.0.1:8443
# Site web
HiddenServiceDir /var/lib/tor/nb-web/
HiddenServicePort 443 127.0.0.1:8444
# Dépôt F-Droid
HiddenServiceDir /var/lib/tor/nb-fdroid/
HiddenServicePort 443 127.0.0.1:8445
Côté app, le mode Tor s'active dans les réglages (et, depuis la v1.8.0, dès le premier écran) : l'app redémarre, puis fait passer toutes ses connexions par Orbot, en SOCKS5 sur 127.0.0.1:9050, vers l'adresse .onion de l'API. Sans le mode Tor, elle se connecte en TLS classique.
Ce que ça a coûté, ce que ça a rapporté
Soyons honnêtes : ce n'a pas été gratuit.
Le coût
- ~6 mois de travail pour un solo dev (moi).
- ~12 000 lignes de code changées entre client et serveur.
- L'audit licence (chasse aux dépendances incompatibles AGPL) a pris 2 semaines à lui seul.
- Tests de non-régression sur 14 variantes Android (de 8.0 à 15) avant chaque release candidat.
- Durcissement du build Gradle (distribution Gradle épinglée par son empreinte SHA-256).
Le bénéfice
- Un premier pas vers le dépôt F-Droid principal. (Correctif : aucune demande d'inclusion n'avait été envoyée, et une bibliothèque Google non libre restait dans l'app ; la recette de build est prête depuis juillet 2026, la demande reste à faire.)
- Plus de Firebase ni de Google Play Services. (Correctif : le scanner de QR codes embarquait encore Google ML Kit jusqu'à la v1.7.1 ; depuis la v1.8.0, il n'y a plus aucun code Google.)
- Avec Orbot, un seul réglage fait passer toutes les connexions de l'app par Tor.
- L'AGPL crochete définitivement la possibilité qu'un fork hostile le re-licencie.
- La candidature au grant NLnet NGI0 est crédible : ils financent du FOSS, pas du semi-libre.
Et un bénéfice plus mou, mais réel : l'absence de Google et la présence de Tor changent la conversation. Au lieu de devoir affirmer « je ne collecte pas vos données » (ce que personne ne peut vérifier), le code de l'app montre ce qu'elle envoie. (Le code du serveur, lui, n'est pas encore publié.) C'est plus honnête, et ça se défend mieux.
Ce qui suit
v1.6.0 boucle un cycle, mais ne ferme pas la roadmap. Trois gros chantiers s'ouvrent maintenant :
- Le grant NGI0 : candidature en cours. S'il est accordé, il financera un audit de sécurité externe.
- iOS : (mise à jour, septembre 2026) plus prévu à court terme. Depuis février 2026, Apple n'accepte plus sur l'App Store les apps « utilisées principalement pour discuter anonymement ».
- L'audit indépendant : l'objectif est qu'un cabinet tiers regarde le code, le binaire et la configuration du serveur. Le rapport sera publié integralement, même les findings gênants.
Pour le reste, il y a la page roadmap. Tout est public, tout est daté, et on dira ce qu'on n'a pas livré quand on ne l'aura pas livré. C'est la différence entre un projet et un pitch deck.
Si vous avez des questions techniques, des idées de RFC, ou simplement envie d'engueuler un choix d'architecture : contact. Les issues sur Codeberg sont aussi ouvertes.
Merci d'avoir lu jusqu'ici. La suite arrive plus vite qu'on ne le croit.