Vector Databases

Construire des systèmes RaaS SaaS sécurisés avec la multi-tenancy de Weaviate

La génération augmentée par récupération (RAG) est devenue la référence pour ancrer les grands modèles de langage (LLM) dans des données propriétaires. Cependant, lors du déploiement de solutions RAG pour les plateformes SaaS, un défi critique émerge : l'isolation des données. Dans un environnement multi-tenant, garantir que le Tenant A ne récupère jamais des documents appartenant au Tenant B n'est pas seulement une bonne pratique, c'est une exigence de sécurité.

Weaviate aborde ce défi de manière native grâce à ses capacités de multi-tenancy. Contrairement aux approches traditionnelles où vous pourriez créer des collections séparées ou gérer une logique de filtrage complexe dans votre couche applicative, Weaviate vous permet de créer des « espaces de noms » isolés au sein d'une seule collection. Cet article explore comment implémenter efficacement ces espaces de noms vectoriels isolés.

Comprendre la multi-tenancy de Weaviate

Dans Weaviate, une collection multi-tenant agit comme un conteneur pour plusieurs tenants. Chaque tenant est essentiellement un segment isolé de la collection. L'avantage architectural clé est que chaque tenant possède son propre ensemble de vecteurs et de métadonnées, physiquement séparés au niveau du stockage. Cela signifie :

  • Isolation des performances : Un grand jeu de données pour un tenant ne ralentit pas les requêtes d'un autre.
  • Sécurité : Les requêtes doivent spécifier explicitement un identifiant de tenant, empêchant toute fuite accidentelle de données entre tenants.
  • Évolutivité : Vous pouvez facilement ajouter ou supprimer des tenants sans migrer les données.

Étapes d'implémentation

1. Configuration de la collection

Pour activer la multi-tenancy, vous devez configurer le schéma de la collection avec l'option multiTenancyConfig. Notez que ce paramètre ne peut pas être modifié après la création de la collection.

import weaviate

client = weaviate.WeaviateClient(
    connection_params=weaviate.ConnectionParams(
        from_environment()
    )
)

schema = client.collections

# Créer une collection multi-tenant
collection = schema.get_or_create(
    "KnowledgeBase",
    data=weaviate.classes.data.Config(
        vector_index_config=weaviate.classes.config.VectorIndexConfig(
            vector_index_type="hnsw"
        ),
        multi_tenancy_config=weaviate.classes.config.MultiTenancyConfig(
            enabled=True
        )
    )
)

2. Ingestion de données spécifiques au tenant

Lors de l'ajout de données, vous devez spécifier le tenant_id. Cela garantit que le vecteur est stocké dans l'espace de noms isolé correct.

# Ingerer des données pour le Tenant A
collection.data.insert(
    {
        "content": "Documentation propriétaire du Tenant A...",
        "category": "manuel"
    },
    tenant_id="tenant_a"
)

# Ingerer des données pour le Tenant B
collection.data.insert(
    {
        "content": "Guides d'utilisation privés du Tenant B...",
        "category": "aide"
    },
    tenant_id="tenant_b"
)

3. Exécution de requêtes isolées

Lors de l'exécution de recherches vectorielles, le tenant_id est un paramètre obligatoire. Si vous l'omettez, l'API lèvera une erreur, agissant comme un mécanisme de sécurité.

# Requête strictement dans l'espace de noms du Tenant A
response = collection.query.near_text(
    query="Comment réinitialiser mon mot de passe ?",
    limit=5,
    tenant_id="tenant_a"
)

print(f"Résultats pour le Tenant A : {len(response.objects)}")
# Cette requête ne renverra JAMAIS les données du Tenant B, même si elles sont sémantiquement similaires.

Considérations pratiques pour les applications SaaS

Bien que Weaviate gère l'isolation vectorielle, votre architecture applicative doit gérer correctement le contexte du tenant. Voici les bonnes pratiques :

  1. Intégration de middleware : Utilisez un middleware API pour extraire l'identifiant du tenant du jeton d'authentification (par exemple, JWT) et l'injecter dans le contexte du client Weaviate. N'autorisez jamais une entrée côté client à déterminer l'identifiant du tenant pour des opérations critiques en matière de sécurité.
  2. Gestion des index : Pour les très grands tenants, envisagez de partitionner davantage en utilisant les fonctionnalités de partitioning de Weaviate ou en gérant des stratégies de stockage chaud/froid.
  3. Cohérence des embeddings : Assurez-vous que le même modèle d'embedding est utilisé pour tous les tenants. Bien que les vecteurs soient isolés, des espaces d'embedding incohérents entre les tenants peuvent entraîner une récupération sous-optimale si vous avez besoin d'analyses inter-tenants (ce qui devrait être rare dans les scénarios d'isolation stricte).

Conclusion

La multi-tenancy de Weaviate offre une solution robuste et de premier ordre pour construire des pipelines RAG isolés dans les environnements SaaS. En exploitant les espaces de noms de tenant natifs, les développeurs peuvent atteindre une isolation stricte des données, de meilleures performances de requête et une gestion simplifiée des ressources. À mesure que vous faites évoluer vos applications RAG, l'adoption précoce de ce modèle vous évitera des efforts considérables dans la conception de couches de sécurité personnalisées plus tard.

Que vous construisiez un bot de support client ou un outil de recherche de connaissances d'entreprise, Weaviate garantit que les données de chaque tenant restent sécurisées, rapides et accessibles uniquement à leurs propriétaires.

Share: