Activation du contrôle d’accès granulaire avec le RBAC au niveau des lignes de Milvus
Pourquoi le contrôle d’accès est important dans les systèmes de données modernes
Le contrôle d’accès est l’un des défis les plus urgents de la gestion moderne des données, en particulier pour les entreprises. À mesure que les organisations se développent, notamment dans des environnements comportant plusieurs départements et rôles, une sécurité robuste et un accès fluide sont tous deux essentiels. Examinons deux exemples où le contrôle d’accès est particulièrement important.
Santé : concilier confidentialité et collaboration
Dans le secteur de la santé, les organisations doivent protéger la confidentialité des patients tout en favorisant la collaboration entre les professionnels de santé. Imaginez un médecin qui a besoin d’un accès complet au dossier médical d’un patient afin d’établir un diagnostic et un plan de traitement précis. Cependant, ce médecin ne devrait pas pouvoir accéder aux dossiers des patients qu’il ne traite pas. Pour répondre à ce besoin, un contrôle d’accès granulaire est essentiel, garantissant que seul le personnel médical autorisé peut consulter les données sensibles des patients. Ce niveau de contrôle aide les organisations à se conformer à des réglementations strictes comme HIPAA tout en préservant la confidentialité.
Finance : protéger les données sensibles
Le secteur financier est confronté à des défis similaires en matière de contrôle d’accès. Les banques et les institutions financières gèrent d’énormes volumes de données sensibles — détails de comptes, historiques de transactions, scores de crédit, etc. Ces données sont souvent converties en vecteurs et stockées dans une base de données vectorielle comme Milvus pour la détection de fraude, l’analyse des risques et les expériences client personnalisées. Sans contrôles d’accès appropriés, des données sensibles pourraient être exposées à des parties non autorisées, entraînant d’importantes conséquences financières et juridiques.
Des contrôles granulaires, tels que des autorisations au niveau des lignes, permettent aux institutions de restreindre l’accès à des utilisateurs spécifiques — par exemple, un gestionnaire de clientèle peut accéder uniquement aux données de compte de ses propres clients. Même un accès plus large, requis par les équipes de gestion des risques, peut être soigneusement surveillé et restreint afin de prévenir les abus.
RBAC au niveau des lignes de Milvus : une solution de contrôle d’accès granulaire
Le contrôle d’accès basé sur les rôles (RBAC) est un modèle de sécurité dans lequel l’accès aux ressources est accordé en fonction du rôle d’un utilisateur au sein d’une organisation. Les rôles définissent les autorisations, et les utilisateurs héritent de ces autorisations, garantissant une gestion sécurisée et efficace des droits d’accès.
Milvus est une base de données vectorielle open source à hautes performances conçue pour évoluer à grande échelle. Elle est idéale pour créer des applications d’IA basées sur des modèles, telles que la génération augmentée par récupération (RAG), les moteurs de recherche sémantique, les systèmes de recommandation et les chatbots. Milvus propose une solution RBAC granulaire basée sur un modèle d’autorisation qui utilise l’indexation bitmap pour permettre un contrôle d’accès au niveau des lignes. Cette fonctionnalité vous permet de contrôler l’accès à des ressources et autorisations Milvus spécifiques en fonction des rôles et privilèges des utilisateurs. Actuellement, Milvus RBAC est disponible uniquement en Python et Java.
Milvus RBAC offre plusieurs avantages :
Rapidité et efficacité : Il permet d’interroger rapidement les autorisations dans de grands ensembles de données.
Flexibilité : Il s’adapte à l’évolution des rôles et des responsabilités, garantissant que les autorisations restent à jour.
Principes fondamentaux du RBAC
Rôles et autorisations
Rôle : Représente le rôle d’un utilisateur dans le système, chaque rôle étant associé à un ensemble spécifique d’autorisations.
Autorisation : Spécifie les droits d’accès aux lignes individuelles d’une connexion de données (table) dans Milvus, comme la possibilité de lire, d’écrire ou de supprimer des données spécifiques.
Création d’un index bitmap
Les index bitmap constituent la base de ce mécanisme de contrôle d’accès :
Chaque rôle est associé à un bitmap qui indique les lignes auxquelles il peut accéder.
La longueur du bitmap correspond au nombre de lignes dans la connexion :
Un 1 à une position signifie que le rôle a accès à cette ligne.
Un 0 signifie aucun accès.
Utilisation de l’index bitmap
Accorder des autorisations : Pour donner à un rôle l’accès à une ligne, définissez le bit correspondant dans le bitmap du rôle à 1.
Vérifier les autorisations : Pour vérifier si un rôle peut accéder à une ligne spécifique, vérifiez simplement si le bit correspondant dans le bitmap est 1.
Supposons que nous ayons une connexion (table), Collection A, qui stocke les connaissances de l’entreprise. Chaque ligne représente du contenu identifié par doc_id et sa base de connaissances associée, kb_id.
| ID de ligne | PK | Données | doc_id | kb_id | Rôle |
|---|---|---|---|---|---|
| 1 | 0 | Données A | 1 | 1 | role1 |
| 2 | 1 | Données B | 1 | 1 | role1 |
| 3 | 2 | Données C | 2 | 1 | role1 |
| 4 | 3 | Données D | 2 | 1 | role1 |
| 5 | 4 | Données E | 3 | 2 | role2 |
Les rôles sont définis comme suit :
Rôle 1 : Peut accéder aux lignes 1, 2, 3 et 4 (
kb_id = 1).Rôle 2 : Peut accéder à la ligne 5 (
kb_id = 2).
Opérations de requête
Lorsqu’un utilisateur interroge les données, le bitmap de son rôle est combiné avec les conditions de requête pour filtrer les lignes auxquelles il est autorisé à accéder. Par exemple, si un utilisateur avec le Rôle 1 interroge "toutes les données", son bitmap 11110 renverra les lignes 1 à 4 (Données A, Données B, Données C et Données D).
Mise à jour des autorisations
Pour ajouter ou supprimer l’accès pour un rôle, mettez simplement à jour le bit correspondant dans le bitmap du rôle. Par exemple, définir un bit à 1 accorde l’accès, tandis que le définir à 0 le révoque.
Avantages et considérations
Efficacité : Les opérations bitmap sont rapides et bien adaptées à la gestion des autorisations dans de grands jeux de données.
Faible surcharge de stockage : Les bitmaps consomment un espace de stockage minimal, même pour des jeux de données comportant des millions de lignes.
Flexibilité : Les index bitmap prennent en charge des conditions et combinaisons de requêtes complexes, ce qui les rend très adaptables à divers cas d’utilisation.
Démonstration du RBAC au niveau des lignes de Milvus
Dans cette section, nous montrerons comment Milvus gère l’accès aux différentes bases de connaissances d’une grande entreprise.
Cas d’utilisation : un RAG d’entreprise avec plusieurs bases de connaissances
Dans une grande entreprise, différents départements maintiennent souvent des bases de connaissances distinctes — certaines publiques, d’autres confidentielles — pour leur application RAG alimentée par Milvus. Pour gérer efficacement les autorisations entre ces bases de connaissances, nous mettons en œuvre des contrôles d’accès basés sur les rôles (RBAC) fondés sur des entités ou des documents. Par exemple, un rôle de super administrateur (admin) pourrait superviser l’accès, avec des rôles supplémentaires pour des unités métier spécifiques comme CEO, finance, sales et developer, chacun ayant accès à différents ensembles de données.
Figure : Contrôle d’accès pour différents rôles dans une grande entreprise
Définition des colonnes d’autorisation
Pour gérer l’accès, nous stockons les données d’autorisation dans une colonne de tableau au sein de Milvus. Cette colonne définira quels rôles ont accès à quelles lignes de données. Le field_name de cette colonne d’autorisation est personnalisable, et la taille du tableau peut être ajustée en fonction des besoins de l’utilisateur. Un index BITMAP est ensuite créé pour cette colonne, ce qui rend les vérifications d’autorisations efficaces.
Voici comment cette configuration est effectuée dans le code :
# 1. Set up a Milvus client
client = MilvusClient(
uri=CLUSTER_ENDPOINT
)
# 2. Create a collection
schema = MilvusClient.create_schema(
auto_id=False,
enable_dynamic_field=False,
)
# 3. define schema
schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True)
schema.add_field(field_name="data", datatype=DataType.VARCHAR, max_length=100)
schema.add_field(field_name="vector", datatype=DataType.FLOAT_VECTOR, dim=128)
# 4. add security column
schema.add_field(field_name="security_group", datatype=DataType.ARRAY,
element_type=DataType.VARCHAR, max_capacity=10, max_length=100)
index_params = MilvusClient.prepare_index_params()
index_params.add_index(
field_name="vector",
index_type="IVF_FLAT",
metric_type="L2",
params={"nlist": 1024}
)
# 5. créer un index bitmap pour la colonne security
index_params.add_index(field_name="security_group",
index_type="BITMAP")
# 6. créer la collection
client.create_collection(
collection_name="test_collection",
schema=schema,
index_params=index_params
)
Autorisations d’écriture
Lors de l’insertion de nouvelles données, vous attribuez des autorisations en spécifiant quels rôles peuvent accéder à chaque ligne. Cela peut se faire en écrivant le ou les rôles correspondants dans la colonne security_group.
Voici un exemple de fonctionnement :
data =[]
data.append({
"id": random.randint(0, 100000),
"vector": [ random.uniform(-1, 1) for _ in range(128) ],
"data": "data" + str(random.randint(0,100000)),
# le rôle ceo peut lire
"security_group": ["ceo"]
})
data.append({
"id": random.randint(0, 100000),
"vector": [ random.uniform(-1, 1) for _ in range(128) ],
"data": "data" + str(random.randint(0,100000)),
# le rôle finance peut lire
"security_group": ["finance"]
})
data.append({
"id": random.randint(0, 100000),
"vector": [ random.uniform(-1, 1) for _ in range(128) ],
"data": "data" + str(random.randint(0,100000)),
# sales et developer peuvent tous deux lire
"security_group": ["sales", "finance"]
})
res = client.insert(collection_name="test_collection", data=data)
Autorisation de requête
Lors de l’exécution d’opérations de recherche ou de requête, il est essentiel de limiter les résultats afin de n’afficher que les données auxquelles le rôle spécifique d’un utilisateur a accès. Les données en dehors des rôles autorisés de l’utilisateur seront masquées dans les résultats de la requête. Voici comment procéder :
Interroger des données en fonction des autorisations de rôle
Dans les exemples ci-dessous, nous utilisons la fonction array_contains() pour filtrer les données en fonction des autorisations propres à chaque rôle. Chaque requête récupère uniquement les données que le rôle donné est autorisé à consulter.
res = client.query(
collection_name="test_collection",
# Interroger les données visibles uniquement pour le rôle CEO
filter='array_contains(security_group, "ceo")',
output_fields=["id", "data", "security_group"],
)
print("ceo role read:")
print(res)
res = client.query(
collection_name="test_collection",
# Interroger les données visibles uniquement pour le rôle Sales
filter='array_contains(security_group, "sales")',
output_fields=["id", "data", "security_group"],
)
print("sales role read:")
print(res)
res = client.query(
collection_name="test_collection",
# Interroger les données visibles uniquement pour le rôle Developer
filter='array_contains(security_group, "develop")',
output_fields=["id", "data", "security_group"],
)
print("developer role read:")
print(res)
res = client.query(
collection_name="test_collection",
# Interroger les données visibles pour les rôles Developer ou CEO
filter='array_contains_any(security_group, ["develop", "ceo"])',
output_fields=["id", "data", "security_group"],
)
print("developer or ceo role read:")
print(res)
Voici un exemple de ce à quoi ressemblerait la sortie :
ceo role read:
data: [
"{'security_group': ['ceo'], 'id': 3443, 'data': 'data35077'}",
"{'security_group': ['ceo'], 'id': 12181, 'data': 'data99090'}",
"{'security_group': ['ceo'], 'id': 16551, 'data': 'data74619'}",
"{'security_group': ['ceo'], 'id': 24466, 'data': 'data1373'}", ...
sales role read:
data: [
"{'data': 'data75305', 'security_group': ['sales'], 'id': 9122}",
"{'data': 'data61054', 'security_group': ['sales'], 'id': 20087}",
"{'data': 'data47948', 'security_group': ['sales', 'develop'], 'id': 21726}",
"{'data': 'data8596', 'security_group': ['sales'], 'id': 40090}", ...
developer role read:
data: [
"{'data': 'data1515', 'security_group': ['develop'], 'id': 6429}",
"{'data': 'data47031', 'security_group': ['develop'], 'id': 10953}",
"{'data': 'data47948', 'security_group': ['sales', 'develop'], 'id': 21726}",
"{'data': 'data86894', 'security_group': ['develop'], 'id': 56980}"], ...
developer or ceo role read:
data: [
"{'data': 'data35077', 'security_group': ['ceo'], 'id': 3443}",
"{'data': 'data1515', 'security_group': ['develop'], 'id': 6429}",
"{'data': 'data47031', 'security_group': ['develop'], 'id': 10953}",
"{'data': 'data99090', 'security_group': ['ceo'], 'id': 12181}", ...
Cette approche garantit que chaque rôle voit exactement les données qu’il est autorisé à consulter, tout en masquant les données non autorisées. Vous pouvez également empiler plusieurs rôles dans le tableau security_group, ce qui permet une gestion des autorisations flexible et efficace.
Filtres personnalisés avec accès basé sur les rôles
Dans certains cas, les utilisateurs peuvent avoir besoin d’appliquer des filtres personnalisés lors de l’interrogation des données. Ces filtres peuvent être combinés avec l’accès basé sur les rôles afin d’affiner les recherches. En appliquant le contrôle d’accès basé sur les rôles avec des conditions de filtre personnalisées, nous pouvons garantir que les utilisateurs ne récupèrent que les données qu’ils sont autorisés à voir, à la fois en fonction du rôle et des critères de requête spécifiques.
Par exemple :
res = client.query(
collection_name="test_collection",
# Sales role queries data with the filter "pk in [1, 3, 5]"
filter='pk in [1, 3, 5] && array_contains(security_group, "sales")',
output_fields=["id", "data", "security_group"],
)
res = client.query(
collection_name="test_collection",
# Developer role queries data with the filter "pk > 10"
filter='pk > 10 && array_contains(security_group, "develop")',
output_fields=["id", "data", "security_group"],
)
Dans ces exemples, les requêtes vérifient non seulement les autorisations basées sur les rôles, mais appliquent également des filtres supplémentaires (comme pk in [1, 3, 5] ou pk > 10) afin de restreindre les résultats selon des critères spécifiques. Cette flexibilité permet aux utilisateurs de créer des requêtes très ciblées tout en maintenant un contrôle strict de l’accès aux données.
Mettre à jour les autorisations
Il arrive que vous deviez modifier des autorisations, qu’il s’agisse d’accorder l’accès à un rôle spécifique pour une ligne de données particulière ou de supprimer cet accès. Milvus facilite ce processus grâce à son API upsert, qui vous permet de mettre à jour les autorisations associées à une ligne de données.
Voyons comment vous pouvez utiliser cette API pour modifier les autorisations d’une ligne spécifique.
Exemple : mise à jour des autorisations d’une ligne de données
Pour mettre à jour les autorisations d’une ligne, il vous suffit d’ajuster le champ security_group. Dans cet exemple, nous ajouterons le rôle "sales" à une ligne qui n’était auparavant accessible qu’au rôle "finance".
upsert_row_update = {
"id": 101,
"vector": upsert_vector,
"data": upsert_data,
# update role
"security_group": ["finance", "sales"]
}
res = client.upsert(
collection_name="test_collection",
data=upsert_row_update)
Résultat :
Avant l’upsert, la ligne avec pk = 101 ressemblait à ceci :
pk = 101:
data: [" {'id': 101,
'data': 'data63309',
'vector': [0.38069534, 0.15088418, -0.6266929, -0.6038463, 0.2516377...],
'security_group': ['finance'],"]
après upsert
données: ["{'id': 101,
'data': 'data63309',
'vector': [0.38069534, 0.15088418, -0.6266929, -0.6038463, 0.2516377...],
'security_group': ['finance', 'sales']}"]
En utilisant la colonne de tableau security_group et le filtrage par index bitmap, nous avons établi une base solide pour le contrôle d’accès en lecture au niveau des lignes, ce qui nous permet de gérer efficacement les permissions lors des requêtes. Cette méthode offre de solides performances et un contrôle précis des droits d’accès. Toutefois, elle exige une approche plus manuelle de la part des administrateurs, qui doivent gérer soigneusement les permissions lors de l’insertion ou de la mise à jour des données et garantir une stratégie de permissions bien pensée lors de la création des tables.
Conclusion
La mise en œuvre d’un contrôle d’accès granulaire est un composant essentiel de la gestion moderne des données, en particulier pour les secteurs traitant des informations sensibles comme la santé et la finance. Milvus propose un RBAC (Role-Based Access Control) au niveau des lignes, qui constitue une solution robuste pour gérer l’accès aux données avec précision et efficacité.
Cette approche renforce non seulement la sécurité, mais offre également de la flexibilité pour répondre à l’évolution des besoins métier, en garantissant que les politiques d’accès puissent s’adapter à mesure que les rôles et les responsabilités changent. Grâce à ses outils puissants et à son modèle de permissions flexible, Milvus permet aux organisations de créer des systèmes de données hautement sécurisés et évolutifs qui répondent aux exigences réglementaires tout en offrant un accès fluide aux bonnes personnes.
Pour une gestion des permissions et de l’héritage encore plus dynamique, Zilliz Cloud, le service entièrement géré de Milvus, propose des fonctionnalités de permissions encore plus granulaires. Ces améliorations permettront non seulement d’accroître l’efficacité administrative, mais aussi d’offrir une plus grande flexibilité, facilitant ainsi la réponse à un éventail plus large d’exigences métier. Pour plus d’informations sur le RBAC de Zilliz Cloud, consultez sa documentation.
Lectures complémentaires
Continuer à lire

A Developer's Guide to Exploring Milvus 2.6 Features on Zilliz Cloud
Milvus 2.6 marks a shift from “vector search + glue code” to a more advanced retrieval engine, and it is now Generally Available (GA) on Zilliz Cloud (a managed Milvus service).

Announcing the General Availability of Zilliz Cloud BYOC on Google Cloud Platform
Zilliz Cloud BYOC on GCP offers enterprise vector search with full data sovereignty and seamless integration.

Selecting the Right ETL Tools for Unstructured Data to Prepare for AI
Learn the right ETL tools for unstructured data to power AI. Explore key challenges, tool comparisons, and integrations with Milvus for vector search.



