CREATE MASKING POLICY

Crée une nouvelle politique de masquage dans le schéma actuel/spécifié ou remplace une politique de masquage existante.

Après avoir créé une politique de masquage, appliquez la politique de masquage à une colonne d’une table à l’aide d’une commande ALTER TABLE … ALTER COLUMN ou d’une vue à l’aide d’une commande ALTER VIEW.

Voir aussi :

Choisir une approche centralisée, hybride ou décentralisée, Rubriques de sécurité avancées au niveau des colonnes

DDL de politique de masquage

Syntaxe

CREATE [ OR REPLACE ] MASKING POLICY [ IF NOT EXISTS ] <name> AS
( <arg_name_to_mask> <arg_type_to_mask> [ , <arg_1> <arg_type_1> ... ] )
RETURNS <arg_type_to_mask> -> <body>
[ COMMENT = '<string_literal>' ]
[ EXEMPT_OTHER_POLICIES = { TRUE | FALSE } ]
Copy

Paramètres requis

name

Identificateur de la politique de masquage ; doit être unique pour votre schéma.

La valeur de l’identificateur doit commencer par un caractère alphabétique et ne peut pas contenir d’espaces ou de caractères spéciaux à moins que toute la chaîne d’identificateur soit délimitée par des guillemets doubles (p. ex. "My object"). Les identificateurs entre guillemets doubles sont également sensibles à la casse.

Pour plus de détails, voir Exigences relatives à l’identificateur.

AS ( arg_name_to_mask arg_type_to_mask [ , arg_1 arg_type_1 ... ] )

La signature de la politique de masquage ; spécifie les colonnes d’entrée et les types de données à évaluer lors de l’exécution de la requête.

Pour plus de détails, voir Référence de types de données SQL.

arg_name_to_mask arg_type_to_mask

La première colonne et son type de données indiquent toujours les valeurs du type de données de la colonne à masquer ou à baliser dans les conditions de stratégies suivantes.

Notez que vous ne pouvez pas spécifier de colonne virtuelle comme premier argument de colonne dans une politique de masquage conditionnelle.

[ , arg_1 arg_type_1 ... ]

Spécifie les colonnes conditionnelles et leurs types de données à évaluer pour déterminer si les conditions de la politique doivent masquer ou tokeniser les données de la première colonne de chaque ligne du résultat de la requête.

Si ces colonnes et types de données supplémentaires ne sont pas spécifiés, Snowflake évalue la politique comme une politique de masquage normale.

RETURNS arg_type_to_mask

Le type de données de retour doit correspondre au type de données d’entrée de la première colonne qui est spécifiée comme une colonne d’entrée.

body

Expression SQL qui transforme les données dans la colonne désignée par arg_name_to_mask.

L’expression peut inclure Fonctions d’expressions conditionnelles pour représenter la logique conditionnelle, les fonctions intégrées ou les UDFs pour transformer les données.

Pour les UDFs et les fonctions externes :

  • Le propriétaire de la politique, le rôle ayant le privilège OWNERSHIP sur la politique, doit avoir le privilège USAGE sur l’UDF ou la fonction externe. Le privilège USAGE sur la fonction externe ou l’UDF n’est pas requis pour le rôle utilisé pour interroger une colonne à laquelle est appliquée une politique de masquage.

  • Si l’une de ces fonctions est utilisée dans le corps de la politique de masquage conditionnelle, le propriétaire de la politique doit avoir le privilège OWNERSHIP sur l’UDF ou la fonction externe. Les utilisateurs interrogeant une colonne à laquelle une politique de masquage conditionnelle est appliquée n’ont pas besoin d’avoir le privilège USAGE sur l’UDF ou sur la fonction externe.

Pour les fonctions contextuelles de la politique body :

Lorsque la politique appelle la fonction CURRENT_DATABASE ou CURRENT_SCHEMA, la fonction évalue la base de données ou le schéma qui contient la table ou la vue protégée, et non la base de données ou le schéma de la session que vous spécifiez avec une commande USE <objet> ou que vous sélectionnez avec le sélecteur de contexte dans Snowsight.

Paramètres facultatifs

COMMENT = 'string_literal'

Ajoute un commentaire ou remplace un commentaire existant pour la politique de masquage.

EXEMPT_OTHER_POLICIES = TRUE | FALSE

L’un des éléments suivants, en fonction de l’utilisation :

  • Spécifie si la politique d’accès aux lignes ou la politique de masquage conditionnel peut faire référence à une colonne qui est déjà protégée par cette politique de masquage.

  • Spécifie si une politique de masquage attribuée à une colonne virtuelle remplace la politique de masquage que la colonne virtuelle hérite de la colonne VALUE. Lorsque vous travaillez avec des tables externes, spécifiez cette propriété dans la politique de masquage qui protège la colonne VALUE.

TRUE

Permet à une autre politique de faire référence à la colonne masquée ou permet à la politique de masquage définie sur une colonne virtuelle de remplacer la politique de masquage que la colonne virtuelle hérite de la colonne VALUE d’une table externe.

FALSE

Ne permet pas à une autre politique de faire référence à la colonne masquée ou n’autorise pas la politique de masquage la colonne virtuelle hérite de la colonne VALUE d’une table externe.

Remarques :

  • La valeur de cette propriété dans la politique de masquage ne peut pas changer après avoir défini la politique de masquage sur une table ou une vue. Pour mettre à jour la valeur de ce paramètre de propriété, exécutez une instruction CREATE OR REPLACE MASKING POLICY sur la politique de masquage.

  • Lorsque la propriété est définie sur true, elle est incluse dans la sortie de l’appel de la fonction GET_DDL sur la police.

Exigences en matière de contrôle d’accès

Un rôle utilisé pour exécuter cette commande SQL doit avoir les privilèges suivants définis au minimum ainsi :

Privilège

Objet

Remarques

CREATE MASKING POLICY

Schéma

Notez que l’exploitation d’un objet dans un schéma requiert également le privilège USAGE sur la base de données et le schéma parents.

Pour obtenir des instructions sur la création d’un rôle personnalisé avec un ensemble spécifique de privilèges, voir Création de rôles personnalisés.

Pour des informations générales sur les rôles et les privilèges accordés pour effectuer des actions SQL sur des objets sécurisables, voir Aperçu du contrôle d’accès.

Lors de la spécification de la propriété EXEMPT_OTHER_POLICIES dans une politique de masquage, le rôle qui possède la politique de masquage (c’est-à-dire le rôle avec le privilège OWNERSHIP sur la politique) doit être dans la hiérarchie des rôles du rôle qui possède la politique d’accès aux lignes ou la politique de masquage conditionnel.

Par exemple, les rôles personnalisés d’administrateur de politiques peuvent former une hiérarchie de rôles comme suit :

masking_admin » rap_admin » SYSADMIN

masking_admin » cond_masking_admin » SYSADMIN

Où :

masking_admin

Spécifie le rôle personnalisé propriétaire de la stratégie de masquage définie sur la colonne qui sera spécifiée dans la signature d’une politique d’accès aux lignes ou d’une politique de masquage conditionnel.

rap_admin

Spécifie le rôle personnalisé propriétaire de la politique d’accès aux lignes.

cond_masking_admin

Spécifie le rôle personnalisé propriétaire de la politique de masquage conditionnel.

Pour plus de détails sur la DDL de politique de masquage et les privilèges, voir Gestion de la sécurité au niveau des colonnes.

Notes sur l’utilisation

  • Si vous souhaitez remplacer une politique de masquage existante et si vous avez besoin de voir la définition actuelle de cette politique, appelez la fonction GET_DDL ou exécutez la commande DESCRIBE MASKING POLICY.

  • Pour les politiques de masquage qui incluent une sous-requête dans le corps de la politique de masquage, utilisez EXISTS dans la branche WHEN de la fonction CASE. Pour un exemple représentatif, reportez-vous à l’exemple d’une table de droits personnalisés dans la section Politique de masquage normale (dans cette rubrique).

  • Une colonne de table ou de vue donnée peut être spécifiée soit dans une signature de politique de masquage, soit dans une signature de politique d’accès aux lignes. En d’autres termes, la même colonne ne peut pas être spécifiée à la fois dans une signature de politique de masquage et dans une signature de politique d’accès aux lignes.

    Pour plus d’informations, voir CREATE ROW ACCESS POLICY.

  • Un fournisseur de partage de données ne peut pas créer une politique de masquage dans un compte de lecteur.

  • Si vous utilisez une UDF dans une politique de masquage, assurez-vous que le type de données de la colonne, l’UDF, et la politique de masquage correspondent. Pour plus d’informations, consultez Fonctions définies par l’utilisateur dans une politique de masquage.

  • Concernant les métadonnées :

    Attention

    Les clients doivent s’assurer qu’aucune donnée personnelle (autre que pour un objet utilisateur), donnée sensible, donnée à exportation contrôlée ou autre donnée réglementée n’est saisie comme métadonnée lors de l’utilisation du service Snowflake. Pour plus d’informations, voir Champs de métadonnées dans Snowflake.

  • Les instructions CREATE OR REPLACE <objet> sont atomiques. En d’autres termes, lorsqu’un objet est remplacé, l’ancien objet est supprimé et le nouvel objet est créé dans une seule transaction.

Exemple : politique de masquage normale

Vous pouvez utiliser Fonctions d’expressions conditionnelles, Fonctions contextuelles et des UDFs pour écrire l’expression SQL.

Les exemples suivants sont représentatifs du corps de la politique et montrent comment créer des conditions de politique de masquage en utilisant différentes expressions SQL, fonctions et types de données.

Ces exemples utilisent principalement la fonction contextuelle CURRENT_ROLE. Si l’activation des rôles et la hiérarchie des rôles sont nécessaires dans les conditions de la politique, utilisez IS_ROLE_IN_SESSION.

Masque complet :

Le rôle personnalisé analyst peut voir la valeur en texte brut. Les utilisateurs sans le rôle personnalisé analyst voient un masque complet.

CREATE OR REPLACE MASKING POLICY email_mask AS (val string) returns string ->
  CASE
    WHEN current_role() IN ('ANALYST') THEN VAL
    ELSE '*********'
  END;
Copy

Permettre à un compte de production de voir les valeurs non masquées et à tous les autres comptes (par exemple, développement, test) de voir les valeurs masquées.

case
  when current_account() in ('<prod_account_identifier>') then val
  else '*********'
end;
Copy

Renvoi de NULL pour les utilisateurs non autorisés :

case
  when current_role() IN ('ANALYST') then val
  else NULL
end;
Copy

Renvoi d’une valeur masquée statique pour les utilisateurs non autorisés :

CASE
  WHEN current_role() IN ('ANALYST') THEN val
  ELSE '********'
END;
Copy

Renvoi d’une valeur de hachage en utilisant SHA2 , SHA2_HEX pour les utilisateurs non autorisés : L’utilisation d’une fonction de hachage dans une politique de masquage peut entraîner des collisions ; il faut donc être prudent avec cette approche. Pour plus d’informations, voir Rubriques de sécurité avancées au niveau des colonnes.

CASE
  WHEN current_role() IN ('ANALYST') THEN val
  ELSE sha2(val) -- return hash of the column value
END;
Copy

Appliquer un masque partiel ou un masque complet :

CASE
  WHEN current_role() IN ('ANALYST') THEN val
  WHEN current_role() IN ('SUPPORT') THEN regexp_replace(val,'.+\@','*****@') -- leave email domain unmasked
  ELSE '********'
END;
Copy

Utilisation des horodatages.

case
  WHEN current_role() in ('SUPPORT') THEN val
  else date_from_parts(0001, 01, 01)::timestamp_ntz -- returns 0001-01-01 00:00:00.000
end;
Copy

Important

Actuellement, Snowflake ne prend pas en charge différents types de données d’entrée et de sortie dans une politique de masquage, comme la définition de la politique de masquage pour cibler un horodatage et renvoyer une chaîne (par exemple ***MASKED***) ; les types de données d’entrée et de sortie doivent correspondre.

Une solution consiste à remplacer la valeur réelle de l’horodatage par une valeur d’horodatage fabriquée. Pour plus d’informations, voir DATE_FROM_PARTS et CAST , ::.

En utilisant une UDF :

CASE
  WHEN current_role() IN ('ANALYST') THEN val
  ELSE mask_udf(val) -- custom masking function
END;
Copy

Sur les données des variantes :

CASE
   WHEN current_role() IN ('ANALYST') THEN val
   ELSE OBJECT_INSERT(val, 'USER_IPADDRESS', '****', true)
END;
Copy

En utilisant une table de droits personnalisée. Notez l’utilisation de EXISTS dans la clause WHEN. Utilisez toujours EXISTS lors de l’inclusion d’une sous-requête dans le corps de la politique de masquage. Pour plus d’informations sur les sous-requêtes que Snowflake prend en charge, voir Utilisation des sous-requêtes.

CASE
  WHEN EXISTS
    (SELECT role FROM <db>.<schema>.entitlement WHERE mask_method='unmask' AND role = current_role()) THEN val
  ELSE '********'
END;
Copy

En utilisant DECRYPT sur des données précédemment chiffrées avec ENCRYPT ou ENCRYPT_RAW, avec une phrase secrète sur les données chiffrées :

case
  when current_role() in ('ANALYST') then DECRYPT(val, $passphrase)
  else val -- shows encrypted value
end;
Copy

En utilisant une <JavaScript UDF sur JSON (VARIANT) :

Dans cet exemple, une UDF JavaScript masque les données d’emplacement dans une chaîne JSON. Il est important de définir le type de données comme VARIANT dans l’UDF et la politique de masquage. Si le type de données dans la colonne de la table, l’UDF et la signature de la politique de masquage ne correspondent pas, Snowflake renvoie un message d’erreur, car il ne peut pas résoudre la requête SQL.

-- Flatten the JSON data

create or replace table <table_name> (v variant) as
select value::variant
from @<table_name>,
  table(flatten(input => parse_json($1):stationLocation));

-- JavaScript UDF to mask latitude, longitude, and location data

CREATE OR REPLACE FUNCTION full_location_masking(v variant)
  RETURNS variant
  LANGUAGE JAVASCRIPT
  AS
  $$
    if ("latitude" in V) {
      V["latitude"] = "**latitudeMask**";
    }
    if ("longitude" in V) {
      V["longitude"] = "**longitudeMask**";
    }
    if ("location" in V) {
      V["location"] = "**locationMask**";
    }

    return V;
  $$;

  -- Grant UDF usage to ACCOUNTADMIN

  grant ownership on function FULL_LOCATION_MASKING(variant) to role accountadmin;

  -- Create a masking policy using JavaScript UDF

  create or replace masking policy json_location_mask as (val variant) returns variant ->
    CASE
      WHEN current_role() IN ('ANALYST') THEN val
      else full_location_masking(val)
      -- else object_insert(val, 'latitude', '**locationMask**', true) -- limited to one value at a time
    END;
Copy

Utilisation du type de données GEOGRAPHY :

Dans cet exemple, une politique de masquage utilise la fonction TO_GEOGRAPHY pour convertir toutes les données GEOGRAPHY d’une colonne en un point fixe, la longitude et la latitude de Snowflake à San Mateo, en Californie, pour les utilisateurs dont CURRENT_ROLE n’est pas ANALYST.

create masking policy mask_geo_point as (val geography) returns geography ->
  case
    when current_role() IN ('ANALYST') then val
    else to_geography('POINT(-122.35 37.55)')
  end;
Copy

Définissez la politique de masquage sur une colonne avec le type de données GEOGRAPHY et définissez la valeur GEOGRAPHY_OUTPUT_FORMAT de la session sur GeoJSON :

alter table mydb.myschema.geography modify column b set masking policy mask_geo_point;
alter session set geography_output_format = 'GeoJSON';
use role public;
select * from mydb.myschema.geography;
Copy

Snowflake renvoie les résultats suivants :

---+--------------------+
 A |         B          |
---+--------------------+
 1 | {                  |
   |   "coordinates": [ |
   |     -122.35,       |
   |     37.55          |
   |   ],               |
   |   "type": "Point"  |
   | }                  |
 2 | {                  |
   |   "coordinates": [ |
   |     -122.35,       |
   |     37.55          |
   |   ],               |
   |   "type": "Point"  |
   | }                  |
---+--------------------+
Copy

Les valeurs des résultats de la requête dans la colonne B dépendent de la valeur du paramètre GEOGRAPHY_OUTPUT_FORMAT pour la session. Par exemple, si la valeur du paramètre est définie sur WKT, Snowflake renvoie les résultats suivants :

alter session set geography_output_format = 'WKT';
select * from mydb.myschema.geography;

---+----------------------+
 A |         B            |
---+----------------------+
 1 | POINT(-122.35 37.55) |
 2 | POINT(-122.35 37.55) |
---+----------------------+
Copy

Pour des exemples utilisant d’autres fonctions de contexte et la hiérarchie des rôles, voir Rubriques de sécurité avancées au niveau des colonnes.

Exemple : politique de masquage conditionnel

L’exemple suivant renvoie des données non masquées pour les utilisateurs dont CURRENT_ROLE est le rôle personnalisé admin, ou dont la valeur de la colonne de visibilité est Public. Toutes les autres conditions donnent lieu à une valeur masquée fixe.

-- Conditional Masking

create masking policy email_visibility as
(email varchar, visibility string) returns varchar ->
  case
    when current_role() = 'ADMIN' then email
    when visibility = 'Public' then email
    else '***MASKED***'
  end;
Copy

L’exemple suivant renvoie des données détokénisées pour les utilisateurs dont CURRENT_ROLE est le rôle personnalisé admin, et dont la valeur dans une autre colonne est Public. Toutes les autres conditions donnent lieu à une valeur de type tokénisée.

-- Conditional Tokenization

create masking policy de_email_visibility as
 (email varchar, visibility string) returns varchar ->
   case
     when current_role() = 'ADMIN' and visibility = 'Public' then de_email(email)
     else email -- sees tokenized data
   end;
Copy

Exemple : autoriser une colonne masquée dans une politique d’accès aux lignes ou une politique de masquage conditionnel

Remplacez une politique de masquage qui permet d’afficher l’adresse e-mail, d’afficher uniquement le domaine de l’adresse e-mail ou d’afficher une valeur masquée fixe :

create or replace masking policy governance.policies.email_mask
as (val string) returns string ->
case
  when current_role() in ('ANALYST') then val
  when current_role() in ('SUPPORT') then regexp_replace(val,'.+\@','*****@')
  else '********'
end
comment = 'specify in row access policy'
exempt_other_policies = true
;
Copy

Cette politique peut maintenant être définie sur une colonne et une politique d’accès aux lignes, ou une politique de masquage conditionnel peut référencer la colonne protégée par cette politique de masquage selon les besoins.