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 :
Hiérarchie des rôles.
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 |
---|---|
Renvoie le nom du rôle utilisé pour la session en cours. |
|
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é. |
|
Renvoie le nom du rôle d’exécution. |
|
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. |
|
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;
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 :
Évaluez les conditions de la politique de masquage.
Déterminez si le rôle spécifié se trouve dans la hiérarchie CURRENT_ROLE.
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');+-------------------------------+ | 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;
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 |
|
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;
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 :
Évaluez les conditions de la politique de masquage.
Déterminez si le rôle spécifié possède la vue.
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é |
✔ |
|
Le rôle personnalisé |
✔ |
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;
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;
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;
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 :
Évaluez les conditions de la politique de masquage.
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.
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é |
✔ |
||
Le rôle personnalisé |
✔ |
||
Ni les rôles personnalisés |
✔ |
É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;
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;
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;
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
.