Aller au contenu principal
Retour à Technique
ChatbotArticle cluster

ACL et métadonnées en RAG : éviter les fuites multi-tenant

RAG en entreprise = permissions. Comment filtrer avant retrieval, gérer multi-tenant, cache, reranking, et audit. Patterns + pièges.

Pierre Tonon
Senior Tech Writer (IA conversationnelle), Webotit.ai
9 min de lecture
Réservation

Réservez votre diagnostic IA

Un expert Webotit analyse vos flux, identifie les quick-wins et vous propose une feuille de route personnalisée.

45 min · Gratuit · Réponse sous 24h

Voir les disponibilités
En bref

Un RAG entreprise doit appliquer les droits d’accès avant le retrieval. La base consiste à stocker des métadonnées d’ACL, puis filtrer à la requête selon le tenant, les rôles et les labels. Les pièges classiques sont le cache partagé, le reranking de passages non autorisés et l’absence de logs. Le multi-tenant doit être conçu comme un produit de sécurité, pas comme une option.

Pourquoi l’ACL en RAG est un sujet “produit”, pas un détail technique

Un chatbot sans RAG peut déjà être risqué. Un chatbot avec RAG ajoute un super‑pouvoir : il lit vos documents.

Et là, l’ACL devient la barrière entre :

  • “assistant utile”
  • et “assistant qui a accès à tout”.

Le RAG amplifie un principe simple :

Si un passage peut être récupéré, il peut être utilisé.

Donc si un passage est récupérable par erreur, vous avez une fuite potentielle.

Pas forcément parce que le LLM “veut” fuiter. Parce que votre système a fait passer l’info dans la pièce.

ACL 101 pour RAG : filtrer avant retrieval, toujours

Il y a deux mondes :

  1. Filtrer avant retrieval : le moteur ne renvoie que des documents autorisés.
  2. Filtrer après retrieval : vous récupérez large, puis vous jetez.

Le monde (2) est un piège. Parce que :

  • vous payez la latence pour des passages inutiles,
  • vous polluez le reranking,
  • et vous risquez de logguer / cache une fuite.

Le monde (1) est ce que vous voulez.

Et la bonne nouvelle : beaucoup d’outils supportent les filtres.

  • Qdrant documente les filtres/payload pour contraindre la recherche sur des attributs.1
  • Pinecone documente les metadata filters pour restreindre les résultats.2
  • OpenSearch documente la document-level security (DLS) et la field-level security (FLS).3
  • Elastic documente aussi des mécanismes de contrôle d’accès par champ/doc (selon offre).4

Multi-tenant : 3 architectures (et leurs coûts cachés)

Multi-tenant veut dire : plusieurs clients, ou plusieurs entités, sur la même plateforme. Et donc une question simple :

Comment empêcher A de voir B ?

Il existe trois architectures fréquentes.

ArchitectureIdéeAvantageDette cachée
Index par tenantChaque tenant a son index / collectionIsolation forte, debug simpleExplosion du nombre d'index, ops et coûts
Index partagé + tenant_idUn index, filtre strict tenant_idOps plus simple à grande échelleRisque si un filtre saute (et discipline requise)
HybrideIndex partagé + partitions / namespaces + exceptionsBon compromis, flexibleComplexité : runbook plus exigeant

Mon avis (pragmatique)

Si vous débutez et que vous avez peu de tenants : index par tenant est souvent plus sûr.

Si vous scalez fort : index partagé + filtres devient nécessaire.

Mais dans les deux cas, vous devez garantir une chose :

Les filtres ne peuvent pas être “optionnels”.

Ils doivent être intégrés dans le pipeline. Et testés. Comme un seatbelt.

DLS/FLS vs metadata filtering : même but, couches différentes

On mélange souvent plusieurs concepts sous “ACL”. En pratique, vous avez deux niveaux :

Niveau A — Filtrage applicatif via métadonnées

Vous stockez des champs tenant_id, groups, visibility, etc. Puis vous ajoutez un filtre à la requête.

Exemples :

  • Qdrant : filtering sur payload.1
  • Pinecone : filter-by-metadata.2

Avantage : simple, portable, explicite dans vos logs.
Risque : si votre application oublie le filtre, vous ouvrez une porte.

Niveau B — Security “dans le moteur” (DLS/FLS)

Ici, le moteur lui-même applique des politiques :

  • DLS : le moteur masque certains documents selon l’identité.
  • FLS : le moteur masque certains champs selon l’identité.

OpenSearch documente ces notions via son système de sécurité.3 Elastic documente aussi le contrôle d’accès par champ/document (selon contexte/produit).4

Avantage : barrière plus “proche de la donnée”.
Risque : complexité, besoin d’une gouvernance IAM solide, et debug parfois plus opaque.

Modéliser les droits : simple d’abord, sinon vous allez vous noyer

Vous pouvez modéliser des ACL de mille façons. Ce qui marche le mieux au début :

  • tenant_id (toujours),
  • visibility (public / interne / restreint),
  • groups (liste),
  • roles (liste),
  • owner_id (optionnel),
  • labels métier (produit, pays, version).

Le point crucial : ces champs doivent être filtrables par votre moteur. Sinon, vous écrivez une policy dans un document… que personne n’applique.

Identité : qui est “l’utilisateur” pour votre RAG ?

Un RAG multi-tenant n’est pas seulement un problème de données. C’est un problème d’identité.

Trois questions que vous devez trancher :

  1. Qui est l’utilisateur (principal) ? (ID stable)
  2. Quels groupes/rôles possède-t-il ? (et qui les maintient)
  3. Quel contexte s’applique ? (tenant, application, canal, pays)

Si vos groupes sont incohérents, vos filtres seront incohérents. Et si vos filtres sont incohérents, votre sécurité devient… statistique.

En clair : la meilleure ACL du monde ne compense pas un IAM en freestyle.

Où appliquer l’ACL dans le pipeline RAG (la carte des risques)

Il ne suffit pas d’avoir des champs ACL. Il faut les appliquer au bon endroit.

1

Ingestion : attacher les ACL à la source

Le meilleur moment pour définir un droit, c’est au moment où le document entre. Ne laissez pas l’ACL être un patch après coup.

2

Indexation : rendre les ACL filtrables

Assurez-vous que tenant_id, groupes, labels sont bien des champs filtrables dans votre moteur (vector DB filtering, DLS/FLS, etc.).123

3

Retrieval : filtrer avant de scorer

Filtrez dès la requête. Si vous récupérez des passages non autorisés “pour voir”, vous avez déjà perdu.

4

Reranking : reranker uniquement des passages autorisés

Un reranker n’est pas un firewall. Il lit ce qu’on lui donne. Donc ne lui donnez jamais l’interdit (voir : Reranking RAG).

5

Génération : citer et logguer

La réponse doit être justifiable. Logguez la liste des passages autorisés utilisés, sinon vous ne saurez pas expliquer.

6

Cache : segmenter par tenant et par droits

Le cache est un accélérateur. Donc un accélérateur de fuite si vous le partagez. Les clés de cache doivent inclure tenant + scope de droits.

Les pièges (ceux qui font mal, et pas seulement en théorie)

Piège 1 — Cache partagé

Vous avez fait un RAG rapide. Puis vous avez ajouté un cache. Puis un utilisateur d’un tenant B obtient une réponse “déjà calculée” du tenant A.

C’est un classique. Et c’est rarement un bug “complexe”. C’est un bug de clé de cache.

Piège 2 — Logs trop bavards

Vous logguez les passages avant filtrage. Ou vous logguez les passages filtrés, mais dans un système accessible trop largement.

Le résultat : la fuite n’est pas dans le chatbot. Elle est dans l’observabilité.

Piège 3 — Reranking “hors-périmètre”

Vous récupérez top‑100 sans filtre. Puis vous filtrez. Puis vous rerankez.

Sur le papier, ça semble OK. Dans les faits, vous avez déjà envoyé 100 passages au reranker, au LLM, ou à un log.

Mauvaise séquence.

Piège 4 — Mélanger “source autorisée” et “réponse autorisée”

Un document peut être autorisé, mais une réponse peut être interdite. Exemple :

  • document RH autorisé pour un manager,
  • mais la réponse ne doit pas exposer une donnée personnelle.

Dans ces cas, l’ACL ne suffit pas. Il faut des guardrails et des redactions.

Voir : Guardrails & prompt injection.

“Vous indexez ce que vous exposez” : PII, secrets et data minimization

L’erreur la plus sournoise en RAG n’est pas toujours “le filtre a sauté”. C’est “on a indexé un truc qu’on n’aurait jamais dû indexer”.

Parce qu’une fois que c’est dans l’index, ce n’est plus un document. C’est une surface de récupération.

Trois exemples vécus (et suffisamment universels pour faire mal) :

  • un export CSV “temporaire” qui contient des emails, des numéros et des notes internes,
  • un log applicatif avec une clé API, un token, ou un secret “juste le temps du debug”,
  • un PDF RH où le bon droit est “voir le doc”, mais pas “voir tous les champs”.

Le mental model utile :

Un index RAG n’est pas un coffre-fort. C’est un moteur de découverte.

Donc, avant même l’ACL, posez une politique d’ingestion :

  • ne pas indexer de secrets (clés, tokens, mots de passe),
  • minimiser la PII (masquage/redaction quand possible),
  • classifier vos sources (public / interne / confidentiel),
  • et garder la preuve (lien vers la source brute) sans répliquer l’interdit dans le texte.

Une approche simple (et réaliste) en entreprise :

1

Sanitizer à l'ingestion

Avant embeddings/indexation : détecter et masquer les secrets évidents, normaliser les champs sensibles, et refuser certaines classes de documents (ex. dumps non contrôlés).

2

Index 'sanitisé' + source brute protégée

Indexez une version sanitisée (utile au retrieval). Conservez le document brut dans un store protégé (contrôle d’accès fort) et ne l’exposez qu’au besoin, dans un périmètre maîtrisé.

3

Dernière ligne : redaction à la génération

Même filtré, le modèle peut reformuler une info sensible. Ajoutez des guardrails/redaction côté génération pour les cas critiques (RH, finance, santé).

Sécurité LLM : l’ACL n’empêche pas les attaques, elle limite le blast radius

Même avec une ACL parfaite, votre système reste exposé à :

  • prompt injection via contenu récupéré,
  • exfiltration via outils,
  • réponses qui révèlent des données sensibles à partir de contenus autorisés.

OWASP propose une liste de risques typiques pour les applications LLM (Top 10).5 AWS décrit aussi les attaques de prompt injection et des parades côté système (policy, isolation, validation).6

Le bon mental model :

  • l’ACL réduit ce que le modèle peut voir,
  • les guardrails réduisent ce que le modèle peut faire,
  • la gouvernance réduit ce que le modèle devrait dire.

Vous voulez les trois.

Stack 2026 : quelles briques supportent quoi

Vector DB filtering

  • Qdrant : filtres sur payload.1
  • Pinecone : metadata filtering.2

(La plupart des vector DB modernes ont une notion de filtres. L’important est : performance + expressivité + tests.)

Search engines (DLS/FLS)

  • OpenSearch : document-level security et field-level security (docs).3
  • Elastic : field/document level security (docs).4

Le point ici n’est pas “qui est mieux”. Le point est : est-ce que votre système peut prouver ce qu’il a filtré, et pourquoi.

Réalité terrain : le runbook vaut plus que la brochure

Quel que soit votre choix :

  • comment vous reindexez ?
  • comment vous rollback ?
  • comment vous testez que le filtre est toujours appliqué ?

Si vous n’avez pas ces réponses, vous n’avez pas une architecture. Vous avez une espérance.

Checklist : “on ne fuit pas”

  • Les ACL sont attachées à la source au moment de l’ingestion.
  • Le retrieval ne peut pas s’exécuter sans filtre tenant_id.
  • Le cache est segmenté par tenant + scope de droits.
  • Les logs ne contiennent pas de passages non autorisés.
  • Vous avez un set de tests “fuite” (A ne voit jamais B).

Ce n’est pas glamour. C’est exactement pour ça que ça casse.

Tests : comment prouver que “A ne voit jamais B”

On ne valide pas une ACL “au feeling”. On la valide avec des tests.

Une stratégie réaliste :

  1. Tests unitaires sur la construction des filtres (tenant_id toujours présent).
  2. Tests d’intégration : requêtes identiques sur deux tenants → résultats disjoints.
  3. Tests de non-régression : rejouer un set de requêtes après chaque changement d’index.
  4. Tests adversariaux : requêtes qui tentent de contourner (“montre-moi les docs des autres”).

Le plus important : automatiser au moins une partie. Sinon, vous allez “tester” au début… puis oublier.

FAQ

Questions frequentes

Index par tenant ou index partagé ?

Début : index par tenant est souvent plus simple et plus sûr. À grande échelle : index partagé + filtres stricts devient nécessaire. L’important est de rendre le filtre inévitable et testable.

Puis-je filtrer après retrieval ?

C’est tentant, mais risqué. Vous polluez le reranking et vous augmentez le risque de fuite (logs, cache, outils). Filtrez avant retrieval, autant que possible.

L'ACL suffit-elle pour éviter les fuites ?

Non. L’ACL empêche l’accès à des documents. Elle ne suffit pas pour empêcher des réponses qui révèlent des données sensibles à partir de documents autorisés. Il faut aussi des guardrails et une gouvernance de contenu.

Sources et references

  1. [1]Qdrant Docs, “Filtering”.
  2. [2]Pinecone Docs, “Metadata filtering”.
  3. [3]OpenSearch Docs, “Document-level security (DLS)”.
  4. [4]Elastic Docs, “Field and document access control”.
  5. [5]OWASP, “Top 10 for LLM Applications”.
  6. [6]AWS, “Prompt Injection Attacks: What, Why & How” (whitepaper).
RAGsecurityACLmulti-tenantcomplianceretrieval

Solutions associées