Fabriqué dans l’UE, et là où vivent vos données
Où Nessie est conçu, où vivent vos données et ce que vous contrôlez lorsque vous l’hébergez vous-même.
Qui le conçoit, et sous quel droit
Nessie est conçu par UnlikeOtherAI s.r.o., une société immatriculée en République tchèque et soumise au droit tchèque.
Cette page décrit comment le logiciel est construit et où il fonctionne. Ce n’est pas une déclaration de conformité : Nessie ne détient aucune certification de sécurité, et rien ici ne doit être lu comme tel. Les données personnelles traitées et leur base juridique relèvent de la politique de confidentialité, qui est une page distincte.
Où fonctionne le produit hébergé
Nessie Cloud fonctionne chez des hébergeurs européens — Scaleway, Hetzner et d’autres. Nous retenons le meilleur service que chacun propose, de sorte que différentes parties du produit peuvent tourner chez différents hébergeurs, tous en Europe.
Toute précision supplémentaire — un site, une ville ou un centre de données en particulier — n’est volontairement pas indiquée ici, car elle deviendrait obsolète sans que personne s’en aperçoive.
L’auto-hébergement vous laisse le choix
L’endroit où fonctionne une instance auto-hébergée est un paramètre de déploiement, pas un paramètre du produit. Le chemin « une seule machine » est une pile Docker Compose que vous placez sur la machine de votre choix. Dans l’arborescence Terraform destinée à un cloud géré, la région est une entrée sans aucune valeur par défaut : rien n’y peut être deviné, donc rien n’y a de valeur par défaut, et la base de données, le bucket de stockage d’objets et les services suivent tous la région que vous indiquez.
Deux détails structurels comptent pour cette même question. La file d’attente et le transport en temps réel reposent tous deux sur PostgreSQL : il n’y a ni Redis ni courtier de messages dans le circuit, donc pas de troisième système à localiser. Et le stockage d’objets est compatible S3 plutôt que lié à un fournisseur ; le déploiement de référence fait tourner MinIO dans un conteneur sur un réseau privé, sans point d’entrée propre. Les éléments qui doivent résider quelque part sont la base de données, le stockage d’objets et les deux services Node, et ils résident tous là où vous les placez. La marche à suivre se trouve sur la page d’installation.
Ce que Nessie conserve — et ce qu’il ne conserve volontairement pas
L’identité n’est pas copiée
Avec la connexion UnlikeOtherAI, le fournisseur d’identité gère et stocke l’identité des personnes : facteurs d’authentification, profils, appartenance aux organisations et aux équipes, invitations. Nessie est une partie utilisatrice (relying party), pas un second système d’identité. C’est une décision sur les données autant que sur l’architecture : une identité que Nessie ne stocke jamais est une identité qu’il ne peut ni divulguer, ni perdre, ni omettre de supprimer.
Ce que la table users conserve réellement, c’est l’identifiant utilisateur stable du fournisseur — la clé à laquelle tout le reste se rattache —, l’adresse e-mail, un miroir non faisant foi du nom d’affichage et de l’avatar, et des champs propres au produit (préférences, pronoms, un numéro de version de jeton servant à révoquer les sessions). Le miroir n’existe que pour afficher un nom et une photo sans requête par ligne, et il est resynchronisé à partir des déclarations vérifiées du fournisseur à la connexion, au changement d’équipe et au renouvellement de session. Rien ne fabrique de valeur : une personne que le fournisseur n’a pas nommée porte son adresse e-mail jusqu’à ce qu’il le fasse. Un hachage de mot de passe n’existe que pour le propriétaire initial d’une installation sans aucun fournisseur d’identité.
Il en va de même pour la structure. Une organisation du fournisseur correspond à une organisation Nessie, liée par l’identifiant d’organisation du fournisseur ; une équipe sans lien en amont répond 404 TEAM_NOT_LINKED plutôt que de se rabattre sur une supposition locale, et une lecture en direct de la liste des membres s’adresse au fournisseur d’identité et ne conserve rien.
Deux miroirs n’ont pas encore disparu, et il serait malhonnête de laisser entendre le contraire. Les noms d’organisation et d’équipe sont encore stockés localement à côté des identifiants de liaison, et les lignes d’appartenance locales autorisent encore les requêtes ordinaires entre deux synchronisations. Supprimer les deux est un chantier ouvert et suivi dans le dépôt, pas un travail déjà terminé.
Rien de commercial
Le service de facturation central gère les paiements. Nessie ne stocke aucun client, abonnement, facture, prix, solde de crédits, politique de recharge, consentement de paiement, relevé ni état de résiliation d’un prestataire de paiement, et il ne calcule pas les tarifs. Il lit des valeurs prêtes à afficher et les présente.
Secrets
Un coffre-fort configuré est indispensable pour stocker un secret, quel qu’il soit. Il n’y a volontairement aucun repli sur la base de données et aucun chemin en clair : sans coffre-fort, l’enregistrement, la rotation et la révocation d’un secret renvoient une erreur au lieu de se dégrader vers quelque chose de moins sûr. Les enregistrements propres à Nessie pour un secret ne contiennent ni valeur, ni texte chiffré, ni clé, ni jeton de coffre-fort — seulement une référence opaque et ses métadonnées — et les chemins du coffre-fort sont construits à partir d’identifiants structurels uniquement, jamais à partir du nom d’une organisation, d’une équipe, d’un projet ou d’une personne.
Les identifiants que Nessie doit détenir lui-même pour agir comme client OAuth — identifiants de connecteurs et de boîtes mail, secrets de webhooks, éléments de renouvellement de session, charges utiles de l’exécuteur — sont scellés dans des enveloppes AES-256-GCM liées à un usage précis, sous un trousseau de clés versionné qui constitue une racine distincte du secret de signature des sessions, avec une procédure de rotation documentée.
Il existe aussi une règle concernant les modèles : l’existence d’un secret peut être connue et son usage peut être autorisé, mais le contenu d’un secret ne doit entrer ni dans le contexte du modèle, ni dans les prompts, les arguments d’outils, les résultats d’outils, la mémoire, les embeddings, la recherche, les journaux ou les messages. On peut accorder à un agent la possibilité d’utiliser un secret. On ne peut jamais lui accorder celle d’en révéler un.
Le chiffrement des disques sous-jacents dépend de la machine sur laquelle fonctionne un déploiement. Le dépôt n’établit pas de chiffrement au niveau des volumes pour la base de données et le stockage d’objets, c’est pourquoi cette page ne l’affirme pas.
Isolation des locataires
Nessie est multi-locataire par conception : une seule base de données, dans laquelle chaque ligne appartient à une seule organisation et chaque table enfant porte une colonne organization_id. L’isolation est assurée à deux endroits : la clause de périmètre que porte chaque requête, et de véritables clés étrangères sur cette colonne, ajoutées au moyen de quarante-deux contraintes après qu’un audit interne a constaté que la colonne était présente mais sans contrainte sur des dizaines de tables.
Une suite de conformité maintient cet invariant à la frontière HTTP. Elle met en place un attaquant au maximum de ses privilèges — propriétaire à part entière de sa propre organisation — et vérifie que chaque lecture canonique des ressources d’une autre organisation répond 403, 404 ou vide, et que chaque modification canonique est rejetée sans toucher à la ligne de l’autre organisation. Elle couvre les canaux, les approbations, le journal d’audit, les déclencheurs, les agents et leurs liaisons, les exécutions, les projets, les tâches, les fils de discussion, les connexions, les installations de workflows, les instances MCP, la base de connaissances et les alertes.
Pour être précis sur le mécanisme : il s’agit d’un contrôle au niveau de l’application complété par des clés étrangères, et non de la sécurité au niveau des lignes (RLS) de PostgreSQL. Il n’y a aucune politique RLS et aucun filet de sécurité côté base de données, et la suite de conformité s’exécute sur un stockage en mémoire fidèle plutôt que sur une base réelle : elle prouve donc les clauses de périmètre que le code écrit, et non le SQL qu’un serveur exécute. Le dépôt le dit dans la documentation même de la suite, et cette page aussi.
La piste d’audit
Chaque action importante est enregistrée : qui a agi et en quelle qualité — une personne, un agent, un service —, ce qui a été fait, sur quelle ressource, dans quelle organisation, quel projet, quelle équipe ou quel canal, si l’action a abouti ou a été refusée, pourquoi, ainsi que l’identifiant de la requête, l’adresse et l’agent utilisateur qui l’accompagnaient.
Le journal est conçu en ajout seul et on ne peut pas y écrire de l’extérieur : POST /api/audit-log n’existe pas, et c’est voulu. Les entrées sont chaînées — chacune porte une empreinte SHA-256 de ses propres champs canoniques ainsi que l’empreinte de l’entrée précédente de cette organisation — de sorte qu’une ligne modifiée ou supprimée rompt la chaîne et se détecte. Un propriétaire ou un administrateur de l’organisation peut parcourir cette chaîne à la demande et se voit indiquer où elle s’est rompue en premier, le cas échéant.
Deux réserves honnêtes. La chaîne rend le journal inviolable de façon détectable (tamper-evident), mais pas à l’abri de toute altération : aucune révocation des droits d’écriture au niveau de la base ni aucun stockage à écriture unique ne se trouve derrière, si bien que la garantie porte sur la détection, non sur la prévention. Et les entrées sont conservées indéfiniment par défaut — une durée de conservation configurable avec export avant suppression est conçue, mais pas réalisée. Les entrées ne peuvent en outre contenir ni secrets ni corps de requête complets, et un ensemble fixe de noms de champs de métadonnées sensibles est masqué à l’entrée.
Le registre des coûts
Chaque appel à un modèle est enregistré au nom de l’organisation, ainsi que de l’utilisateur, de l’équipe, du projet, du canal, de l’agent et de l’exécution dont il provient, avec les jetons consommés et, côte à côte, le coût communiqué par le fournisseur et l’estimation propre à Nessie. Une mesure que le fournisseur ne communique pas est stockée comme nulle plutôt que devinée. Les rapports sont consultables par un propriétaire ou un administrateur de l’organisation.
Ce registre est une télémétrie opérationnelle : ce qu’une organisation a dépensé et pour le compte de qui. Ce n’est ni une facture ni une autorité de facturation.
Tiers, lorsque vous utilisez le produit hébergé
Un déploiement hébergé communique avec un petit ensemble fixe de services. Le trafic des modèles et la recherche web ne vont pas directement aux fournisseurs : tous deux passent par une passerelle unique exploitée par UnlikeOtherAI, derrière laquelle se trouvent les fournisseurs de modèles et de recherche. La connexion et la facturation passent par l’authentificateur d’UnlikeOtherAI. Le coffre-fort de secrets est auto-hébergé à côté de l’application. Les liens d’appel vidéo générés par le serveur utilisent par défaut le service public Jitsi.
Presque tout le reste est désactivé tant qu’un opérateur ne l’a pas configuré, et le signale au lieu d’échouer en silence : les comptes Google, Microsoft et Slack connectés ; l’e-mail des agents via Amazon SES, qu’un déploiement exécute dans son propre compte, sans intermédiaire ; les notifications push mobiles et navigateur ; les connecteurs de recherche et de sources de tableaux ; les navigateurs cloud. Deux précisions méritent d’être énoncées, car elles changent la destination des données :
- Les boîtes mail connectées restent chez votre fournisseur. Le courrier est lu en direct chez votre fournisseur, via IMAP et SMTP ou la connexion propre au fournisseur ; Nessie stocke l’identifiant d’accès, scellé, et rien d’autre sur le compte. Une boîte que vous connectez à la boîte de réception Clients fait exception : vous demandez que ses conversations soient conservées avec chaque client, elles sont donc copiées.
- Les appels vocaux dans l’application ne passent pas par Nessie. L’API fournit un identifiant temporaire et le client ouvre lui-même la connexion audio. La dictée et les appels téléphoniques sont différents : leur audio transite par Nessie jusqu’aux fournisseurs de reconnaissance vocale et de modèles qui le traitent.
Un détail sur l’inférence suit le même principe : les en-têtes signés d’identité de l’appelant ne sont envoyés qu’à l’hôte de chat configuré, de sorte qu’orienter les embeddings vers un autre point de terminaison ne lui remet jamais une assertion de délégation concernant la personne dont le texte est transformé en embedding.
Le produit hébergé utilise plusieurs fournisseurs d’inférence et choisit entre eux selon le coût et la qualité. Une organisation pourra choisir dans l’Admin les fournisseurs que ses agents peuvent utiliser : occidentaux uniquement, européens uniquement, chinois uniquement, ou sans préférence — le fournisseur le plus efficace pour chaque tâche. Une instance auto-hébergée choisit les siens.
L’héberger vous-même change tout cela
Chaque tiers mentionné ci-dessus est un choix de configuration sur une instance auto-hébergée. L’inférence peut être dirigée vers n’importe quel point de terminaison compatible OpenAI, y compris un point de terminaison sur votre propre matériel. Les connecteurs sont désactivés tant que vous ne les activez pas. La connexion UnlikeOtherAI est la voie prise en charge, et un déploiement sans aucun fournisseur d’identité fonctionne comme une organisation unique non liée, avec un propriétaire initial.
C’est tout l’intérêt de ce dispositif : le logiciel est le même, et les décisions sur l’endroit où il fonctionne et sur ce qu’il peut atteindre reviennent à celui qui l’exploite. La page d’installation explique comment faire.