Rubriques de sécurité avancées au niveau des colonnes

Cette rubrique fournit une introduction à deux concepts avancés liés aux politiques de masquage de sécurité au niveau des colonnes :

  1. Hiérarchie des rôles.

  2. En utilisant des Fonctions contextuelles multiples.

Fonctions de contexte et hiérarchie des rôles

La sécurité au niveau des colonnes prend en charge l’utilisation de Fonctions contextuelles dans les conditions du corps de la politique de masquage pour vérifier si un utilisateur est autorisé à voir les données. Pour déterminer si un utilisateur peut voir les données dans une instruction SQL donnée, il est utile de considérer les points suivants :

La session en cours

Les conditions de la politique de masquage à l’aide de CURRENT_ROLE ciblent le rôle utilisé pour la session en cours.

Le rôle d’exécution

Les conditions de la politique de masquage à l’aide de INVOKER_ROLE ciblent le rôle d’exécution dans une instruction SQL.

Hiérarchie des rôles

Si la hiérarchie des rôles est nécessaire dans les conditions de la politique, utilisez IS_ROLE_IN_SESSION.

Déterminez si un rôle spécifié dans une condition de politique de masquage (par exemple, un rôle personnalisé analyst) est un rôle de privilège inférieur dans la hiérarchie des rôles CURRENT_ROLE ou INVOKER_ROLE. Si tel est le cas, le rôle renvoyé par les fonctions CURRENT_ROLE ou INVOKER_ROLE hérite des privilèges du rôle spécifié. Pour plus d’informations sur la hiérarchie des rôles et l’héritage des privilèges, voir :

Le tableau suivant présente les fonctions de contexte courantes dans les politiques de masquage qui ciblent la session en cours, le rôle d’exécution et la hiérarchie des rôles.

Fonction contextuelle

Description

CURRENT_ROLE

Renvoie le nom du rôle utilisé pour la session en cours.

IS_ROLE_IN_SESSION

Renvoie TRUE si le rôle actuel de l’utilisateur dans la session (c’est-à-dire le rôle retourné par CURRENT_ROLE) hérite des privilèges du rôle spécifié.

INVOKER_ROLE

Renvoie le nom du rôle d’exécution.

IS_GRANTED_TO_INVOKER_ROLE

Renvoie TRUE si le rôle renvoyé par la fonction INVOKER_ROLE hérite des privilèges du rôle spécifié dans l’argument, en fonction du contexte dans lequel la fonction est appelée.

INVOKER_SHARE

Renvoie le nom du partage qui a directement accédé à la table ou à la vue dans laquelle la fonction INVOKER_SHARE est invoquée.

Utilisez CURRENT_ROLE et IS_ROLE_IN_SESSION

Une condition de politique de masquage utilisant CURRENT_ROLE cible la session en cours et n’est pas affectée par le contexte d’exécution de l’instruction SQL.

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.

Considérez le corps de la politique de masquage suivant :

CREATE OR REPLACE MASKING POLICY mask_string AS
(val string) RETURNS string ->
CASE
  WHEN CURRENT_ROLE() IN ('ANALYST') THEN val
  ELSE '********'
END;
Copy

Pour déterminer si un utilisateur donné a l’autorisation de voir des données dans une colonne où cette politique de masquage est définie sur cette colonne, procédez comme suit :

  1. Évaluez les conditions de la politique de masquage.

  2. Déterminez si le rôle spécifié se trouve dans la hiérarchie CURRENT_ROLE.

  3. Exécutez une requête de test pour vérifier.

Étape 1 : évaluez les conditions de la politique de masquage

Le tableau suivant résume les conséquences des conditions du corps de la politique de masquage.

Contexte

Voit les données non masquées

Voit les données masquées

CURRENT_ROLE = rôle personnalisé ANALYST.

CURRENT_ROLE se trouve dans le rôle personnalisé ANALYST dans la hiérarchie.

CURRENT_ROLE ne se trouve pas dans la hiérarchie des rôles personnalisés ANALYST.

Ensuite, évaluez la hiérarchie des rôles.

Étape 2 : déterminez si le rôle spécifié se trouve dans la hiérarchie CURRENT_ROLE

En supposant que CURRENT_ROLE n’est pas le rôle personnalisé ANALYST, déterminez si CURRENT_ROLE hérite des privilèges accordés au rôle personnalisé ANALYST.

Exécutez l’instruction suivante :

SELECT IS_ROLE_IN_SESSION('ANALYST');
Copy
+-------------------------------+
| IS_ROLE_IN_SESSION('ANALYST') |
+-------------------------------+
| FALSE                         |
+-------------------------------+

Comme Snowflake renvoie FALSE, CURRENT_ROLE n’hérite pas des privilèges accordés au rôle personnalisé ANALYST. Par conséquent, en fonction du corps de la politique de masquage dans cet exemple, l’utilisateur doit voir une valeur de masque fixe.

Étape 3 : exécutez une requête de test pour vérifier

Exécutez une requête sur la colonne dont la politique de masquage dans cet exemple est appliquée à cette colonne pour vérifier que l’utilisateur voit une valeur masquée fixe.

USE ROLE analyst;

SELECT * FROM mydb.mysch.mytable;
Copy

Utiliser INVOKER_ROLE

Une condition de politique de masquage utilisant INVOKER_ROLE cible le contexte d’exécution de l’instruction SQL.

Le tableau suivant résume le contexte d’exécution et la valeur que INVOKER_ROLE renvoie dans une condition de politique de masquage :

Contexte

Rôle évalué

Utilisateur

CURRENT_ROLE

Table

CURRENT_ROLE.

Vue

Afficher le rôle du propriétaire.

UDF

Rôle du propriétaire de l’UDF.

Procédure stockée avec droit de l’appelant

CURRENT_ROLE.

Procédure stockée avec droit du propriétaire

Rôle du propriétaire de la procédure stockée.

Tâche

Rôle de propriétaire de tâche.

Flux

Rôle qui interroge un flux donné.

Considérez le corps de la politique de masquage suivant qui est appliqué à une seule vue sur une table :

CREATE OR REPLACE MASKING POLICY mask_string AS
(val string) RETURNS string ->
CASE
  WHEN INVOKER_ROLE() IN ('ANALYST') THEN val
  ELSE '********'
END;
Copy

Pour déterminer si un utilisateur donné exécutant une requête sur la colonne a l’autorisation de voir les données, procédez comme suit :

  1. Évaluez les conditions de la politique de masquage.

  2. Déterminez si le rôle spécifié possède la vue.

  3. Exécutez une requête de test pour vérifier.

Étape 1 : évaluez les conditions de la politique de masquage

Le tableau suivant résume les conséquences des conditions du corps de la politique de masquage appliquées à une colonne de vue.

Contexte

Voit les données non masquées

Voit les données masquées

Le rôle personnalisé analyst est le rôle de propriétaire de la vue.

Le rôle personnalisé analyst n’est pas le rôle de propriétaire de la vue.

Ensuite, déterminez si le rôle personnalisé ANALYST possède la vue.

Étape 2 : déterminez si le rôle ANALYST est propriétaire de la vue

Pour déterminer si le rôle personnalisé ANALYST possède la vue, exécutez l’instruction suivante :

SHOW GRANTS OF ROLE analyst;
Copy

Si le rôle personnalisé analyst est propriétaire de la vue, une requête dans la colonne de vue doit générer des données non masquées.

Si le rôle personnalisé analyst ne possède pas la vue, les données masquées doivent être affichées.

Étape 3 : exécutez une requête de test pour vérifier

Exécutez une requête sur la colonne de vue pour déterminer si le rôle personnalisé ANALYST voit des données masquées ou non masquées.

USE ROLE analyst;

SELECT * FROM mydb.mysch.myview;
Copy

Utiliser IS_GRANTED_TO_INVOKER_ROLE

La fonction IS_GRANTED_TO_INVOKER_ROLE peut être validée dans un corps de politique de masquage dans le cadre d’une condition. Lorsque la fonction correspond à TRUE, le rôle dans l’argument de la fonction se situe dans la hiérarchie INVOKER_ROLE.

Considérez le corps de la politique de masquage suivant qui est appliqué à une colonne de vue des numéros de sécurité sociale (SSNs) :

CREATE OR REPLACE MASKING POLICY mask_string AS
(val string) RETURNS string ->
CASE
  WHEN IS_GRANTED_TO_INVOKER_ROLE('PAYROLL') THEN val
  WHEN IS_GRANTED_TO_INVOKER_ROLE('ANALYST') THEN REGEXP_REPLACE(val, '[0-9]', '*', 7)
  ELSE '*******'
END;
Copy

Pour déterminer si un utilisateur donné exécutant une requête sur la colonne de vue a l’autorisation de voir les données, procédez comme suit :

  1. Évaluez les conditions de la politique de masquage.

  2. Déterminez si le rôle spécifié se trouve dans la hiérarchie de rôles de l’invocateur. Par exemple, si la stratégie est définie sur une vue, le rôle spécifié doit faire partie de la hiérarchie de rôles du propriétaire de la vue pour renvoyer TRUE. Pour plus de détails, voir les notes sur l’utilisation.

  3. Exécutez une requête de test pour vérifier.

Étape 1 : évaluez les conditions de la politique de masquage

Le tableau suivant résume les conséquences des conditions du corps de la politique de masquage appliquées à une colonne de vue et de l’affichage des données dans la colonne de vue.

Contexte

Données non masquées

Données partiellement masquées

Données masquées

Le rôle personnalisé payroll se trouve dans la hiérarchie des rôles de propriétaire de la vue.

Le rôle personnalisé analyst se trouve dans la hiérarchie des rôles de propriétaire de la vue.

Ni les rôles personnalisés payroll ni analyst ne figurent dans la hiérarchie des propriétaires de vues.

Étape 2 : déterminez si le rôle spécifié se trouve dans la hiérarchie des rôles du propriétaire de la vue

Si les rôles personnalisés payroll ou analyst se trouvent dans la hiérarchie du propriétaire de la vue, l’exécution d’une commande SHOW GRANTS sur le rôle du propriétaire de la vue peut vérifier la hiérarchie des rôles. Par exemple :

SHOW GRANTS TO ROLE view_owner_role;
Copy

Les sorties de l’instruction SQL indiqueront si le rôle de propriétaire de la vue a reçu les rôles personnalisés payroll ou analyst.

Étape 3 : exécutez une requête de test pour vérifier

Exécutez une requête sur la colonne qui possède la politique de masquage de cet exemple appliquée à cette colonne pour vérifier comment l’utilisateur voit les données dans la colonne de vue.

USE ROLE payroll;

SELECT * FROM mydb.mysch.myview;

USE ROLE analyst;

SELECT * FROM mydb.mysch.myview;
Copy

Combinez CURRENT_ROLE et INVOKER_ROLE dans les politiques de masquage

Snowflake prend en charge la création d’une politique de masquage unique pour différencier le rôle utilisé pour la session qui exécute une requête (c’est-à-dire CURRENT_ROLE) et le propriétaire de l’objet qui exécute une requête (par exemple, le propriétaire de la vue, INVOKER_ROLE). Les cas d’utilisation de ce type sont généralement plus compliqués que la simple détermination d’un ensemble de valeurs à masquer et d’un public relativement restreint (par exemple les utilisateurs avec le rôle personnalisé analyst) qui peut voir les valeurs non masquées.

Fonctions de hachage, de cryptage et de chiffrement dans les politiques de masquage

Le hachage et Cryptographique/Somme de contrôle peuvent être utilisés dans les politiques de masquage pour masquer les données sensibles.

Avant de mettre en œuvre l’une de ces fonctions dans une politique de masquage, il est important d’examiner si votre cas d’utilisation de ces fonctions implique des opérations JOIN. Dans le cadre de certaines mises en œuvre de la politique de masquage, des opérations JOIN créatives faisant intervenir des tables et des vues peuvent conduire à une rétroingénierie de la valeur masquée à sa valeur réelle en fonction de la limitation suivante :

  • Il est possible que des collisions se produisent parce qu’il peut ne pas y avoir de représentation exactes (1:1) de la valeur réelle (c’est-à-dire de l’entrée) et de la valeur hachée, cryptographique ou de la somme de contrôle basée sur le nombre total de valeurs (c’est-à-dire la sortie, la plage de valeurs) à transformer.

Une représentation exacte (1:1) est plus susceptible de se produire jusqu’à ce que le nombre total de valeurs d’entrée atteigne la racine carrée des valeurs de sortie à transformer.

Par exemple, si les valeurs de sortie à hacher sont 144, il est raisonnable de s’attendre à ce que les 12 premières valeurs (c’est-à-dire 144^(1/2) – la racine carrée de 144) soient uniques et que des collisions puissent se produire pour les 132 valeurs restantes. Cette limitation et ses conséquences étant possibles, il est conseillé de ne jamais utiliser de fonctions de hachage, de cryptographie ou de somme de contrôle dans les politiques de masquage dont les valeurs peuvent être utilisées dans les opérations JOIN.

Astuce

Si le cas d’utilisation de la politique de masquage donne la priorité à l’évitement des collisions pour une sécurité renforcée, il faut mettre en œuvre la tokenisation externe. La tokenisation n’entraîne pas de collisions, car il y a toujours une représentation exacte (1:1) des valeurs d’entrée et de sortie.

Si la tokenisation n’est pas possible, une solution possible consiste à mettre en œuvre une politique de masquage pour différencier le rôle de session exécutant une requête (c’est-à-dire CURRENT_ROLE) et le propriétaire de l’objet exécutant une requête (c’est-à-dire INVOKER_ROLE).

Par exemple, la politique de masquage suivante assume deux rôles personnalisés différents, CSR_EMPL_INFO et DBA_EMPL_INFO, pour réglementer l’accès aux informations sur les employés.

CREATE OR REPLACE MASKING POLICY mask_string AS
(val string) RETURNS string ->
CASE
    WHEN CURRENT_ROLE() IN ('CSR_EMPL_INFO') THEN HASH(val)
    WHEN INVOKER_ROLE() IN ('DBA_EMPL_INFO') THEN val
    ELSE null
END;
Copy

Si la politique est appliquée à la table, alors la politique sera héritée de toute vue créée à partir de la table. Si le rôle personnalisé dba_empl_info possède la vue créée à partir de cette table (c’est-à-dire qu’il a le privilège OWNERSHIP sur la vue), alors seuls les utilisateurs ayant ce rôle personnalisé peuvent voir les valeurs réelles s’ils interrogent la vue. Les utilisateurs ayant le rôle personnalisé csr_empl_info voient toujours une valeur hachée, que la requête soit faite sur la table ou sur la vue. Tous les autres utilisateurs voient NULL.