L'application
Synchroniser entre appareils
Activer la synchronisation entre appareils, le chiffrement, et la clé de récupération mise sous séquestre par l'opérateur
Cette page est traduite automatiquement à partir de la documentation en anglais.
Sur ta propre instance, openplate est une application locale par défaut, ton journal reste dans l'IndexedDB du navigateur sur l'appareil que tu utilises, et rien n'en sort tant que tu ne fais pas pointer l'application vers un serveur central. Déplacer ce journal d'un appareil à l'autre est la seule chose qui nécessite un compte, cela se trouve donc dans un service distinct, openplate-core, avec ses propres image, base de données et secrets.
Sur ta propre instance, la synchronisation est facultative. Non définie, openplate ne perd aucune fonctionnalité. Sur le service hébergé, chaque compte se synchronise, de sorte que le journal possède aussi une copie chiffrée sur le serveur.
Ce qui circule entre tes appareils
Tout ce que le moteur de synchronisation appelle une entité est fusionné ligne par ligne, donc une modification effectuée sur un appareil arrive sur les autres et une suppression effectuée sur un appareil supprime la ligne sur les autres. Dans cette version, cela concerne tes aliments personnels, ton journal alimentaire, tes saisies de poids, ton profil et tes objectifs, tes jeûnes, ton garde-manger, ta routine de jeûne, ainsi que les marques d'activité et les récompenses associées à la série. Tes repas enregistrés circulent également, sous forme de liste globale plutôt que ligne par ligne, ce qui est la dernière partie du journal attendant encore une fusion par ligne.
Tes clés de partage et de recherche voyagent aussi, dans une partie scellée du blob que tes propres appareils peuvent ouvrir, tout comme un opérateur détenant ta clé de récupération (voir Le chiffrement, et ce que l'opérateur détient). Un clinicien à qui tu donnes accès à un journal ne peut pas la lire.
Trois éléments ne circulent jamais, quels que soient tes réglages :
- Les photos d'assiette. Elles résident dans une base de données distincte sur l'appareil qui les a prises, elles sont exclues de la charge utile de synchronisation et de chaque fichier de sauvegarde, et elles s'effacent selon un calendrier que tu définis.
- La clé de ton fournisseur d'IA. Elle réside dans sa propre base de données sur l'appareil où tu l'as saisie, et elle n'est transmise à personne d'autre qu'au fournisseur que tu as choisi.
- L'historique de tes suppressions. Ton appareil consigne les suppressions qu'il a effectuées pour pouvoir prouver qu'elles étaient délibérées, et cette liste reste sur l'appareil. Les suppressions elles-mêmes circulent ; la liste ne circule pas.
Ce dont elle a besoin
- Une instance openplate-core active : celle hébergée, la tienne, ou n'importe quel serveur tiers implémentant le protocole. Pour déployer la tienne, utilise
docker/topologies/compose.core.yml: voir self-hosting.md et topologies.md. CORE_URLdéfini sur l'application, pointant vers ce service.- Une page sécurisée. La connexion dérive tes clés avec la Web Crypto API du navigateur, que les navigateurs ne proposent que sur
https://ou surlocalhost. Voir self-hosting.md. - Un compte. Sur ta propre instance, l'inscription se fait sur invitation sauf si tu définis
OPEN_SIGNUP=true, tu génères donc toi-même le premier, self-hosting.md.
L'activer
CORE_URL contrôle l'ensemble de la fonctionnalité.
- Non défini (par défaut) : aucune interface de synchronisation ne s'affiche, et aucune requête de synchronisation ne quitte l'application.
- Défini : les écrans de synchronisation s'affichent et communiquent avec cette URL. Son origine est ajoutée automatiquement à la directive
connect-srcdu CSP de production : tu n'as pas besoin deCSP_CONNECT_EXTRApour cela.
Redémarre l'application après modification. Si tu le retires, les écrans de synchronisation disparaissent et l'application cesse toute requête externe. Ton journal local reste intact dans les deux cas.
Ajouter un deuxième appareil : fais-le pointer vers le même CORE_URL et connecte-toi avec l'adresse e-mail et le mot de passe utilisés sur le premier. C'est toute la procédure, et rien n'a besoin d'être copié depuis le premier appareil.
Il doit s'agir d'une adresse qu'un navigateur peut joindre. Le client de synchronisation s'exécute dans la page, donc un nom d'hôte compose comme http://core:3000 ne fonctionne pas : utilise l'URL publique que les appareils de tes utilisateurs résolvent. Une valeur mal formée bloque le démarrage volontairement, afin qu'une faute de frappe ne ressemble pas à « la synchronisation est discrètement désactivée ».
La console de recherche (/study)
L'application intègre toujours une route /study, et elle reste inactive sur une instance ordinaire. Elle ne s'active que si le serveur central avec lequel elle communique possède SYNC_RESEARCH=true, ce qui correspond à désactivé par défaut : une instance que tu déploies sans modifier cet indicateur n'exécute aucune étude, ne conserve aucun graphe d'étude et ne propose aucune inscription. Lis .env.example de openplate-core avant de l'activer : cela amène le serveur à stocker des données personnelles liées à la santé, ce qui est une tout autre responsabilité que de conserver un journal chiffré.
Le chiffrement, et ce que l'opérateur détient
Ton mot de passe ne quitte jamais ton navigateur. Il est étiré avec Argon2id puis divisé par HKDF en branches indépendantes. Deux branches restent sur l'appareil pour déchiffrer la clé des données et tes paramètres privés. Une troisième branche est transmise au service comme identifiant de connexion. Ce sont des sœurs cryptographiques, sans relation parent-enfant, si bien qu'en détenir une ne révèle rien sur les autres. Ton journal est chiffré sur l'appareil avant son téléversement et reste chiffré en transit ; le service stocke un texte chiffré opaque, et ce qu'il voit en dehors de cela se résume à une adresse e-mail ainsi qu'à la taille et l'horodatage de tes téléversements.
L'opérateur détient une clé de récupération. Lors de l'inscription, l'application génère un code de récupération, chiffre ta clé de données avec ce code et l'envoie au serveur, qui le garde scellé sous un secret qui lui est propre. C'est ce qui permet à l'option "mot de passe oublié" de restituer ton journal plutôt qu'un compte vide : le lien de réinitialisation (envoyé par e-mail, ou remis par l'administrateur sur une instance sans e-mail) transmet à nouveau le code à ton navigateur, qui s'en sert pour déchiffrer la clé de données et la chiffrer à nouveau sous le nouveau mot de passe.
Pour le dire clairement, car c'est le compromis assumé par cette conception : l'opérateur d'une instance peut restaurer, et donc en principe lire, un journal hébergé chez lui. Sur une instance que tu héberges toi-même, cet opérateur, c'est toi. Sur une instance gérée par une organisation, celle-ci voit déjà chaque photo d'assiette qui passe par son proxy IA, cela change donc moins la donne qu'il n'y paraît, et c'est le prix à payer pour réinitialiser un mot de passe sans perdre ses données.
Avant M192, il n'y avait aucun séquestre, et le risque était inverse : un mot de passe oublié couplé à un code de récupération perdu signifiait la perte définitive des données, pour nous comme pour toi, et l'application devait afficher le code une fois en demandant de le garder à vie. Personne ne le fait.
Les photos d'assiette ne font jamais partie d'une charge utile de synchronisation. Elles restent sur l'appareil qui les a prises, elles sont exclues des exports JSON, et sur une instance gérée, la copie qui parvient au proxy d'IA est lue une seule fois sans que le proxy la conserve. Une photo envoyée avec un signalement d'estimation erronée est conservée par l'opérateur pendant une durée limitée.
Partager un journal avec un praticien
Sur une instance dont le serveur central définit SYNC_SHARING=true, une personne peut autoriser un soignant, comme un diététicien, à lire son journal. Le soignant lui envoie un lien de connexion. La personne l'ouvre et saisit les douze caractères dictés par le soignant, afin de détecter une éventuelle mauvaise clé avant tout partage. La personne valide ensuite le partage sous Paramètres → Partage : l'application surchiffre la clé des données avec la clé publique du soignant, puis téléverse cette copie protégée. Le navigateur du soignant la déchiffre et affiche le journal à l'adresse /shared. Le serveur stocke la copie chiffrée, mais jamais sa clé d'accès. Un partage peut être révoqué à tout moment. Un compartiment privé du journal conserve les clés de recherche et de partage propres à la personne, et aucun soignant ne peut l'ouvrir. Ces clés figurent également en clair dans l'export JSON, afin qu'un appareil restauré puisse continuer à ouvrir ce qui a été partagé avec lui ; self-hosting.md détaille les conséquences pour ce fichier.
Le même écran contient l'interrupteur du pouls, un décompte optionnel des repas et des scans à l'échelle de l'instance ; architecture.md précise ce qu'il transmet.
Ce qui se trouvait ici auparavant : la passerelle
Jusqu'à la version M192, une personne pouvait rejoindre une passerelle IA distincte à partir du même lien d'invitation, et cette connexion suivait le compte à l'intérieur du compartiment scellé. Cette passerelle n'existe plus : le serveur central a repris le proxy IA. Ainsi, sur une instance exploitée par une organisation, un compte connecté disposant d'un quota effectue ses analyses via l'unique serveur avec lequel il communique déjà, sans aucune étape de connexion à transmettre ailleurs. Une instance que tu héberges toi-même ne change pas : une clé que tu configures reste sur l'appareil où tu l'as enregistrée.