Sécurité et flux de données
Où résident vos données, ce qui est chiffré, comment la connexion IA est authentifiée et limitée, ce qu'Assetli journalise, ce que voit le fournisseur d'IA et ce que nous ne savons pas encore faire.
Dernière mise à jour: 30 octobre 2026
Cette page s’adresse à un lecteur technique et sceptique. Chaque affirmation ci-dessous a été vérifiée dans le code de l’application à la date indiquée plus haut. Ce qui relève d’une limite et non d’une fonctionnalité figure au chapitre Ce que nous ne savons pas encore faire, signalé comme prévu.
En résumé
Deux pages complémentaires vont plus loin : Qui traite vos données liste chaque tiers et ce qu’il reçoit, Combien de temps les données sont conservées indique la durée de conservation de chaque enregistrement.
- Assetli ne se connecte jamais à votre banque et ne conserve aucun identifiant bancaire. Les données arrivent par import de fichier, saisie manuelle ou synchronisation facultative depuis Wallet by BudgetBakers à l’aide du jeton de cette application.
- Les fichiers que vous joignez sont dans un stockage privé situé dans l’UE, sans adresse publique, et ne s’affichent qu’à leur propriétaire connecté.
- Avec la double authentification activée, le code est demandé à chaque connexion par mot de passe. Après une connexion via Google ou Apple, Assetli ne demande pas de code : la vérification est assurée par votre compte Google ou Apple. « Se déconnecter de tous les appareils » met fin à toutes les sessions, application mobile et connexions IA comprises.
- La connexion IA repose sur OAuth 2.1 avec PKCE, un écran de consentement, des jetons de courte durée stockés sous forme d’empreinte, un profil par connecteur et des autorisations distinctes pour la lecture et l’écriture. L’écriture exige un forfait payant.
- Votre conversation avec l’IA n’atteint pas Assetli. Le serveur ne reçoit que les appels d’outils. Les lectures ne sont pas journalisées, les écritures le sont pendant douze mois.
- Aucune bibliothèque tierce de suivi d’erreurs ou d’analytique ne tourne sur l’API ni dans les applications mobiles (Android et iPhone). Google Analytics et Microsoft Clarity ne se chargent sur le site public qu’après le consentement aux cookies et ne voient jamais le trafic de l’API ; Vercel Web Analytics compte les pages vues sur le site et dans le tableau de bord sans cookies.
Où résident les données
| Quoi | Où |
|---|---|
| Application et API | Vercel, région de Francfort (fra1) |
| Base de données | MongoDB Atlas, région de Francfort (UE) |
| Fichiers joints (photos, documents, tickets) | Cloudflare R2, un stockage privé soumis à la juridiction UE (les objets restent dans l’UE), sans adresse publique. Un fichier ne s’affiche qu’à son propriétaire connecté : le serveur vérifie la connexion et l’appartenance de l’enregistrement au profil actif, puis délivre un lien signé valable 15 minutes au plus, ou transmet lui-même le fichier (aperçu sur le web, photos des objets de valeur). Le lien lui-même ne demande pas de connexion, c’est pourquoi sa durée est courte. Les fichiers téléversés auparavant ont été déplacés dans l’UE le 30 octobre 2026 et les copies d’origine supprimées. Les icônes d’abonnements et de budgets et les fichiers temporaires sont sur Vercel Blob. Les relevés importés ne sont pas conservés du tout |
| Données de référence publiques (grilles tarifaires, statistiques) | Cloudflare R2, un stockage public distinct (aucun fichier d’utilisateur) |
| Sauvegarde de la base | Archive mongodump chiffrée en AES-256 (avec vérification qu’elle se déchiffre), stockée sur l’ordinateur de l’exploitant en République tchèque ; programmée chaque nuit. Les sauvegardes de plus de 30 jours sont supprimées, mais les 7 dernières sont toujours conservées, même si elles sont plus anciennes. Une seconde copie, chiffrée avant de quitter le serveur de build, est conservée 30 jours comme artefact GitHub Actions, uniquement lorsque la tâche y tourne (elle ne tourne plus depuis le 21 octobre 2026). La sauvegarde nocturne échoue actuellement, voir Ce que nous ne savons pas encore faire |
| Taux de change | Récupérés auprès de frankfurter.app (taux BCE). La requête ne contient que des codes de devises |
| Paiements | Stripe. Les données de carte n’atteignent jamais Assetli |
Connexion à Assetli
- Par e-mail et mot de passe. Les mots de passe sont stockés sous forme d’empreinte bcrypt.
- Connexion via Google ou Apple (OAuth), aussi en natif dans l’application mobile.
- Authentification à deux facteurs facultative par application TOTP avec codes de secours. Une fois activée, le code (de l’application d’authentification, ou un code de secours) est demandé à chaque connexion par mot de passe, sur le web et dans l’application, ainsi qu’à l’entrée dans l’administration de l’exploitant.
- Après une connexion via Google ou Apple, Assetli ne demande pas de code, ni sur le web ni dans l’application. La vérification est assurée par votre compte Google ou Apple (clé d’accès ou passkey, leur validation en deux étapes ; Apple l’exige pour « Se connecter avec Apple »). Nous vous recommandons d’y activer la validation en deux étapes ou une clé d’accès.
- Le secret TOTP est chiffré, un même code ne peut pas servir deux fois et un code de secours ne fonctionne qu’une fois.
- Après 5 tentatives échouées en 15 minutes, le compte est verrouillé 15 minutes ; les mauvais codes de double authentification comptent aussi, qu’ils soient saisis à la connexion, dans l’application ou dans les Paramètres (désactivation de la double authentification, nouveaux codes de secours).
- La session repose sur un cookie HTTP-only émis par la bibliothèque Auth.js ; elle est valable 7 jours après la dernière utilisation.
- Se déconnecter de tous les appareils (Paramètres sur le web et dans l’application) met fin à toutes les sessions web, révoque les jetons de l’application mobile, du module Google Sheets et de toutes les connexions IA (MCP), et supprime les enregistrements de notifications push. La même chose se produit automatiquement après une réinitialisation du mot de passe. Après l’activation ou la désactivation de la double authentification, les autres appareils sont déconnectés et vous restez connecté uniquement là où vous avez fait la modification. Les autres instances du serveur prennent le changement en compte dans les 30 secondes.
- Des e-mails de sécurité sont envoyés après une connexion depuis un nouvel appareil, après une réinitialisation du mot de passe et après la désactivation de la double authentification. Un appareil est reconnu par son type, son navigateur et son système, sans versions ni adresse IP ; la base ne conserve qu’une empreinte de ces éléments. L’e-mail indique l’appareil, le pays approximatif, l’heure et le mode de connexion. On ne peut pas se désabonner de ces e-mails.
- L’administration ne laisse entrer l’exploitant qu’avec une double authentification validée dans la même session, et inscrit chaque accès dans un journal d’audit (voir Journalisation ci-dessous).
Chiffrement
- Tout le trafic passe par HTTPS.
- Un chiffrement au niveau des champs en AES-256-GCM (texte chiffré versionné, vecteur d’initialisation aléatoire, balise d’authentification) protège : le numéro de compte, l’IBAN et les notes des comptes bancaires, le jeton Wallet by BudgetBakers, les secrets à deux facteurs, vos propres clés d’API de fournisseurs d’IA, les notes Family Legacy et les coordonnées de paiement des membres des groupes de dépenses partagées (numéro de compte ou IBAN, nom et code de la banque, adresse de portefeuille crypto ; le lien public d’un groupe ne les reçoit pas du tout). Les champs chiffrés ne peuvent pas être filtrés par une requête en base et ne sont déchiffrés qu’à l’affichage de l’enregistrement. Sont aussi stockés chiffrés : le jeton de rafraîchissement de « Se connecter avec Apple », les identifiants d’achat Google Play et votre adresse secrète d’import par e-mail.
- Les jetons d’accès et de rafraîchissement OAuth, les codes d’autorisation et les clés d’API sont stockés sous forme d’empreinte SHA-256. La forme lisible n’existe que dans votre client. De même pour les jetons des liens de réinitialisation du mot de passe et de vérification de l’e-mail : la base ne contient qu’une empreinte, le lien lisible n’existe que dans l’e-mail et chacun ne sert qu’une fois.
La connexion IA, étape par étape
Voici ce qui se passe lorsque vous posez à Claude, ChatGPT ou Gemini une question qui nécessite vos données.
- Votre client appelle
POST /api/mcpavec un corps JSON-RPC, c’est-à-dire le nom de l’outil et ses arguments. Rien d’autre de la conversation n’est envoyé. - Le middleware laisse passer la requête. Ce chemin n’a pas de mot de passe global et le corps de la requête n’est pas journalisé.
- Vérification du jeton. Le jeton de l’en-tête
Authorization: Bearerest haché puis recherché en base. Il doit exister, ne pas être expiré (1 heure), ne pas être révoqué, et son destinataire doit correspondre à l’hôte. L’enregistrement fournit votre identifiant d’utilisateur, le profil choisi au consentement, les autorisations et l’identifiant du client. - Autorisation, forfait et jeton d’aperçu. Chaque outil de la catégorie écriture, aperçus (
prepare_*) compris, exige l’autorisationwriteet un forfait Premium ou Max. Sans l’autorisationwrite, les outils d’écriture ne sont pas proposés au client et un appel renvoieSCOPE_REQUIRED. Avec l’autorisationwrite, ils sont proposés aussi dans le forfait Free, pour que l’écriture fonctionne dès le passage à Premium, mais chaque appel sans forfait Premium ou Max renvoieTIER_FEATUREsans que rien ne s’exécute. La vérification du forfait a lieu à chaque appel, pas dans la liste d’outils, et s’applique donc aussi après la fin de l’essai. Une écriture doit en outre porter un jeton de confirmation émis par son outil d’aperçu pour les mêmes arguments au cours des dix dernières minutes ; sans lui, ou avec des arguments différents, l’écriture est refusée. - Exécution de l’outil. Le traitement interroge MongoDB avec un filtre sur votre utilisateur et votre profil. Les résultats sont assemblés dans un ensemble de champs fixe.
- Audit (écritures uniquement). Le nom de l’outil, l’identifiant du client, le résultat et un résumé des arguments sont enregistrés dans la collection
mcp_audit_logsavec une expiration à 365 jours. Les montants, catégories, symboles, dates et noms de cibles sont conservés ; le texte libre (descriptions, notes, nom du commerçant, contenu du relevé) n’est stocké que sous forme de longueur, le contenu du relevé également sous forme d’empreinte. L’enregistrement lui-même porte son origine (createdVia: MCP et identifiant du connecteur) — transactions, ordres, relevés, objets de valeur, budgets et règles de catégorisation — et les listes des transactions, ordres, relevés, objets de valeur et budgets le signalent par un badge « IA » dont l’infobulle indique le canal et l’outil. Les actions qui modifient des enregistrements existants au lieu d’en créer un (apparier un virement, appliquer une règle, déplacer l’argent d’une enveloppe, confirmer un solde) sont consignées dans le journal d’audit. - Réponse. Le résultat en JSON revient à votre client, qui le transmet au modèle.
Ce qu’Assetli voit et ne voit pas
| Assetli le voit-il ? | |
|---|---|
| Votre question et les réponses du modèle | Non. Elles restent dans le client IA. |
| Nom de l’outil et arguments | Oui, le temps du traitement de la requête. |
| Arguments des appels d’écriture | Oui, sous forme de résumé sans texte libre, douze mois dans le journal d’audit. |
| Arguments des appels de lecture | Ne sont pas conservés. |
| Résultats des outils | Calculés et renvoyés, non conservés. |
| Identité du client | Le nom enregistré du connecteur et son identifiant. Dans les journaux d’hébergement habituels, également l’adresse IP et l’agent du serveur du client IA. |
La phrase « nous ne voyons que ce que vous voyez en cliquant dans l’application » est exacte pour la lecture. Pour l’écriture, Assetli conserve un peu plus qu’un clic dans l’application, à savoir l’enregistrement d’audit.
Ce que voit le fournisseur d’IA
Le fournisseur qui exécute votre modèle (Anthropic pour Claude, OpenAI pour ChatGPT, Google pour Gemini) voit vos questions, les résultats des outils et donc chaque chiffre qu’un outil renvoie. Ces données sont traitées selon les conditions de ce fournisseur, pas selon celles d’Assetli. Les outils renvoient les mêmes données que celles affichées dans l’application : soldes, transactions avec description et commerçant, positions, valeurs et adresses de biens immobiliers, plaques d’immatriculation, dettes. Ils ne renvoient jamais de numéros de compte, d’IBAN, de mots de passe, de jetons ni de données d’autres utilisateurs.
L’assistant intégré à l’application fonctionne autrement : c’est Assetli qui envoie vos messages et un instantané financier à Anthropic (ou au fournisseur dont vous avez saisi la clé) et qui conserve la conversation dans votre profil. Voir Assistant IA.
Portée du jeton
- Un utilisateur, un profil. Le jeton porte le profil choisi au consentement. Un connecteur ne peut pas changer de profil.
- Lecture ou écriture. Accordée sur l’écran de consentement, l’écriture inclut la lecture. Le serveur vérifie l’autorisation à chaque appel.
- Lié au destinataire. Un jeton émis pour
assetli.appest refusé par tout autre hôte. - De courte durée. Jeton d’accès 1 heure, jeton de rafraîchissement 60 jours, remplacé à chaque renouvellement.
- Révocable. Menu du compte → Connexion IA (MCP) liste chaque connecteur et, après confirmation, révoque tous ses jetons d’un coup. « Se déconnecter de tous les appareils » dans les Paramètres révoque les jetons de tous les connecteurs en une fois.
- Aucun secret partagé. Les clients sont des clients OAuth publics avec PKCE, il n’existe aucun secret client et votre mot de passe ne quitte jamais Assetli.
- Uniquement l’endpoint MCP. Le jeton d’un connecteur tiers est accepté par
/api/mcpet nulle part ailleurs. L’API REST n’accepte les jetons Bearer que de notre propre application mobile.
Le même serveur OAuth délivre aussi des jetons à l’application Assetli pour Android et iPhone, encore en test fermé et pas accessible au public. On peut s’y connecter par e-mail et mot de passe, avec Google ou Apple directement dans l’application, ou dans le navigateur du système ; le mot de passe et le code de double authentification sont vérifiés par la même fonction que sur le web, verrouillage des tentatives compris (pour un compte avec double authentification, l’application demande le code après une connexion par mot de passe ; pas après une connexion via Google ou Apple, où la vérification est assurée par le compte Google ou Apple), et les jetons sont émis par la même fonction que /api/oauth/token (accès 1 heure, rafraîchissement 60 jours). L’application saute l’écran de consentement, car c’est la nôtre. Elle garde ses jetons dans le stockage sécurisé du téléphone (Android Keystore, trousseau sur iPhone), et ils se révoquent sur la même page Connexion IA (MCP) ou avec « Se déconnecter de tous les appareils ».
Journalisation
| Journal | Contenu | Conservation |
|---|---|---|
| Journal d’audit MCP (base) | Utilisateur, profil, identifiant du client, nom de l’outil, succès ou erreur, résumé des arguments sans texte libre. Écritures uniquement. Consultable dans le menu du compte → Connexion IA (MCP). | 365 jours |
| Journal des requêtes d’hébergement (Vercel) | Méthode, chemin, statut, durée, IP du client. Sans corps de requête. | Selon le forfait Vercel |
| Sortie des fonctions (Vercel) | Messages d’erreur émis par l’application en cas d’échec, par exemple une erreur de base. Pas les corps de requête. | Selon le forfait Vercel |
| Journal d’erreurs d’administration (base) | Erreurs applicatives de certains endpoints, de l’interface web et des applications mobiles (Android et iPhone) : message et trace technique de l’erreur, page ou écran, version de l’application et du système, identifiant du compte comme pseudonyme (sans nom ni e-mail), adresse IP et User-Agent. Non utilisé sur le chemin MCP. | 12 mois, puis supprimé automatiquement |
| Journal des accès à l’administration (base) | Qui, quand, méthode, chemin et identifiants tirés de l’adresse (ID d’utilisateur ou d’enregistrement, collection). Aucun contenu affiché par l’administration, aucune adresse e-mail. Une même requête dans un délai de 30 secondes n’est inscrite qu’une fois. La suppression d’un compte n’efface pas la trace de sa consultation. | 365 jours, puis supprimé automatiquement |
Ce qui ne s’y trouve pas :
- Aucun Sentry, Datadog, PostHog ni bibliothèque équivalente dans l’API ou dans les applications mobiles (Android et iPhone). Une telle dépendance n’existe pas dans le projet.
- Aucun middleware capturant les corps de requête ou de réponse.
- Google Analytics et Microsoft Clarity ne se chargent que dans le navigateur, sur le site public, et seulement après le consentement aux cookies. Le trafic de l’API et du MCP ne les atteint jamais. Seule exception : un événement d’inscription. Quand vous créez un compte, notre serveur le signale à Google Analytics — uniquement si vous avez accepté l’analyse (sinon le cookie Analytics n’existe pas et rien n’est envoyé). Il contient l’identifiant anonyme Analytics et la page d’où vous venez, jamais votre nom, votre e-mail ni vos données financières.
- Vercel Web Analytics compte les pages vues sur le site et dans le tableau de bord (pas dans l’application mobile) sans cookies et sans consentement ; l’identifiant de visite est une empreinte valable un jour. Il ne voit jamais le trafic de l’API ni du MCP.
Autres connexions
- Wallet by BudgetBakers (Premium, Max) : vous saisissez un jeton d’API de Wallet, Assetli le stocke chiffré et ne fait que lire l’API de Wallet. Il n’écrit jamais dans Wallet. Le jeton est supprimé quand vous vous déconnectez. Techniquement, il permettrait aussi d’écrire ; Assetli ne s’en sert que pour lire.
- Clés d’API (
ask_…) : un type de clé distinct, en lecture seule, destiné à l’API de données (tarifs de l’énergie, taux des crédits immobiliers et de l’épargne). Elle ne donne pas accès à vos données financières. Elles sont stockées sous forme d’empreinte SHA-256, peuvent être limitées à la lecture, dotées d’une expiration et révoquées dans les Paramètres. La connexion IA ne les utilise pas. - Module complémentaire Google Sheets : un type de jeton propre, accepté seulement par deux points d’accès liés aux prêts immobiliers. Il est listé et révocable sur la même page de connexions.
- Extension de navigateur pour la vérification immobilière : elle lit l’annonce ouverte dans votre navigateur et envoie son texte au point d’accès d’analyse. Le serveur ne visite jamais les portails immobiliers lui-même. D’emblée, elle n’a accès qu’à assetli.app ; après un clic sur son icône, elle demande l’autorisation pour le site de l’onglet ouvert, et Chrome vous la demande si elle n’a pas encore été accordée. À l’ouverture de son panneau, elle envoie l’adresse de la page ouverte pour vérifier si vous l’avez déjà analysée ; elle ne lit le contenu de la page qu’après un clic sur « Analyser cette page ».
Vos droits sur les données
- Export (sur le web et dans l’application mobile) : Paramètres → Exporter les données produit un fichier contenant tous les enregistrements qui vous appartiennent, toutes collections confondues, sans secrets d’authentification ni journaux temporaires.
- Suppression : Paramètres → Supprimer le compte efface l’utilisateur et chaque enregistrement qui lui est rattaché, y compris ceux liés à un groupe de dépenses partagées ou à un contact Family Legacy, ainsi que tous les fichiers. Une phrase de confirmation est demandée. Dans l’application mobile (Android et iPhone) : Plus → Paramètres → Supprimer le compte. Détails : Suppression du compte.
Ce que nous ne savons pas encore faire
Nous préférons l’écrire plutôt que vous laisser le découvrir.
- La confirmation est imposée comme un appariement, pas comme un consentement. Le serveur refuse une écriture dépourvue du jeton issu de l’aperçu correspondant, pour les mêmes arguments, dans les dix dernières minutes. Savoir si vous avez réellement vu l’aperçu et donné votre accord reste du ressort du client IA ; Claude, ChatGPT et Gemini ajoutent leur propre demande d’autorisation d’outil.
- La durée de conservation des journaux côté hébergeur dépend du forfait Vercel et n’est pas pilotée par l’application.
- La sauvegarde nocturne automatique de la base échoue depuis le 22 octobre 2026. Nous la réparons. La seconde copie dans GitHub Actions n’est plus créée non plus depuis le 21 octobre 2026.
- Le développement travaille sur la base de production. L’exploitant accède aux données pour l’exploitation, la correction de bugs et le développement, et uniquement dans la mesure nécessaire. Le développement et les scripts de contrôle tournent sur la base de production, et certains parcourent les profils des utilisateurs (par exemple la vérification que l’IA affiche les mêmes chiffres que le site). L’exploitant utilise pour cela un assistant de programmation IA d’Anthropic, si bien que la sortie de ces scripts peut être traitée par Anthropic en tant que sous-traitant. Une base de développement séparée est notre plus grand chantier ouvert.
- L’outil de base de données de l’administration peut aussi modifier et supprimer des enregistrements. Y accéder exige la double authentification et est journalisé ; il n’affiche les champs chiffrés que sous forme chiffrée, et les mots de passe, jetons OAuth et clés d’API n’existent dans la base que sous forme d’empreintes.
- Les vulnérabilités connues des bibliothèques ne sont pas encore surveillées automatiquement. Nous mettons en place des alertes.
Signaler un problème de sécurité
Écrivez à info@assetli.app en indiquant « security » en objet. Merci de ne pas faire de tests sur les données d’autres utilisateurs.