Servir un RAG (Retrieval Augmented Generation) à plusieurs clients sur une infrastructure partagée — pattern multi-tenant — est l'architecture la plus courante en 2026 pour les SaaS B2B. Mais c'est aussi celle où une mauvaise architecture mène le plus rapidement à un cross-tenant leak : un client voyant les données d'un autre. Voici les trois patterns d'isolation, leurs trade-offs, et le choix raisonné.
Le risque cross-tenant en RAG
Un système RAG type :
- Documents indexés en chunks, embeddings stockés dans une vector DB.
- Requête utilisateur → embedding → top-K documents les plus proches.
- Top-K injecté dans le prompt LLM → réponse.
Le risque : à l'étape 2, un top-K peut contenir des documents d'autres tenants si l'isolation n'est pas appliquée correctement. Conséquence : le LLM répond avec des données qui ne devraient pas être visibles à ce tenant.
Causes typiques :
- Filtrage par metadata oublié dans une nouvelle route.
- Bug de logique dans le filtre.
- Mauvaise utilisation d'un cache partagé.
- Migration ratée entre versions.
Voir aussi RAG en production : sécuriser ingestion, embeddings et rétrieval.
Les trois patterns d'isolation
Pattern 1 — Filtrage par metadata (faible coût, faible isolation)
Tous les vecteurs sont dans le même index, distingués par un champ tenant_id. Les requêtes filtrent.
``python results = vector_db.search( query_embedding, filter={"tenant_id": current_tenant_id}, top_k=5 ) ``
Avantages :
- Coût d'infrastructure le plus bas.
- Cache partagé optimal.
- Setup le plus simple.
Inconvénients :
- Risque résiduel élevé : un bug dans le filtre = leak immédiat.
- Pas de garantie cryptographique : c'est de la logique applicative.
- Pas adapté pour des données très sensibles ou réglementées.
Quand l'utiliser :
- Tenants tous au même niveau de criticité.
- Stack mature, well-tested.
- Données peu sensibles (catalogue produits, knowledge base FAQ, etc.).
- Phase d'apprentissage et de prototype.
Pattern 2 — Index séparés (coût moyen, isolation forte)
Un index distinct par tenant. Les requêtes vont par construction dans le bon index.
``python # Tenant routing au niveau infra, pas dans la requête index_name = f"tenant-{current_tenant_id}-docs" results = vector_db.get_index(index_name).search(query_embedding, top_k=5) ``
Avantages :
- Isolation par construction : un mauvais routing pourrait leaker, mais le code de routing est centralisé et testé.
- Performances de recherche meilleures (indices plus petits).
- Suppression d'un tenant = drop d'un index, instantané.
Inconvénients :
- Coût d'infrastructure plus élevé (chaque index a son overhead).
- Pas adapté à un volume très élevé de tenants (10 000+ peut être problématique).
- Plus de complexité opérationnelle.
Quand l'utiliser :
- SaaS B2B avec 10-1000 tenants moyens à grands.
- Données sensibles (CRM, contracts, knowledge base interne).
- Compliance qui demande isolation forte (HDS, secret bancaire).
C'est mon défaut recommandé pour les SaaS B2B modernes.
Pattern 3 — Infrastructure dédiée (coût élevé, isolation maximale)
Un cluster ou une instance vector DB par tenant. Pas de partage de ressources.
``python # Multi-cluster routing cluster = tenant_to_cluster_map[current_tenant_id] results = cluster.search(query_embedding, top_k=5) ``
Avantages :
- Isolation la plus forte possible (cryptographique au niveau réseau).
- Compliance maximale.
- Performance dédiée par tenant (pas de noisy neighbor).
- Permet personnalisation forte par tenant (modèles d'embedding différents, par exemple).
Inconvénients :
- Coût d'infrastructure très élevé (×N tenants).
- Setup complexe.
- Pas adapté pour un grand nombre de tenants.
Quand l'utiliser :
- Tenants critiques avec exigences réglementaires fortes (santé, défense, secret bancaire).
- Petit nombre de tenants premium (<50).
- Tenants qui paient pour le niveau d'isolation.
Choix selon le profil de criticité
| Profil | Pattern recommandé | |---|---| | MVP, faible volume, données peu sensibles | Pattern 1 (metadata) | | SaaS B2B standard, données business | Pattern 2 (index séparés) | | SaaS healthtech, fintech, enterprise sensible | Pattern 2 ou 3 selon criticité | | Très grand volume tenants (10k+) | Pattern 1 avec audit renforcé OU sharding | | Acteur très exposé (Tier 1 enterprise) | Pattern 3 |
Vector DBs et leur support multi-tenant
Pinecone (Pinecone Serverless)
- Support natif des indices par tenant (Pattern 2).
- Namespaces dans un index pour Pattern 1.
- Bon pour les trois patterns.
Weaviate
- Multi-tenancy natif (depuis v1.20) avec tenant ID, recommandé pour Pattern 1 ou 2.
- Performances optimisées pour Pattern 2.
Qdrant
- Collection dédiée par tenant (Pattern 2) supporté nativement.
- Filtres par metadata (Pattern 1) bien supportés.
Milvus / Zilliz Cloud
- Database par tenant possible.
- Bon pour Pattern 2.
pgvector (PostgreSQL)
- Schémas séparés par tenant pour Pattern 2.
- Filtrage par tenant_id pour Pattern 1.
- Bon choix si vous êtes déjà sous PostgreSQL.
LanceDB
- Tables séparées par tenant (Pattern 2) légères.
- Bon pour les setups simples avec peu d'opérationnel.
Checks de sécurité runtime
Quel que soit le pattern :
1. Tests de cross-tenant isolation systématiques
À chaque release, tests automatiques qui :
- Connectent en tant que tenant A.
- Tentent une requête qui ne devrait retourner que les données du tenant A.
- Vérifient que zéro document du tenant B/C/D apparaît.
```python def test_no_cross_tenant_leak(): # Tenant A asks generic question response_a = rag.query(tenant="A", query="What is in our docs?")
# Verify no tenant B markers in response for marker in TENANT_B_DOCUMENT_MARKERS: assert marker not in response_a.context_documents ```
2. Logs structurés par tenant
Chaque requête loggée avec tenant_id. Si une requête retourne des docs avec un autre tenant_id, alerte critique.
3. Audit régulier
Trimestriel : revue manuelle de log d'échantillon, scan des accès anormaux, vérification des permissions.
L'erreur la plus coûteuse
Migrer du Pattern 1 au Pattern 2 ou 3 après avoir grandi est très coûteux. Refacto de routing, migration de données, downtime, tests. La décision d'architecture en début de projet a 10x plus de poids qu'une décision intermédiaire.
Pour la majorité des SaaS B2B, commencer directement en Pattern 2 est la bonne décision : coût initial maîtrisé, isolation forte par construction, scalabilité acceptable.
Articulation avec la conformité
- ISO 27001 : isolation multi-tenant est implicite dans Annexe A 8.x.
- SOC 2 : auditeurs vérifient les contrôles d'isolation.
- HDS : isolation forte requise (Pattern 2 ou 3).
- DORA : pour les SaaS financiers, attendez-vous à devoir prouver Pattern 2 ou 3.
Investir dans une isolation forte dès le départ = ROI direct sur les certifications futures.