RFC: Proposition d'un format standardisé pour les userPrivateData dunipod

@Chiara07 a commencé à travailler, dans une version de développement de Gecko, sur la migration des profils, des contacts et des files de certifications de Cesium+ vers Dunipod. Dans ce cadre, elle a ouvert un ticket côté Cesium2 pour standardiser le format de la file de certifications entre les applications.

Je pense qu’il faut en profiter pour standardiser le format de toutes les données qui seront stockées dans le domaine userPrivateData de Dunipod.

C’est le bon moment pour le faire, car dès qu’une application utilisera Dunipod en production pour ce type de données, elle imposera un standard de fait, et toutes les autres applications se retrouveront obligées de gérer les éventuels défauts de cette première implémentation. C’est pourquoi je souhaite que nous prenions le temps, dès maintenant, de définir un format propre, efficient, versionné et évolutif.

Le domaine userPrivateData a vocation à stocker toutes les données qu’un utilisateur souhaite conserver pour lui-même. Cela inclut potentiellement (liste non exhaustive) :

  • La file de certifications
  • Les contacts
  • Les préférences de l’utilisateur
  • Les données spécifiques à chaque application, comme les données de configuration

À l’avenir, ce domaine pourrait également être utilisé pour stocker des fragments de Shamir chiffrés, dans le cadre d’un protocole de membres gardiens, par exemple, ou encore pour d’autres usages auxquels nous ne pensons même pas encore.

Tout compte (même non-membre) peut stocker des données dans son espace userPrivateData, mais il doit posséder un certain solde en Ğ1, dont le montant minimum dépend de la taille des données stockées, et ce, afin de lutter contre le spam.

Pour limiter la consommation du quota de stockage de l’utilisateur, le format doit être binaire et compact. Dans la RFC, je propose un format basé sur SCALE, car toutes les applications gèrent déjà ce format pour interagir avec Duniter.

Dunipod est totalement agnostique quant au format des données userPrivateData. Il se contente de vérifier leur taille et de s’assurer que l’utilisateur a le droit de stocker des données de cette taille.

Voici la Merge Request qui propose la RFC. J’invite tous les développeurs d’applications à l’analyser et à faire des retours constructifs, directement sur la MR ou dans ce sujet du forum :

cc @poka @vjrj @Nicolas80 @vit @Moul @kapis

Tu m’as tagué ici donc j’en profite pour dire que je prends ma retraite du projet duniter, tout du moins pour cette année. Je suis bien trop occupé à côté et je pense avoir fait le tour ici toutes ces années. @Chiara07 fait un travail formidable sur Gecko et j’espère que d’autres viendront l’aider, n’hésitez pas, vous lecteur de ce forum, à tenter de venir contribuer sur les outils de l’écosystème duniter que vous aimez.

Concernant le sujet de ce topic, je n’ai pas lu la RFC en détails mais si je comprends bien il s’agit donc de champs libres côté Dunipod pour les données privées et chiffrés des users. Un peu comme le permet elasticsearch.

Donc ça signifie que pour avoir un typage fort du schéma de donnée proposé en RFC, ça doit se jouer côté libs de chaque apps ? Aucun moyen de valider la consistance du schema de donnée depuis l’api de dunipod ? Voir d’en extraire un schéma et du codegen donc ?

Je comprends et je te souhaite tout le succès possible dans tes nouveaux projets ! :slight_smile:

Je sais que tu ne seras jamais très loin en cas de besoin, mais que tu seras moins disponible qu’avant. Merci encore pour toutes tes précieuses contributions !

Je plussoie, @Chiara07 fait un excellent travail ! Et grâce à l’IA, vous aussi, vous pouvez vous lancer. Ça demande du temps et de la motivation, mais ce n’est pas si difficile. @Chiara07 peut en attester !

Oui, j’ai préféré privilégier la flexibilité côté Dunipod pour les userPrivateData, car ces données sont chiffrées et Dunipod ne peut donc pas en vérifier la structure. On peut ajouter des contrôles côté Dunipod pour toutes les données en clair (ce que fait déjà dunipod pour les profils), mais le blob chiffré est forcément opaque pour Dunipod.

Effectivement la question du stockage public chiffré des données “privées” est intéressante. Il faut veiller à ne pas y mettre de données qui seraient trop sensibles si la clé fuitait, car contrairement à un réseau privé, l’archivage des données ne nécessite pas une attaque type “man in the middle”. De plus, certaines métadonnées nécessairement publiques peuvent être sensibles, il faut aussi y faire attention.

Je n’ai pas creusé cette question avant donc je vais surtout partager mes questions à chaud qui ne concernent pas tant le format des données elles-même, mais la modalité d’accès :

  • quelle clé utilise-t-on pour référencer une donnée ? seulement les 32 octets d’une clé publique vers un blob unique ? plus d’octets pour pouvoir stocker plusieurs blobs pour une seule clé et accéder à un seul ?
  • le périmètre de la RFC couvre-t-il uniquement le dépôt de données ou également leur indexation ? par exemple ou pourrait dans l’idée déposer le blob chiffré d’un index des documents privés d’une clé, ce qui permettrait :
    • de réceptionner des messages chiffrés sur un appareil A
    • de les indexer et publier un index chiffré sur les datapods
    • de récupérer l’index chiffré sur un appareil B et faire une recherche dans les messages sur une clé d’indexation (par exemple lister les messages de la semaine passée) pour ne récupérer que ces messages sur les datapods (via leur clé individuelle)
      Sans ça l’appareil B serait obligé de récupérer tous les messages pour faire une recherche dedans.

Ces questions me paraissent moins urgentes que celles du format de versionnage des données si on passe par un “shared domain”

De mon côté pour les datapods j’avais exploré un format de données où le versionnage ne nécessitait pas un consensus, mais était entièrement auto-embarqué avec un préfixe qui n’est pas un entier numéroté de manière incrémentale mais un hash d’un document public de description du format. Cette approche fait perdre un peu en compacité (32 octets d’adressage plutôt que 16 bits et un annuaire commun) mais était plus adapté à mon contexte “local first” et “sans consensus”.

Pour le domaine userPrivateData, c’est un blob par compte, on commence simple. On pourra toujours ajouter du multi-blob plus tard, tout en restant rétrocompatible avec le blob historique.

Uniquement le format des données et la manière de les chiffrer.
La manière d’indexer les données est déclarée par les offchain rules, qui prévoient une indexation par auteur pour les userPrivateData, car comme indiqué, ce domaine sert uniquement aux données que l’utilisateur stocke pour lui-même.

Ces idées que tu mentionnes, j’y ai déjà pensé, mais elles feraient l’objet d’autres domaines dans le futur. C’est hors scope de userPrivateData.