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 attributs (ABAC) dans Unity Catalog applique des filtres de lignes et des masques de colonnes à cette identité :

  • RBAC : Un utilisateur endosse un rôle pour agir avec les permissions de ce rôle au lieu des siennes. Utilisez des rôles pour séparer les accès selon les projets ou les paliers de sensibilité.
  • Politiques de filtre de lignes ABAC et de masquage de colonnes : Filtrez les lignes ou masquez les valeurs de colonne pour les tables auxquelles l’identité active peut déjà accéder. Les politiques sont définies sur des objets sécurisables, tels que des catalogues ou des schémas, et utilisent balises régies pour identifier les tables et colonnes correspondantes. Consultez les concepts fondamentaux du contrôle d’accès basé sur les attributs (ABAC).

Comportement des fonctions d’identité lorsqu’elles assument un rôle

Les fonctions SQL du catalogue Unity liées à l’identité sont évaluées en fonction de l’identité active de la session, et non de l’utilisateur authentifié sous-jacent. Lorsqu’un utilisateur assume un rôle, l’identité de session active devient le rôle :

Function Lorsque l’utilisateur agit sous sa propre identité utilisateur Quand l’utilisateur assume un rôle
session_user() Retourne le nom d’utilisateur de l’utilisateur Renvoie le nom du rôle endossé
is_member(group) Retour true si l’utilisateur est un membre direct ou indirect d’un groupe local de l’espace de travail ou d’un groupe de comptes assigné à l’espace de travail Retourne true uniquement si le rôle assumé est lui-même membre de group. Retourne false pour les groupes auxquels l’utilisateur sous-jacent appartient, mais pas le rôle assumé.
is_account_group_member(group) Retour true si l’utilisateur est un membre direct ou indirect du groupe de comptes Renvoie true basé sur l’appartenance directe et indirecte du rôle assumé aux groupes de compte, y compris les groupes non assignés à l’espace de travail.

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

Note

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

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

Piège courant : vues de sécurité au niveau des lignes reposant sur session_user()

Un modèle courant commun à l’ABAC et aux filtres de lignes 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 retourné par session_user(). Par exemple:

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 facility_filter.facility_id référence identifie le paramètre de fonction. Sans le nom de la fonction, facility_id se résout plutôt dans la colonne de la table de provisionnement. Voir résolution de noms.

Lorsque le même utilisateur assume un rôle, session_user() ne retourne plus son nom d’utilisateur. Elle renvoie le nom du rôle. Comme le rôle n’apparaît pas dans la table de provisionnement, le filtre ne retourne aucune ligne et l’utilisateur semble perdre l’accès aux données qui lui ont été attribuées.

Ajouter le rôle à la table d’approvisionnement

Traitez le rôle comme un autre principal dans vos données d’approvisionnement : insérez une ligne par rôle avec les installations (ou d’autres attributs) que le rôle doit voir. Le filtre vérifie ensuite si l’identité active est l’utilisateur ou le rôle endossé.

Modèles d’utilisation combinée

Les exemples suivants combinent RBAC avec des filtres de lignes ABAC et des masques de colonnes.

Requirements

Avant d’utiliser les exemples, suivez ces étapes :

  • Utilisez un compute qui prend en charge ABAC.
  • Créer les balises gouvernées et accorder les autorisations nécessaires pour appliquer des tags, créer des fonctions définies par l’utilisateur (UDF) et gérer les politiques. Voir Séparation des tâches et des autorisations.
  • Accordez l’accès aux identités de requête USE CATALOG, USE SCHEMA et SELECT sur les données pertinentes. Les filtres à lignes et les masques de colonne n’accordent pas ces privilèges. Consultez les privilèges d’utilisation.
  • Créez chaque UDF d’exemple dans un schéma où vous avez la permission, et utilisez ce schéma comme schéma courant lors de la création de la politique associée, ou qualifiez pleinement le nom de la fonction. Pour un guide détaillé, voir le tutoriel : Configurez 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 ayant son propre rôle d’autorisation. Un filtre de ligne limite chaque rôle aux données de sa version d’essai. Le même schéma s’applique à d’autres projets nécessitant un accès séparé aux données. Marquez la colonne project_id de chaque table avec la clé project de balise gérée. Les valeurs de colonne identifient le projet pour chaque ligne.

Configuration :

  • Tables sous clinical_trials.* avoir un project_id colonne étiquetée avec le étiquette gouvernée clé project.
  • Chaque projet a un rôle d’accès correspondant nommé role-<project> (par exemple, role-alpha, role-beta).
  • Les utilisateurs n’ont la permission « Assume » que sur les rôles des projets sur lesquels ils travaillent.

UDF de filtrage des lignes :

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

Politique:

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 avec la valeur de la colonne project_id de chaque ligne. MATCH COLUMNS utilise la balise governed pour trouver cette colonne. Les clauses TO et EXCEPT sélectionnent les identités auxquelles une politique s’applique. Ils ne comparent pas les valeurs des lignes. Comme l’explique le guide sur le ciblage du principal, préférez TO / EXCEPT pour un ciblage simple du principal et réservez les fonctions d’identité dans une UDF aux 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 politique couvre tous les projets : USING COLUMNS (project) transmet la valeur de chaque ligne de la colonne appariée à la UDF. L’alias project nomme la colonne correspondante, pas une valeur de tag. Pour un exemple utilisant une table de recherche pour déterminer l’accès aux lignes, voir Utiliser les tables de correspondance pour le contrôle d’accès dynamique.

Comportement:

  • Un utilisateur utilisant son identité utilisateur ne voit aucune ligne dans les tables clinical_trials. session_user() renvoie leur 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 principal de service.
  • Un utilisateur qui suppose que role-alpha ne voit que les lignes où project_id est égal à alpha. Après avoir changé à role-beta, lance à nouveau la requête pour voir des lignes où project_id est égal à beta.

Masquez les informations personnelles identifiables à moins qu’un rôle ne soit attribué

Dans cet exemple, des informations personnelles identifiables (PII), telles que les numéros de sécurité sociale et les adresses e-mail, apparaissent masquées par défaut. Pour voir les valeurs brutes, un utilisateur doit sélectionner 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.

Configuration :

  • Balisez les colonnes sensibles avec la clé pii (valeurs autorisées telles que ssn, email, phone).
  • Créez un role-pii-cleared groupe sans membres. Accordez l’autorisation Assume sur ce groupe.
    • Les utilisateurs autorisés à consulter les informations personnelles brutes peuvent utiliser ce rôle d’accès pour consulter les données non masquées. N’ajoutez pas de membres au groupe, car la clause EXCEPT de la politique leur permettrait de voir des données non masquées sans se voir attribuer le rôle.

Créez le masque de colonne UDF, en utilisant ce SQL :

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

Politique:

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 entièrement role-pii-cleared de la stratégie, de sorte que la fonction UDF n’est jamais appelée lorsque ce rôle est l’identité active. Consultez Préférer TO/EXCEPT pour le ciblage principal pour obtenir des conseils généraux sur le ciblage principal via TO / EXCEPT.

Comportement:

  • Un utilisateur agissant avec sa propre identité utilisateur voit *** dans chaque colonne de données personnelles identifiables. C’est l’état par défaut pour tout le monde, y compris pour les utilisateurs qui ont l’autorisation Assume sur role-pii-cleared.
  • Après avoir pris en compte role-pii-cleared, la stratégie ne s’applique plus à la session, et le même utilisateur voit les valeurs brutes.
  • Les événements d’audit pour ces requêtes identifient le rôle ayant autorisé dans identity_metadata.run_as et son nom dans identity_metadata.run_as_display_name. Voir l’attribution de l’audit.

Stratégies de niveau de sensibilité qui varient selon le rôle assumé

Les données sont classées en niveaux de confidentialité (internal, confidential, restricted). Chaque niveau a un rôle d’accès correspondant, ce qui restricted implique l’accès à confidential et internal également. Une seule UDF de filtrage des lignes contrôle la visibilité des lignes en comparant le niveau de chaque ligne au rôle attribué à l’utilisateur.

Configuration :

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

UDF de filtrage des lignes :

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:

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);

Étant donné qu’un rôle n’est pas membre de lui-même, cette fonction UDF se compare session_user() à chaque nom de rôle plutôt que de tester l’appartenance avec is_account_group_member(). Voir la note dans Comment les fonctions d’identité se comportent lorsqu’elles assument un rôle expliquant pourquoi les vérifications d’appartenance ne correspondent pas au rôle assumé. Consultez Considérations relatives aux performances des règles de filtrage des lignes et de masquage des colonnes pour connaître les incidences sur les performances des fonctions d’identité dans les UDF.

Comportement:

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

Les utilisateurs sélectionnent 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 du système de journal 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_as_display_name et run_by_display_name correspondants contiennent des noms lisibles par l’humain. Pour les requêtes effectuées de manière interactive en assumant un rôle, celles-ci identifient respectivement l’utilisateur et le rôle. Les charges de travail peuvent avoir un initiateur différent. Voir Définir l’exécution en tant que groupe.

Utilisez les événements d’audit pour revoir l’activité dans le cadre d’un rôle. Pour inspecter quelles politiques s’appliquent à une table, utilisez SHOW EFFECTIVE POLICIES comme décrit dans Plan pour une évaluation dynamique des politiques. Pour l’accès à l’audit, le format et la disponibilité, voir Vérifier l’attribution de l’audit.

Ressources supplémentaires

Resource Description
Tutoriel : Accès exclusif aux modèles avec RBAC Configurez et vérifiez l’accès distinct aux données pour deux essais cliniques en utilisant des rôles.
Changer de rôles RBAC Endossez un rôle à l’aide du sélecteur de rôle, de clusters en mode d’accès dédié, de la CLI Databricks, de l’API ou d’outils BI tiers.
Gérer les autorisations sur un groupe Accorder ou révoquer l’autorisation Assume sur un groupe afin que les utilisateurs puissent Assume le rôle correspondant.
Contrôle d’accès basé sur les attributs dans le catalogue Unity Découvrez comment fonctionnent les tags gouvernés, les politiques et l’évaluation des politiques.