Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Cette page décrit les modèles courants d’implémentation des stratégies de filtre de lignes et de masque de colonne ABAC. Pour connaître les concepts globaux, consultez Les concepts de base pour le contrôle d’accès basé sur les attributs (ABAC). Pour connaître la syntaxe de stratégie, consultez Créer et gérer des stratégies ABAC.
Fonctions de masquage compatibles avec cast
Azure Databricks caste automatiquement la sortie de la fonction de masquage pour qu'elle corresponde au type de données de la colonne cible. Consultez la conversion automatique des types pour les masques de colonne.
Les modèles suivants vous aident à concevoir des fonctions de masquage compatibles avec cast.
Retourner un type castable
Lors du masquage d’une colonne, retournez le même type de données ou un type qui est convertible. Vérifiez les types de données des colonnes que votre stratégie cible et vérifiez que chaque branche de la fonction retourne une valeur compatible.
-- Succeeds: Masks a DOUBLE column, returns DOUBLE in every branch
CREATE FUNCTION mask_salary(salary DOUBLE, user_role STRING)
RETURNS DOUBLE
RETURN CASE
WHEN user_role IN ('admin', 'hr') THEN salary
WHEN user_role = 'manager' THEN ROUND(salary / 1000) * 1000
ELSE 0.0
END;
-- Fails: 'CONFIDENTIAL' cannot be cast to a DOUBLE column type
CREATE FUNCTION mask_salary_as_text(salary DOUBLE, user_role STRING)
RETURNS STRING
RETURN CASE
WHEN user_role IN ('admin', 'hr') THEN CAST(salary AS STRING)
ELSE 'CONFIDENTIAL'
END;
Éviter le dépassement de capacité numérique
Lorsqu’une fonction de masque accepte et retourne un type numérique plus large que la colonne cible, le résultat est automatiquement converti en type de colonne. Si la valeur retournée dépasse la plage du type plus étroit, le cast provoque un débordement et la requête échoue pendant l'exécution.
-- The target column is TINYINT (max 127). The input is upcast to BIGINT
-- for the function. Adding 1000 produces a BIGINT result that overflows
-- when cast back to TINYINT.
CREATE FUNCTION mask_score(score BIGINT)
RETURNS BIGINT
RETURN score + 1000;
Utiliser VARIANT pour plusieurs types de colonnes
Consultez les fonctions de masquage basées sur VARIANT pour plusieurs types de colonnes.
Compatibilité des casts de test
Testez les fonctions de masquage avec différents modèles de données.
SELECT CAST(mask_salary(salary, 'admin') AS DOUBLE) FROM employees;
SELECT CAST(mask_salary(salary, 'manager') AS DOUBLE) FROM employees;
SELECT CAST(mask_salary(salary, 'viewer') AS DOUBLE) FROM employees;
Fonctions de masquage basées sur VARIANT pour plusieurs types de colonnes
Lorsque vous devez masquer les colonnes de différents types de données (par exemple, INT, , DOUBLEDECIMAL(10,2), DECIMAL(15,5)et ainsi de suite), vous pouvez écrire une seule fonction UDF masquage qui accepte et retourne un VARIANT type. Azure Databricks caste automatiquement la sortie de la fonction masque de colonne pour qu'elle corresponde au type de données de la colonne cible conformément aux normes ANSI SQL.
Cette approche réduit le nombre de fonctions utilisateur et les stratégies requises. Au lieu d’écrire des fonctions de masquage distinctes pour chaque type de colonne, une fonction gère tous les types.
Masquer plusieurs types numériques avec une fonction unique
Au lieu de créer une fonction de masque distincte pour chaque précision numérique, vous pouvez les utiliser VARIANT pour les gérer toutes avec une seule fonction :
CREATE FUNCTION mask_numeric(val VARIANT)
RETURNS VARIANT
DETERMINISTIC
RETURN 0::VARIANT;
Cette fonction retourne 0 en tant que VARIANT, où Azure Databricks l'adapte automatiquement au type de la colonne cible. Une stratégie ABAC unique utilisant cette fonction peut masquer INT, DOUBLEet DECIMAL les colonnes sans nécessiter de fonctions distinctes pour chaque précision.
Si vous préférez conserver le type explicitement dans la fonction, vous pouvez faire une branche sur le type et retourner une valeur masquée appropriée pour chaque utilisation schema_of_variant():
-- Use VARIANT to accommodate different data types
CREATE FUNCTION flexible_mask(data VARIANT)
RETURNS VARIANT
RETURN CASE
WHEN schema_of_variant(data) = 'INT' THEN 0::VARIANT
WHEN schema_of_variant(data) = 'DATE' THEN DATE'1970-01-01'::VARIANT
WHEN schema_of_variant(data) = 'DOUBLE' THEN 0.00::VARIANT
ELSE NULL::VARIANT
END;
Masquer les colonnes de struct avec VARIANT
Pour Databricks Runtime 18.1 et versions ultérieures, vous pouvez également masquer les colonnes de struct en les convertissant en VARIANT dans une politique ABAC. Utiliser la structure du struct pour masquer sélectivement les champs.
Note
La conversion des structs en VARIANT pour le masquage est prise en charge uniquement dans le cadre des politiques de masquage de colonne ABAC.
L’exemple suivant utilise schema_of_variant() pour identifier deux formes de struct différentes et redacter des champs sensibles dans chacun d’eux :
CREATE FUNCTION flexible_mask(data VARIANT)
RETURNS VARIANT
RETURN CASE
WHEN schema_of_variant(data) = 'OBJECT<age: BIGINT, email: STRING>' THEN
to_variant_object(named_struct('age', data:age, 'email', 'redacted'))
WHEN schema_of_variant(data) = 'OBJECT<id: BIGINT, ssn: STRING>' THEN
to_variant_object(named_struct('id', data:id, 'ssn', 'xxx-xx-xxxx'))
ELSE NULL::VARIANT
END;
Empêcher l’accès jusqu’à ce que les colonnes sensibles soient marquées
Un modèle de gouvernance courant consiste à contrôler l’accès en fonction de la classification des données. Vous pouvez l’implémenter avec une balise et des stratégies restrictives par défaut qui appliquent différents niveaux de protection en fonction de l’état de classification.
- Appliquez une balise comme
classification : unverifiedà tous les nouveaux objets par défaut, par le biais de l’automatisation ou de l’héritage des étiquettes en appliquant la balise au niveau du catalogue ou du schéma, afin que toutes les nouvelles tables ajoutées au catalogue ou au schéma héritent automatiquement de la balise. - Créez une stratégie de filtre de lignes qui bloque l’accès aux tables marquées
classification : unverified. - Créez une stratégie de masque de colonne qui masque les colonnes sensibles sur les tables où la
classification : unverifiedbalise n’est plus présente. - Lorsqu’un gestionnaire de données termine la classification, il met à jour la balise. La stratégie de blocage ne correspond plus et la stratégie de masquage prend effet.
-- Block access to unverified tables for all non-admin users
CREATE FUNCTION catalog.schema.block_all() RETURNS BOOLEAN
RETURN FALSE;
CREATE POLICY block_unverified
ON CATALOG my_catalog
ROW FILTER catalog.schema.block_all
TO `account users` EXCEPT `data_admins`
FOR TABLES
WHEN has_tag_value('classification', 'unverified');
Pour protéger les données sensibles une fois qu’elles ont été classifiées, définissez une stratégie de masque de colonne qui prend effet lorsque la classification : unverified balise n’est plus présente :
CREATE FUNCTION catalog.schema.mask_pii(val STRING)
RETURNS STRING
RETURN '***';
CREATE POLICY mask_reviewed_pii
ON CATALOG my_catalog
COLUMN MASK catalog.schema.mask_pii
TO `account users`
EXCEPT `data_admins`
FOR TABLES
WHEN NOT has_tag_value('classification', 'unverified')
MATCH COLUMNS (has_tag_value('pii', 'name') OR has_tag_value('pii', 'address')) AS m
ON COLUMN m;
Révélation partielle sans regex
Révéler une partie d’une valeur sensible à l’aide d’opérations de chaîne au lieu d’une expression régulière. Le masquage basé sur les expressions régulières examine la valeur complète de chaque ligne, ce qui est coûteux sur les champs de texte volumineux (voir Éviter le masquage par expressions régulières sur les champs de texte volumineux).
CREATE FUNCTION mask_ssn(ssn STRING, show_last INT) RETURNS STRING
DETERMINISTIC
RETURN CONCAT('***-**-', RIGHT(ssn, show_last));
Hachage cohérent (pseudonymisation déterministe)
Le hachage cohérent (également appelé pseudonyme déterministe) remplace les données sensibles par une valeur hachée identique sur plusieurs tables. Le marquage d’une fonction indique DETERMINISTIC au moteur que la fonction retourne toujours le même résultat pour la même entrée, ce qui lui permet d’optimiser la requête. Consultez Utiliser des expressions déterministes et sans risque d’erreur.
La fonction suivante hache de manière cohérente une valeur de chaîne et utilise un paramètre version pour permettre la rotation des clés. Incrémentez le nombre à travers la clause USING COLUMNS de la stratégie version pour générer de nouveaux hachages sans affecter les données historiques qui utilisaient la version précédente. La fonction concatène la valeur d’origine avec le numéro de version avant le hachage. Par conséquent, la même entrée avec la même version produit toujours le même hachage.
CREATE FUNCTION pseudonymize(val STRING, version INT) RETURNS STRING
DETERMINISTIC
RETURN SHA2(CONCAT(val, CAST(version AS STRING)), 256);
Filtrage de lignes avec prédicats en colonnes uniquement
Filtrez des lignes à l’aide d’une logique booléenne simple qui référence uniquement des colonnes de table. Les prédicats de colonne uniquement activent l'optimisation des prédicats, ce qui permet au moteur d'ignorer les données non pertinentes pendant les scans (voir Comprendre l'optimisation des prédicats sur les tables protégées).
CREATE FUNCTION filter_by_region(region STRING, allowed STRING)
RETURNS BOOLEAN
DETERMINISTIC
RETURN array_contains(split(allowed, ','), lower(region));
Utilisez une stratégie qui transmet les régions autorisées en tant que constante :
CREATE POLICY regional_access
ON CATALOG analytics
ROW FILTER filter_by_region
TO 'emea_team'
FOR TABLES
MATCH COLUMNS has_tag('region') AS rgn
USING COLUMNS (rgn, 'emea,apac');
Filtrage de lignes à travers plusieurs colonnes associées
Lorsqu’une table comporte plusieurs colonnes représentant des attributs associés (par exemple, ship_to_country et bill_to_country), vous pouvez les mettre en correspondance avec des conditions d’étiquette distinctes et passer les deux à une seule fonction UDF. Cela évite de créer des stratégies distinctes pour chaque colonne. Une stratégie peut inclure jusqu’à trois expressions de colonne dans la MATCH COLUMNS clause (voir quotas de stratégie).
CREATE FUNCTION filter_by_countries(ship_country STRING, bill_country STRING, allowed STRING)
RETURNS BOOLEAN
DETERMINISTIC
RETURN array_contains(split(allowed, ','), lower(ship_country))
OR array_contains(split(allowed, ','), lower(bill_country));
CREATE POLICY regional_orders
ON SCHEMA prod.orders
ROW FILTER filter_by_countries
TO analysts
FOR TABLES
WHEN has_tag_value('sensitivity', 'high')
MATCH COLUMNS
has_tag('ship_country') AS ship,
has_tag('bill_country') AS bill
USING COLUMNS (ship, bill, 'us,ca,mx');
Un analyste voit uniquement les commandes où le pays d’expédition ou de facturation se trouve dans leur liste autorisée.
Tables de correspondance dans les UDF de politique ABAC
Lorsque les règles d’accès varient par utilisateur et ne peuvent pas être exprimées uniquement par les clauses de la stratégie TO/EXCEPT, vous pouvez vérifier les droits d’accès sur une petite table de recherche. Utilisez TO/EXCEPT le cas échéant, car il s’agit de l’approche recommandée pour le ciblage des principaux (voir Approche pour le ciblage des principaux). Conserver la table de recherche petite afin que l'optimiseur convertisse la sous-requête en jointure de hachage par diffusion (voir Conserver les tables de recherche petites).
CREATE TABLE access_rules (
principal VARCHAR(255),
priority VARCHAR(64)
);
INSERT INTO access_rules VALUES
('alice@company.com', '1-URGENT'),
('alice@company.com', '2-HIGH'),
('bob@company.com', '1-URGENT');
CREATE FUNCTION priority_allowed(o_priority STRING) RETURNS BOOLEAN
RETURN EXISTS (
SELECT 1 FROM access_rules
WHERE principal = session_user() AND priority = o_priority
);
CREATE POLICY priority_filter
ON CATALOG operations
ROW FILTER priority_allowed
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag('priority') AS pri
USING COLUMNS (pri);