Aller au contenu principal

Utiliser RBAC avec ABAC

Le contrôle d'accès basé sur les rôles (RBAC) définit l'identité active pour une session. Le contrôle d’accès basé sur les attributs (ABAC) dans Unity Catalog applique des filtres de ligne et des masques de colonne à cette identité :

  • RBAC : un utilisateur assume un rôle pour agir avec les autorisations de ce rôle au lieu des siennes. Utilisez des rôles pour séparer l'accès entre les projets ou les niveaux de sensibilité.
  • Stratégies de filtre de ligne et de masque de colonne ABAC : filtrez les lignes ou masquez les valeurs de colonne pour les tables auxquelles l’identité active peut déjà accéder. Les stratégies sont définies sur des objets sécurisables, tels que des catalogues ou des schémas, et utilisent des balises gouvernées pour identifier les tables et les colonnes correspondantes. Consultez Concepts de base du contrôle d’accès basé sur les attributs (ABAC).

Comportement des fonctions d'identité lors de l'attribution d'un rôle​

Les fonctions SQL liées à l'identité de Unity Catalog se résolvent par rapport à l'identité active de la session, et non à l'utilisateur authentifiant sous-jacent. Lorsqu'un utilisateur assume un rôle, l'identité de session active devient le rôle :

Fonction

Lorsque l'utilisateur agit en tant que son identité d'utilisateur

Lorsqu'un utilisateur assume un rôle

session_user()

Retourne le nom d'utilisateur de l'utilisateur

Renvoie le nom du rôle assumé.

is_member(group)

Renvoie true si l'utilisateur est un membre direct ou indirect d'un groupe local au workspace ou d'un groupe de compte assigné au workspace

Renvoie true uniquement si le rôle assumé est lui-même membre de group. Renvoie false pour les groupes dont l'utilisateur sous-jacent est membre, mais pas le rôle assumé.

is_account_group_member(group)

Renvoie true si l'utilisateur est un membre direct ou indirect du groupe de comptes

Renvoie true en fonction des appartenances directes et indirectes du rôle supposé au groupe de comptes, y compris les groupes non affectés au workspace.

Fonction

Lorsque l'utilisateur agit en tant que son identité d'utilisateur

Lorsqu'un utilisateur assume un rôle

session_user()

Retourne le nom d'utilisateur de l'utilisateur

Renvoie le nom du rôle assumé.

is_member(group)

Renvoie true si l'utilisateur est un membre direct ou indirect d'un groupe local au workspace ou d'un groupe de compte assigné au workspace

Renvoie true uniquement si le rôle assumé est lui-même membre de group. Renvoie false pour les groupes dont l'utilisateur sous-jacent est membre, mais pas le rôle assumé.

is_account_group_member(group)

Renvoie true si l'utilisateur est un membre direct ou indirect du groupe de comptes

Renvoie true en fonction des appartenances directes et indirectes du rôle supposé au groupe de comptes, y compris les groupes non affectés au workspace.

Le rôle assumé est l’identité active pour l’évaluation des politiques ABAC, la résolution des octrois de Unity Catalog et l’attribution d’audit. Assumer un rôle peut donc modifier le comportement des politiques et des vues existantes construites autour de l’identité par utilisateur.

remarque

Un rôle n’est pas membre de lui-même. Lorsqu’un utilisateur assume le rôle G, session_user() retourne G, mais is_member('G') et is_account_group_member('G') retournent false. Pour correspondre au rôle assumé dans une stratégie, effectuez une comparaison avec session_user() plutôt que de tester l’appartenance avec is_member ou is_account_group_member.

La référence SQL recommande session_user() au lieu de l’alias obsolète current_user(). Utilisez is_account_group_member() pour tester l’appartenance à un groupe de compte. Voir fonction session_user et fonction is_member.

Écueil courant : vues de sécurité au niveau des lignes basées sur session_user()​

Un schéma courant à travers ABAC et les filtres de ligne au niveau de la table consiste à filtrer les lignes en effectuant une jointure avec une table de provisionnement (également appelée table de mappage ou liste de contrôle d'accès) indexée sur le nom d'utilisateur renvoyé par session_user(). Par exemple :

SQL
CREATE OR REPLACE FUNCTION facility_filter(facility_id STRING)
RETURN EXISTS (
SELECT 1
FROM governance.user_facility_provisioning p
WHERE p.user = session_user()
AND p.facility_id = facility_filter.facility_id
);

La référence facility_filter.facility_id identifie le parameter de fonction. Sans le nom de la fonction, facility_id correspond à la colonne de la table de provisionnement à la place. Voir Résolution des noms.

Lorsque le même utilisateur assume un rôle, session_user() ne renvoie plus son nom d’utilisateur. Il renvoie le nom du rôle. Comme le rôle ne se trouve pas dans la table de provisionnement, le filtre ne renvoie aucune ligne et l’utilisateur semble perdre l’accès aux données qui lui avaient été accordées.

Ajouter le rôle à la table de provisionnement​

Traitez le rôle comme un autre principal dans vos données de provisionnement : insérez une ligne par rôle avec les installations (ou autres attributs) que le rôle devrait voir. Le filtre correspond alors à si l'identité active est l'utilisateur ou le rôle assumé.

Modèles d'utilisation combinée​

Les exemples suivants combinent le contrôle d’accès basé sur les rôles (RBAC) avec des filtres de lignes ABAC et des masques de colonnes.

Exigences​

Avant d’utiliser les exemples, effectuez les étapes suivantes :

  • Utilisez un compute compatible ABAC.
  • Créez les tags gouvernés et accordez les autorisations nécessaires pour appliquer des tags, créer des fonctions définies par l’utilisateur (UDF) et gérer des politiques. Voir Séparation des tâches et des autorisations.
  • Accordez aux identités de querying USE CATALOG, USE SCHEMA et SELECT les données pertinentes. Les filtres de ligne et les masques de colonne n'accordent pas ces privilèges. Voir Privilèges d'utilisation.
  • Créez chaque UDF d'exemple dans un schéma pour lequel vous disposez des autorisations nécessaires et utilisez ce schéma comme schéma actuel lors de la création de sa politique, ou qualifiez complètement le nom de la fonction. Pour une procédure pas à pas complète, consultez Didacticiel : Configurer ABAC avec SQL.

Filtres de lignes par projet basés sur le rôle assumé​

Une organisation de recherche clinique mène plusieurs essais simultanés, chacun avec son propre rôle d'accès. Un filtre de lignes limite chaque rôle aux données de son essai. Le même schéma s'applique aux autres projets qui nécessitent un accès séparé aux données. Marquez la colonne project_id de chaque table avec la clé de balise gouvernée project. Les valeurs de colonne identifient le projet pour chaque ligne.

Installer :

  • Les tables sous clinical_trials.* ont une colonne project_id taguée avec la clé de tag gouverné project.
  • Chaque projet a un rôle d'accès correspondant nommé role-<project> (par exemple, role-alpha, role-beta).
  • Les utilisateurs disposent de l'autorisation Assume uniquement sur les rôles des projets sur lesquels ils travaillent.

Filtre de ligne UDF :

SQL
CREATE FUNCTION project_match(project_id STRING) RETURNS BOOLEAN
DETERMINISTIC
RETURN session_user() = CONCAT('role-', project_id);

Politique :

SQL
CREATE POLICY per_project_row_filter
ON CATALOG clinical_trials
ROW FILTER project_match
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag('project') AS project
USING COLUMNS (project);

Cette UDF compare l'identité active à la valeur de la colonne project_id de chaque ligne. MATCH COLUMNS utilise la balise gouvernée pour trouver cette colonne. Les clauses TO et EXCEPT sélectionnent les principaux auxquels une règle s'applique. Elles ne comparent pas les valeurs de ligne. Comme l'explique le guide de ciblage des principaux, préférez TO / EXCEPT pour une délimitation simple des principaux et réservez les fonctions d'identité à l'intérieur d'une UDF pour des cas comme celui-ci, où une seule règle dépend à la fois de l'identité active et du contenu de la ligne.

Une seule règle couvre tous les projets : USING COLUMNS (project) transmet la valeur de chaque ligne de la colonne correspondante dans l'UDF. L'alias project nomme la colonne correspondante, pas une valeur de balise. Pour un exemple utilisant une table de recherche pour déterminer l'accès aux lignes, consultez la section Utilisation de tables de mappage pour le contrôle d'accès dynamique.

Comportement :

  • Un utilisateur agissant en tant qu'identité utilisateur ne voit aucune ligne dans les tables clinical_trials. session_user() renvoie son nom d'utilisateur. Choisissez des noms de rôle qui ne peuvent pas correspondre au nom d'utilisateur d'un utilisateur ou à l'ID d'application d'un Service Principal Databricks.
  • Un utilisateur assumant role-alpha ne voit que les lignes où project_id est égal à alpha. Après être passé à role-beta, exécutez à nouveau la query pour voir les lignes où project_id est égal à beta.

Masquer les informations personnelles identifiables à moins qu'un rôle ne soit assumé​

Dans cet exemple, les informations personnellement identifiables (PII), comme les numéros de sécurité sociale et les adresses e-mail, apparaissent masquées par default. Pour voir les valeurs brutes, un utilisateur doit assumer role-pii-cleared. Les événements d’audit identifient le rôle utilisé pour accéder aux données et l’identité qui a initié l’événement.

Installer :

  • Marquez les colonnes sensibles avec la clé de tag gouverné pii (valeurs autorisées telles que ssn, email, phone).
  • Créez le groupe role-pii-cleared sans membres. Accorder l'autorisation Assume sur ce groupe.
    • Les utilisateurs autorisés à voir les PII brutes peuvent assumer ce rôle d'accès pour voir les données non masquées. N'ajoutez pas de membres au groupe, car la clause EXCEPT de la politique leur permettrait de voir les données non masquées sans assumer le rôle.

Créez l’UDF de masque de colonne à l’aide de ce SQL :

SQL
CREATE FUNCTION mask_pii(val STRING) RETURNS STRING
DETERMINISTIC
RETURN '***';

Politique :

SQL
CREATE POLICY pii_default_mask
ON CATALOG customer_data
COLUMN MASK mask_pii
TO `account users`
EXCEPT `role-pii-cleared`
FOR TABLES
MATCH COLUMNS has_tag('pii') AS pii_col
ON COLUMN pii_col;

La clause EXCEPT exclut role-pii-cleared entièrement de la politique, de sorte que l'UDF n'est jamais appelée lorsque ce rôle est l'identité active. Consultez Préférer À/SAUF pour le ciblage de principal pour obtenir des conseils généraux sur le ciblage de principal via TO / EXCEPT.

Comportement :

  • Un utilisateur agissant en tant que son identité utilisateur voit *** dans chaque colonne PII. Il s'agit de l'état default pour tout le monde, y compris les utilisateurs disposant de l'autorisation Assume sur role-pii-cleared.
  • Une fois role-pii-cleared assumé, la politique ne s'applique plus à la session, et le même utilisateur voit les valeurs brutes.
  • Les événements d'audit pour ces query identifient le rôle autorisant dans identity_metadata.run_as et son nom dans identity_metadata.run_as_display_name. Voir Attribution d'audit.

Politiques de niveau de sensibilité qui varient selon le rôle assumé​

Les données sont classées par niveaux de sensibilité (internal, confidential, restricted). Chaque niveau a un rôle d'accès correspondant, restricted impliquant également l'accès à confidential et internal. Un seul filtre de ligne UDF contrôle la visibilité des lignes en comparant le niveau de chaque ligne au rôle assumé par l'utilisateur.

Installer :

  • Les tables ont une colonne sensitivity_level balisée avec la clé de balise régie sensitivity (valeurs autorisées : internal, confidential, restricted).
  • Trois rôles d'accès : role-sens-internal, role-sens-confidential, role-sens-restricted.

Filtre de ligne UDF :

SQL
CREATE FUNCTION sensitivity_allowed(row_sensitivity STRING) RETURNS BOOLEAN
DETERMINISTIC
RETURN CASE
WHEN session_user() = 'role-sens-restricted' THEN TRUE
WHEN session_user() = 'role-sens-confidential' THEN row_sensitivity IN ('internal', 'confidential')
WHEN session_user() = 'role-sens-internal' THEN row_sensitivity = 'internal'
ELSE FALSE
END;

Politique :

SQL
CREATE POLICY sensitivity_filter
ON CATALOG corp_data
ROW FILTER sensitivity_allowed
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag('sensitivity') AS sens
USING COLUMNS (sens);

Comme un rôle n'est pas membre de lui-même, cette UDF compare session_user() à chaque nom de rôle au lieu de tester l'appartenance avec is_account_group_member(). Voir la remarque dans Comportement des fonctions d'identité lors de l'assomption d'un rôle pour savoir pourquoi les tests d'appartenance ne correspondent pas au rôle assumé. Voir Considérations sur les performances des politiques de filtre de ligne et de masque de colonne pour les caractéristiques de performance des fonctions d'identité dans les UDF.

Comportement :

  • Un utilisateur qui agit sous son identité utilisateur ne voit aucune ligne. La branch ELSE FALSE correspond à tout ce qui n’est pas l’un des trois rôles.
  • En supposant que role-sens-internal ne révèle que internal lignes.
  • En supposant role-sens-confidential, cela révèle internal et confidential lignes.
  • En supposant que role-sens-restricted révèle toutes les lignes.

Les utilisateurs utilisent le niveau dont ils ont besoin pour la session. Le filtre s’applique aux tables avec la colonne balisée et retourne les lignes autorisées par ce rôle.

Attribution de l’audit​

Dans la table de log d’audit, identity_metadata.run_by identifie qui a initié un événement et identity_metadata.run_as identifie l’identité utilisée pour l’autorisation. Les champs run_by_display_name et run_as_display_name correspondants contiennent des noms lisibles par l’homme. Pour les queries effectuées de manière interactive tout en assumant un rôle, ceux-ci identifient respectivement l’utilisateur et le rôle. Les workloads de job peuvent avoir un initiateur différent. Consultez Définir l’exécution en tant que groupe.

Utilisez les événements d'audit pour examiner l'activité sous un rôle. Pour inspecter les politiques qui s'appliquent à une table, utilisez SHOW EFFECTIVE POLICIES comme décrit dans Planifier l'évaluation des politiques dynamiques. Pour l'accès à l'audit, le schéma et la disponibilité, consultez Vérifier l'attribution de l'audit.

Ressources supplémentaires​