Classification des données d’utilisation

Cette rubrique fournit des exemples d’utilisation du processus de classification dans Snowflake.

Dans ce chapitre :

Vue d’ensemble

Les exemples suivants de classification des données traitent de différents cas d’utilisation en fonction de la portée :

Si vous êtes un nouvel utilisateur de la classification, commencez par classer une seule table, puis passez aux deux autres exemples.

Table et rôles communs

La plupart des exemples de cette rubrique utilisent la table et les rôles personnalisés présentés ci-dessous :

  • my_db.my_schema.hr_data, qui contient des données sur les employés.

  • Rôles :

    • data_engineer: exécute le processus de classification.

    • policy_admin: protège les informations personnelles grâce à une politique de masquage.

    • analyst : est donné comme exemple de rôle personnalisé pour lequel vous pourriez vouloir restreindre l’accès. Les exemples supposent que ce rôle existe.

    • Rôles de base de données:

      • GOVERNANCE_ADMIN: attribue les balises du système de classification.

      • GOVERNANCE_VIEWER: interroge les vues Account Usage relatives aux balises et aux politiques de masquage.

  1. Créer la table :

    CREATE OR REPLACE TABLE hr_data (
        age INTEGER,
        email_address VARCHAR,
        fname VARCHAR,
        lname VARCHAR
        );
    
    Copy
  2. Chargez la table (détails non montrés).

  3. Créez les rôles personnalisés et accordez les privilèges nécessaires à ces rôles.

  4. Le rôle data_engineer doit avoir accès à la table pour exécuter le processus de classification. Notez que cet exemple accorde le rôle de base de données GOVERNANCE_ADMIN au rôle data_engineer car vous ne pouvez pas changer de rôle pour un rôle de base de données :

    use role accountadmin;
    
    create role data_engineer;
    
    grant usage on database my_db to role data_engineer;
    
    grant usage on schema my_db.my_schema to role data_engineer;
    
    grant select, update on table my_db.my_schema.hr_data to role data_engineer;
    
    grant database role snowflake.governance_admin to role data_engineer;
    
    Copy
  5. Le rôle personnalisé policy_admin doit affecter une politique de masquage à toute colonne contenant des données PII :

    use role accountadmin;
    create role policy_admin;
    grant apply masking policy on account to role policy_admin;
    grant database role snowflake.governance_viewer to role policy_admin;
    
    Copy

Classifier une seule table

L’exemple de la table unique s’appuie sur le processus de classification en trois étapes (analyse, révision et application) pour appliquer les résultats afin de révoquer l’accès aux tables du rôle personnalisé analyst.

Étape 1 : classifier les colonnes de la table

Dans cette étape, le data_engineer exécute le processus de classification et le policy_admin protège les données de la colonne avec une politique de masquage.

  1. Analyser : Utilisez le rôle personnalisé data_engineer pour appeler la fonction EXTRACT_SEMANTIC_CATEGORIES afin de classer les colonnes de la table nommée my_db.my_schema.hr_data :

    USE ROLE data_engineer;
    
    SELECT EXTRACT_SEMANTIC_CATEGORIES('my_db.my_schema.hr_data');
    
    Copy
  2. Examiner : L’ingénieur des données examine les résultats pour s’assurer qu’ils ont un sens. Pour plus de détails, reportez-vous à Interpréter le résultat.

  3. Appliquer : L’ingénieur des données attribue une balise du système de classification aux colonnes.

    L’ingénieur des données a deux options : l’affectation automatique ou l’affectation manuelle.

    Pour attribuer automatiquement les balises système, appelez la procédure stockée ASSOCIATE_SEMANTIC_CATEGORY_TAGS. Remarque :

    • Le nom entièrement qualifié de la table et la fonction de la première étape sont des arguments pour la procédure stockée.

    • La procédure stockée réexécute la fonction EXTRACT_SEMANTIC_CATEGORIES. Si vous souhaitez conserver les résultats de la première étape, enregistrez-les dans une table avant d’appeler la procédure stockée.

      CALL ASSOCIATE_SEMANTIC_CATEGORY_TAGS(
         'my_db.my_schema.hr_data',
          EXTRACT_SEMANTIC_CATEGORIES('my_db.my_schema.hr_data')
      );
      
      Copy

      Si l’exécution de la procédure stockée réussit, elle renvoie un message similaire au suivant : Applied tag semantic_category to <n> columns. Applied tag privacy_category to <n> columns.

    Sinon, si la procédure stockée ne s’exécute pas ou si la décision est d’affecter manuellement la balise du système de classification à chaque colonne, utilisez une instruction ALTER TABLE … ALTER COLUMN. Par exemple, attribuez l’une ou l’autre des balises système à la colonne FNAME (c’est-à-dire le prénom).

    USE ROLE data_engineer;
    
    ALTER TABLE my_db.my_schema.hr_data
      MODIFY COLUMN fname
      SET TAG SNOWFLAKE.CORE.SEMANTIC_CATEGORY='NAME';
    
    Copy

    ou

    ALTER TABLE my_db.my_schema.hr_data
      MODIFY COLUMN fname
      SET TAG SNOWFLAKE.CORE.PRIVACY_CATEGORY='IDENTIFIER';
    
    Copy

Étape 2 : protéger les colonnes de la table

Cette étape suppose que plusieurs colonnes de la table my_db.my_schema.hr_data ont la balise PRIVACY_CATEGORY = 'IDENTIFIER' attribuée à ces colonnes et qu’il est nécessaire de protéger ces colonnes avec une politique de masquage.

Pour protéger ces colonnes :

  1. Utilisez le rôle policy_admin pour trouver les colonnes auxquelles est appliquée la balise de confidentialité IDENTIFIER.

    USE ROLE policy_admin;
    
    SELECT * FROM SNOWFLAKE.ACCOUNT_USAGE.TAG_REFERENCES
      WHERE TAG_NAME = 'PRIVACY_CATEGORY'
      AND TAG_VALUE = 'IDENTIFIER';
    
    Copy

    La latence pour la TAG_REFERENCES peut atteindre 120 minutes. Si vous avez besoin de résultats plus rapidement et que vous connaissez le nom de la colonne pour laquelle vous interrogez les balises de classification, vous pouvez utiliser les fonctions de table TAG_REFERENCES ou TAG_REFERENCES_ALL_COLUMNS à la place.

  2. Utilisez le rôle policy_admin pour appliquer des politiques de masquage aux colonnes appropriées. Par exemple, l’instruction suivante applique la politique de masquage identifier_mask à la colonne fname :

    ALTER TABLE my_db.my_schema.hr_data
      MODIFY COLUMN fname
      SET MASKING POLICY governance.policies.identifier_mask;
    
    Copy

Étape 3 : utiliser des balises système pour révoquer un accès

Enfin, l’administrateur de la sécurité (c’est-à-dire un utilisateur avec le rôle SECURITYADMIN) :

  • Interroge la vue TAG_REFERENCES pour trouver toutes les colonnes ayant la valeur de la balise de confidentialité IDENTIFIER.

  • Révoque le privilège SELECT pour le rôle personnalisé analyst sur les tables pour lesquelles la balise PRIVACY_CATEGORY = 'IDENTIFIER' est définie sur une colonne :

Astuce

Il n’est pas nécessaire d’utiliser le rôle système SECURITYADMIN pour effectuer ces tâches ; vous pouvez utiliser tout rôle personnalisé auquel ont été attribués les privilèges nécessaires.

USE ROLE SECURITYADMIN;

SELECT * FROM SNOWFLAKE.ACCOUNT_USAGE.TAG_REFERENCES
    WHERE TAG_NAME = 'PRIVACY_CATEGORY'
    AND TAG_VALUE= 'IDENTIFIER';

REVOKE SELECT ON TABLE my_db.my_schema.hr_data FROM ROLE analyst;
Copy

Classifier toutes les tables d’un schéma

Cet exemple montre comment classifier toutes les tables d’un schéma à l’aide de deux procédures stockées définies par l’utilisateur :

  • classify_schema : répertorie toutes les tables du schéma, crée une table pour stocker les résultats de la classification, puis extrait les balises de classification de chaque table et les stocke dans la table des résultats.

  • associate_tag_batch: Utilise les résultats de la procédure stockée classify_schema pour affecter automatiquement les balises du système de classification à toutes les colonnes des tables du schéma et renvoie le nombre de balises affectées à chaque table.

Important

La procédure stockée nommée classify_schema crée une table temporaire pour stocker les résultats. La table temporaire existe pour la durée de la session de l’utilisateur qui appelle cette procédure stockée. Lorsque la session de l’utilisateur expire, Snowflake supprime la table temporaire et l’utilisateur doit appeler à nouveau la procédure stockée pour recréer la table temporaire.

Si la table temporaire doit être conservée, supprimez le mot-clé temp de la commande sqlText pour créer la table.

Pour plus de détails, voir l’option TEMP[ORARY] dans la commande CREATE TABLE.

  1. Créer la première procédure nommée (classify_schema) :

    create or replace procedure classify_schema(schema_name string, result_table string)
    returns object language JavaScript
    as $$
    // 1
    const table_names = snowflake.execute({
      sqlText: `show terse tables in schema identifier(?)`,
      binds: [SCHEMA_NAME],
    });
    
    // helper function for quoted table names
    function quote(name) {
      return '"'+ name.replace(/"/g,'""') + '"';
    }
    
    // create table to store results in. if it already exists, we will add to it rather than overwrite
    snowflake.execute({
        sqlText: `create temp table if not exists identifier(?) (table_name string, result variant)`,
        binds: [RESULT_TABLE],
    })
    // loop through tables
    while (table_names.next()) {
      let name = table_names.getColumnValue('name');
      // add schema to table name
      name = SCHEMA_NAME + "." + quote(name);
      // insert qualified table name and result into result table
      const results = snowflake.execute({
        sqlText: `insert into identifier(?) select ?, extract_semantic_categories(?)`,
        binds: [RESULT_TABLE, name, name],
      });
    }
    // return the number of tables classified
    return {tables_classified: table_names.getRowCount()};
    $$;
    
    Copy
  2. Créer la deuxième procédure nommée (associate_tag_batch) :

    create or replace procedure associate_tag_batch(result_table string)
    returns Object language JavaScript
    as $$
    // get table names and classification results to loop through
    const tags_to_apply = snowflake.execute({
      sqlText: `select table_name, result from identifier(?)`,
      binds: [RESULT_TABLE],
    });
    
    const out = {};
    while (tags_to_apply.next()) {
      // get table name
      const name = tags_to_apply.getColumnValue('TABLE_NAME');
      // get classification result
      const classification_results = tags_to_apply.getColumnValue('RESULT');
      // call associate semantic category tags with table name and classification result
      const results = snowflake.execute({
        sqlText: `call associate_semantic_category_tags(?, parse_json(?))`,
        binds: [name, JSON.stringify(classification_results)],
      });
      results.next();
      out[name] = results.getColumnValue(1).split('\n');
    }
    // return number of tags applied per table
    return out;
    $$;
    
    Copy
  3. Appelez la procédure stockée classify_schema avec le nom du schéma que vous souhaitez classifier et le nom d’une table temporaire pour contenir les résultats de EXTRACT_SEMANTIC_CATEGORY pour chaque table en tant qu’arguments :

    call classify_schema('my_db.my_schema','my_temporary_classification_table');
    
    Copy
  4. Examinez les résultats dans la table temporaire et modifiez-les si nécessaire. Pour plus de détails, reportez-vous à Interpréter le résultat.

  5. Lorsque vous êtes satisfait des résultats, appelez la procédure stockée associate_tag_batch pour affecter les balises du système de classification aux colonnes de la table :

    call associate_tag_batch('my_temporary_classification_table');
    
    Copy

Classifier toutes les tables d’une base de données

Cet exemple montre comment classifier toutes les tables d’une base de données à l’aide de deux procédures stockées :

  • classify_database: Classe toutes les tables d’un schéma pour chaque schéma de la base de données, et renvoie le nombre de tables et le nombre de schémas qui sont classés.

  • associate_tag_batch: Effectue les mêmes opérations que celles définies dans Classifier toutes les tables d’un schéma (dans cette rubrique).

  1. Créer la procédure stockée classify_database :

    create or replace procedure classify_database(database_name string, result_table string)
    returns Object language JavaScript
    as $$
    // get list of schemas in database
    const schema_names = snowflake.execute({
      sqlText: `show terse schemas in database identifier(?)`,
      binds: [DATABASE_NAME],
    });
    
    // helper function for quoted schema names
    function quote(name) {
      return '"'+ name.replace(/"/g,'""') + '"';
    }
    
    // counter for tables. will use result from classify_schema to increment
    let table_count = 0
    while (schema_names.next()) {
      let name = schema_names.getColumnValue('name');
      // skip the information schema
      if (name == "INFORMATION_SCHEMA") {
        continue;
      }
      // add database name to schema
      name = DATABASE_NAME + "." + quote(name);
      // call classify_schema on each schema. This will loop over tables in schema
      const results = snowflake.execute({
        sqlText: `call classify_schema(?, ?)`,
        binds: [name, RESULT_TABLE],
      });
      results.next();
      // increment total number of tables by the number of tables in the schema
      table_count += results.getColumnValue(1).tables_classified ;
    }
    
    return {
        tables_classified: table_count,
        // subtract one from number of schemas because we skip the information schema
        schemas_classified: schema_names.getRowCount() - 1,
    };
    $$;
    
    Copy
  2. Appelez la procédure stockée classify_database avec le nom de la base de données que vous souhaitez classifier et le nom de la table temporaire pour stocker les résultats dans chaque schéma de la base de données :

    call classify_database('my_db','my_temporary_classification_table');
    
    Copy
  3. Naviguez vers chaque schéma, vérifiez la table temporaire et modifiez-la si nécessaire.

  4. Si les résultats vous conviennent, appelez la procédure stockée associate_tag_batch une fois pour chaque schéma pour appliquer les balises aux tables de ce schéma : Par exemple, si la base de données contient trois schémas, appelez la procédure stockée trois fois :

    call associate_tag_batch('my_temporary_classification_table');
    
    Copy