ACL et métadonnées en RAG : éviter les fuites multi-tenant
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.
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ésUn 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 :
- Filtrer avant retrieval : le moteur ne renvoie que des documents autorisés.
- 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.
| Architecture | Idée | Avantage | Dette cachée |
|---|---|---|---|
| Index par tenant | Chaque tenant a son index / collection | Isolation forte, debug simple | Explosion du nombre d'index, ops et coûts |
| Index partagé + tenant_id | Un index, filtre strict tenant_id | Ops plus simple à grande échelle | Risque si un filtre saute (et discipline requise) |
| Hybride | Index partagé + partitions / namespaces + exceptions | Bon compromis, flexible | Complexité : 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 :
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),labelsmé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 :
- Qui est l’utilisateur (principal) ? (ID stable)
- Quels groupes/rôles possède-t-il ? (et qui les maintient)
- 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.
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.
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.
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).
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.
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 :
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).
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é.
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
(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 :
- Tests unitaires sur la construction des filtres (tenant_id toujours présent).
- Tests d’intégration : requêtes identiques sur deux tenants → résultats disjoints.
- Tests de non-régression : rejouer un set de requêtes après chaque changement d’index.
- 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
Articles associés
Guardrails chatbot : sécurité & prompt injection (2026)
Les guardrails d'un chatbot IA sont l'ensemble des protections qui empêchent le modèle de divulguer des données, d'inventer, ou d'exécuter des actions dangereuses. En 2026, le risque numéro 1 est la prompt injection : l'utilisateur tente de reprogrammer le ch
LireRAG pour chatbot : guide 2026 (anti-hallucination)
Le RAG (Retrieval-Augmented Generation) est la technique qui permet à un chatbot IA de répondre à partir de vos documents (contrats, FAQ, procédures) au lieu d'improviser. On récupère d'abord des passages pertinents via une recherche (souvent vectorielle), pu
LireRecherche hybride RAG : BM25 + vecteurs en production
La **recherche hybride** (hybrid search) combine deux “yeux” complémentaires : **BM25** pour attraper les mots exacts (codes, références, noms propres) et la **recherche vectorielle** pour attraper le sens (synonymes, paraphrases). En RAG, on récupère des can
Lire