Uso da classificação de dados com APIs clássicas

Este tópico fornece exemplos de classificação de dados com APIs clássicas no Snowflake: EXTRACT_SEMANTIC_CATEGORIES e ASSOCIATE_SEMANTIC_CATEGORY_TAGS. Essas APIs não estão mais sendo atualizadas para coincidir com as atualizações na classificação de dados.

Você pode continuar a usar estas APIs. No entanto, você deve atualizar seus fluxos de trabalho para usar as abordagens mostradas em Uso da classificação de dados.

Neste tópico:

Visão geral

Os seguintes exemplos de classificação de dados tratam de diferentes casos de uso com base no escopo:

Se você for um novo usuário da classificação, comece classificando uma única tabela e depois siga para os outros dois exemplos.

Tabela e funções comuns

Os exemplos neste tópico utiliza a tabela e as funções personalizadas mostradas abaixo:

  • Tabela: my_db.my_schema.hr_data, que contém dados sobre os funcionários.

  • Funções:

    • data_engineer: classifica tabelas.

    • policy_admin: protege informações pessoais com uma política de mascaramento.

    • analyst: serve como um exemplo de uma função personalizada para a qual você pode querer restringir o acesso. Os exemplos assumem que esta função existe.

    • Funções de banco de dados:

      • GOVERNANCE_ADMIN: atribui as tags do sistema de classificação.

      • GOVERNANCE_VIEWER: consulta as exibições de Account Usage relacionadas a tags e políticas de mascaramento.

  1. Crie a tabela:

    CREATE OR REPLACE TABLE hr_data (
        age INTEGER,
        email_address VARCHAR,
        fname VARCHAR,
        lname VARCHAR
        );
    
    Copy
  2. Carregue a tabela (detalhes não mostrados).

  3. Crie as funções personalizadas e conceda os privilégios necessários a essas funções.

  4. A função data_engineer precisa ter acesso à tabela para executar o processo de classificação. Observe que este exemplo concede a função de banco de dados GOVERNANCE_ADMIN à função data_engineer porque você não pode mudar as funções para uma função de banco de dados:

    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. A função personalizada policy_admin precisa atribuir uma política de mascaramento a qualquer coluna que contenha dados 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

Classificação de uma única tabela

O exemplo de tabela única expande o processo de classificação em três etapas (ou seja, analisar, revisar e aplicar) para aplicar os resultados para revogar o acesso à tabela a partir da função personalizada analyst.

Etapa 1: Classificar as colunas da tabela

Nesta etapa, o data_engineer executa o processo de classificação e o policy_admin protege os dados da coluna com uma política de mascaramento.

  1. Analisar: use a função personalizada data_engineer para chamar a função EXTRACT_SEMANTIC_CATEGORIES para classificar as colunas na tabela chamada my_db.my_schema.hr_data:

    USE ROLE data_engineer;
    
    SELECT EXTRACT_SEMANTIC_CATEGORIES('my_db.my_schema.hr_data');
    
    Copy
  2. Revisar: o engenheiro de dados analisa os resultados para garantir que eles façam sentido.

  3. Aplicar: o engenheiro de dados atribui uma tag do sistema de classificação às colunas.

    O engenheiro de dados tem duas opções: atribuição automatizada ou atribuição manual.

    Para atribuir as tags do sistema automaticamente, chame o procedimento armazenado ASSOCIATE_SEMANTIC_CATEGORY_TAGS. Nota:

    • O nome totalmente qualificado da tabela e a função da primeira etapa são argumentos para o procedimento armazenado.

    • O procedimento armazenado executa novamente a função EXTRACT_SEMANTIC_CATEGORIES. Se você quiser preservar os resultados da primeira etapa, salve os resultados em uma tabela antes de chamar o procedimento armazenado.

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

      Se o procedimento armazenado for executado com sucesso, ele retorna uma mensagem semelhante à seguinte: Applied tag semantic_category to <n> columns. Applied tag privacy_category to <n> columns.

    Caso contrário, quando o procedimento armazenado não for executado ou se a decisão for atribuir a tag do sistema de classificação a cada coluna conforme necessário manualmente, use uma instrução ALTER TABLE … ALTER COLUMN. Por exemplo, atribuir uma ou outra tag do sistema à coluna FNAME (ou seja, nome).

    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

Etapa 2: Proteger as colunas da tabela

Esta etapa considera que várias colunas da tabela my_db.my_schema.hr_data têm a tag PRIVACY_CATEGORY = 'IDENTIFIER' atribuída a estas colunas e que existe a necessidade de proteger estas colunas com uma política de mascaramento.

Para proteger estas colunas:

  1. Use a função policy_admin para encontrar as colunas que têm a tag de privacidade IDENTIFIER aplicada:

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

    A latência da exibição TAG_REFERENCES pode ser de até 120 minutos. Se você precisar dos resultados mais cedo e souber o nome da coluna para a qual está consultando as tags de classificação, também é possível usar as funções de tabela TAG_REFERENCES ou TAG_REFERENCES_ALL_COLUMNS.

  2. Use a função policy_admin para aplicar políticas de mascaramento às colunas apropriadas. Por exemplo, a seguinte instrução aplica a política de mascaramento identifier_mask à coluna fname:

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

Etapa 3: Como usar tags do sistema para revogar o acesso

Finalmente, o administrador de segurança (ou seja, um usuário com a função SECURITYADMIN):

  • Consulta a exibição TAG_REFERENCES para encontrar todas as colunas com o valor da tag de privacidade IDENTIFIER.

  • Revoga o privilégio SELECT para a função personalizada analyst nas tabelas para as quais a tag PRIVACY_CATEGORY = 'IDENTIFIER' está definida em uma coluna:

Dica

Você não precisa usar a função de sistema SECURITYADMIN para realizar estas tarefas. Você pode usar qualquer função personalizada que tenha os privilégios necessários atribuídos.

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

Classificação de todas as tabelas em um esquema

Este exemplo mostra como classificar todas as tabelas em um esquema usando dois procedimentos armazenados definidos pelo usuário:

  • classify_schema: lista todas as tabelas do esquema, cria uma tabela para armazenar os resultados da classificação, e depois extrai as tags de classificação de cada tabela e as armazena na tabela de resultados.

  • associate_tag_batch: usa os resultados do procedimento armazenado classify_schema para atribuir automaticamente as tags do sistema de classificação a todas as colunas da tabela no esquema e retorna o número de tags atribuídas a cada tabela.

Importante

O procedimento armazenado denominado classify_schema cria uma tabela temporária para armazenar os resultados. A tabela temporária existe pela duração da sessão do usuário para o usuário que chama esse procedimento armazenado. Quando a sessão do usuário expira, o Snowflake descarta a tabela temporária e o usuário precisa chamar novamente o procedimento armazenado para recriar a tabela temporária.

Se a tabela temporária precisar ser preservada, remova a palavra-chave temp do comando sqlText para criar a tabela.

Para obter mais detalhes, consulte a opção TEMP[ORARY] no comando CREATE TABLE.

  1. Crie o primeiro procedimento chamado 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. Crie o segundo procedimento chamado 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. Chame o procedimento armazenado classify_schema usando o nome do esquema que você gostaria de classificar e o nome de uma tabela temporária para guardar os resultados de EXTRACT_SEMANTIC_CATEGORY de cada tabela como os argumentos:

    call classify_schema('my_db.my_schema','my_temporary_classification_table');
    
    Copy
  4. Analise os resultados da tabela temporária e modifique conforme necessário.

  5. Quando estiver satisfeito com os resultados, chame o procedimento armazenado associate_tag_batch para atribuir as tags do sistema de classificação às colunas da tabela:

    call associate_tag_batch('my_temporary_classification_table');
    
    Copy

Classificação de todas as tabelas em um banco de dados

Este exemplo mostra como classificar todas as tabelas de um banco de dados utilizando dois procedimentos armazenados:

  • classify_database: classifica todas as tabelas dentro de um esquema para cada esquema no banco de dados, e retorna o número de tabelas e o número de esquemas que são classificados.

  • associate_tag_batch: realiza as mesmas operações definidas em Classificação de todas as tabelas em um esquema (neste tópico).

  1. Crie o procedimento armazenado 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. Chame o procedimento armazenado classify_database com o nome do banco de dados que você deseja classificar e o nome da tabela temporária para armazenar os resultados em cada esquema do banco de dados:

    call classify_database('my_db','my_temporary_classification_table');
    
    Copy
  3. Navegue até cada esquema, reveja a tabela temporária e revise, se necessário.

  4. Quando estiver de acordo com os resultados, chame o procedimento armazenado associate_tag_batch uma vez para cada esquema para aplicar as tags às tabelas desse esquema. Por exemplo, se o banco de dados tiver três esquemas, chame o procedimento armazenado três vezes:

    call associate_tag_batch('my_temporary_classification_table');
    
    Copy