Aller au contenu principal

Sécurité et isolation de la mémoire

Authentification toujours active​

MoteurMécanismeGarde-fous vérifiés
Mem0AUTH_DISABLED=false ; clé d'administration X-API-Key, clés d'API des utilisateurs (m0sk_...) ou JWTappel sans clé ou avec une mauvaise clé : 401 ; inscription publique fermée (403), le premier administrateur étant créé par le lanceur avant que l'API écoute ; une clé révoquée est refusée
CogneeREQUIRE_AUTHENTICATION et ENABLE_BACKEND_ACCESS_CONTROL à true ; clé X-Api-Key stockée sous forme d'empreinte saléeappel sans clé : 401 ; le compte amont default_user@example.com n'existe pas ; inscription publique refusée (403) sauf avec la clé de service ; synchronisation cloud refusée (403)

Ces garde-fous sont prouvés par test_mem0_real.py et test_cognee_real.py. Chez Cognee, l'ingestion par URL (allow_url_ingestion) et les requêtes Cypher (allow_cypher) sont désactivées par défaut, et un fichier local hors de la racine des données est refusé (415). Le serveur MCP de Cognee n'a pas d'authentification propre : il n'écoute que sur 127.0.0.1.

Télémétrie coupée et aucune sortie​

Mem0 tourne avec MEM0_TELEMETRY=false (le lanceur refuse une autre valeur). Cognee tourne avec TELEMETRY_DISABLED, RUNTIME__DLTHUB_TELEMETRY=false, HF_HUB_OFFLINE, HF_HUB_DISABLE_TELEMETRY, TRANSFORMERS_OFFLINE et DO_NOT_TRACK. Les tests réels font passer toute sortie HTTP(S) des moteurs par un proxy d'enregistrement qui doit rester inutilisé : il l'est resté.

Secrets​

  • Générés et scellés par le Manager à l'installation : pour Mem0 admin_api_key, jwt_secret, admin_password ; pour Cognee admin_password, service_api_key, jwt_secret, reset_password_secret, verification_secret, api_key_salt.
  • Jamais dans la ligne de commande ni dans les journaux : les tests vérifient qu'aucune valeur n'apparaît dans les arguments ni dans le journal de l'API, et le test fonctionnel masque la clé.
  • Renouvellement : une nouvelle valeur et un redémarrage pour les clés d'API ; changer un secret JWT ferme toutes les sessions ; changer api_key_salt invalide toutes les clés d'API de Cognee sauf celle de service.
  • Dans Navin Enterprise, les clés des instances de plateforme arrivent par le fichier d'environnement sensible (env://EAI_CRED_MEMORY_MEM0_API_KEY, env://EAI_CRED_MEMORY_COGNEE_API_KEY) ; la clé d'un tenant sur une instance partagée est une référence OpenBao (openbao://...). Elles sont résolues côté serveur, jamais renvoyées ni journalisées.

Contexte dérivé et correspondance des portées​

Le contexte d'une opération (tenant, organisation, projet, utilisateur, agent, session, portée, équipe) est dérivé de l'identité authentifiée et du registre des agents, jamais des paramètres envoyés par un agent. Une correspondance contrôlée le traduit en identifiants du moteur :

MoteurIdentifiants utilisés
Mem0user_id, agent_id, run_id et les métadonnées (navin_ns et les champs de la portée)
Cogneele nom du jeu de données

Chaque identifiant porte un préfixe opaque, une HMAC de l'instance, du tenant et du projet, qu'on ne peut pas deviner.

Garantie d'isolation et refus​

GarantieQuand
logicalidentifiants et préfixe imposés par Navin seul : toute instance Mem0 partagée (ses clés ne limitent pas les mémoires), une instance Cognee partagée sans utilisateur propre au tenant
backendséparation imposée par le moteur : builtin (sécurité au niveau des lignes de PostgreSQL), Cognee avec contrôle d'accès et un utilisateur Cognee propre au tenant
dedicated_instanceinstance installée par le Manager pour ce seul tenant et déclarée avec son tenant_id

La politique de l'agent fixe required_isolation. Quand l'instance choisie garantit moins, l'opération est refusée avec memory_isolation_unsatisfied (HTTP 409) : « une instance dédiée installée par le Navin Manager est nécessaire ». Pour une banque, exiger dedicated_instance et installer une instance Mem0 ou Cognee par tenant. La séparation de deux utilisateurs dans une même instance Cognee est prouvée par test_cognee_real.py : l'un ne voit, ne lit ni ne cherche les jeux de l'autre tant qu'une permission de lecture n'est pas donnée.

Autorisations, politiques et audit​

  • OpenFGA : l'appelant doit être l'agent lui-même ou détenir une relation sur lui (can_invoke pour les mémoires et les connaissances, viewer ou editor pour la politique).
  • OPA : chaque écriture passe la décision memory.write, chaque lecture memory.search, avant l'appel au moteur.
  • Rôles : déclarer ou retirer une instance demande platform_admin ; déposer la clé d'un tenant tenant_admin.
  • Audit : chaque opération produit un événement (opération, contexte, moteur, décision, résultat), jamais le contenu des mémoires. Un refus ou une panne du moteur produit aussi un événement deny ou failure.

Mémoires restituées et secrets​

  • Les mémoires restituées sont des données non fiables, jamais des instructions. Leur contenu passe le filtre d'injection de prompt de la passerelle (un élément bloqué est écarté), puis chaque élément est entouré des marqueurs de données non fiables et donné au Context Manager comme segment memory. Les permissions sont contrôlées avant toute restitution au LLM.
  • Les secrets, mots de passe, jetons et clés ne sont jamais mémorisés : la DLP les détecte et l'écriture est refusée avec memory_secret_refused (HTTP 422). Les données personnelles sont refusées quand la politique pose allow_personal_data à false.