Tópicos avançados de segurança em nível de coluna

Este tópico fornece uma introdução a dois conceitos avançados relacionados a políticas de mascaramento de segurança em nível de coluna:

  1. Hierarquia de funções.

  2. Uso de múltiplas Funções de contexto.

Funções de contexto e hierarquia de funções

A Segurança em nível de coluna suporta o uso de Funções de contexto nas condições do corpo da política de mascaramento para impor se um usuário tem autorização para ver dados. Para determinar se um usuário pode ver os dados em uma determinada instrução SQL, é útil considerar:

A sessão atual

As condições da política de mascaramento usando CURRENT_ROLE visam a função em uso para a sessão atual.

A função de execução

As condições da política de mascaramento usando INVOKER_ROLE visam a função de execução em uma instrução SQL.

Hierarquia das funções

Se a hierarquia de funções for necessária nas condições da política, use IS_ROLE_IN_SESSION.

Determinar se uma função específica em uma condição de política de mascaramento (por exemplo, a função personalizada analyst) é uma função de privilégio inferior na hierarquia de funções CURRENT_ROLE ou INVOKER_ROLE. Se assim for, a função retornada pelas funções CURRENT_ROLE ou INVOKER_ROLE herda os privilégios da função especificada. Para obter mais informações sobre a hierarquia de funções e a herança de privilégios, consulte:

A tabela a seguir mostra funções de contexto comuns em políticas de mascaramento que visam a sessão atual, a função de execução e a hierarquia de funções.

Função de contexto

Descrição

CURRENT_ROLE

Retorna o nome da função em uso para a sessão atual.

IS_ROLE_IN_SESSION

Retorna TRUE se a função atual do usuário na sessão (ou seja, a função retornada por CURRENT_ROLE) herdar os privilégios da função especificada.

INVOKER_ROLE

Retorna o nome da função de execução.

IS_GRANTED_TO_INVOKER_ROLE

Retorna TRUE se a função retornada pela função INVOKER_ROLE herdar os privilégios da função especificada no argumento com base no contexto no qual a função é chamada.

INVOKER_SHARE

Retorna o nome do compartilhamento que acessou diretamente a tabela ou exibição onde a função INVOKER_SHARE é chamada.

Uso de CURRENT_ROLE e IS_ROLE_IN_SESSION

Uma condição de política de mascaramento usando CURRENT_ROLE visa a sessão atual e não é afetada pelo contexto de execução da instrução SQL.

Se a ativação e a hierarquia de funções for necessária nas condições da política, use IS_ROLE_IN_SESSION.

Considere o seguinte corpo de política de mascaramento:

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

Para determinar se um usuário específico tem autorização para ver os dados em uma coluna onde esta política de mascaramento é definida nessa coluna, complete as seguintes etapas:

  1. Avalie as condições da política de mascaramento.

  2. Determine se a função especificada está na hierarquia CURRENT_ROLE.

  3. Realize uma consulta de teste para verificar.

Etapa 1: Avaliar as condições da política de mascaramento

A tabela a seguir resume as consequências das condições do corpo de política de mascaramento.

Contexto

Vê dados não mascarados

Vê dados mascarados

CURRENT_ROLE = função personalizada ANALYST.

CURRENT_ROLE está na função personalizada ANALYST na hierarquia.

CURRENT_ROLE não está na hierarquia de funções personalizadas ANALYST.

A seguir, avalie a hierarquia de funções.

Etapa 2: Determinar se a função especificada está na hierarquia CURRENT_ROLE

Considerando que CURRENT_ROLE não é a função personalizada ANALYST, determine se CURRENT_ROLE herda os privilégios concedidos à função personalizada ANALYST.

Execute a seguinte instrução:

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

Como o Snowflake retorna FALSE, CURRENT_ROLE não herda privilégios concedidos à função personalizada ANALYST. Portanto, com base no corpo da política de mascaramento deste exemplo, o usuário deve ver um valor de máscara fixo.

Etapa 3: Executar uma consulta de teste para verificar

Execute uma consulta na coluna que tem a política de mascaramento neste exemplo aplicada a essa coluna para verificar se o usuário vê um valor de máscara fixo.

USE ROLE analyst;

SELECT * FROM mydb.mysch.mytable;
Copy

Uso de INVOKER_ROLE

Uma condição de política de mascaramento usando INVOKER_ROLE visa o contexto de execução da instrução SQL.

A tabela a seguir resume o contexto de execução e o valor que INVOKER_ROLE retorna em uma condição de política de mascaramento:

Contexto

Função avaliada

Usuário

CURRENT_ROLE

Tabela

CURRENT_ROLE.

Exibição

Função do proprietário da exibição.

UDF

Função do proprietário da UDF.

Procedimento armazenado com direitos do chamador

CURRENT_ROLE.

Procedimento armazenado com direitos do proprietário

Função do proprietário do procedimento armazenado

Tarefa

Função do proprietário da tarefa.

Fluxo

A função que consulta um determinado fluxo.

Considere o seguinte corpo de política de mascaramento que é aplicado a uma única exibição em uma tabela:

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

Para determinar se um usuário específico que executa uma consulta na coluna tem autorização para ver os dados, complete as seguintes etapas:

  1. Avalie as condições da política de mascaramento.

  2. Determine se a função especificada é proprietária da exibição.

  3. Realize uma consulta de teste para verificar.

Etapa 1: Avaliar as condições da política de mascaramento

A tabela a seguir resume as consequências das condições do corpo da política de mascaramento aplicadas a uma coluna de exibição.

Contexto

Vê dados não mascarados

Vê dados mascarados

A função personalizada analyst é a função do proprietário da exibição.

A função personalizada analyst não é a função do proprietário da exibição.

Em seguida, determine se a função personalizada ANALYST é proprietária da exibição.

Etapa 2: Determinar se a função ANALYST é proprietária da exibição

Para determinar se a função personalizada ANALYST é proprietária da exibição, execute a seguinte instrução:

SHOW GRANTS OF ROLE analyst;
Copy

Se a função personalizada analyst for proprietária da exibição, então uma consulta na coluna de exibição deve resultar em dados não mascarados.

Se a função personalizada analyst não for proprietária da exibição, os dados mascarados devem ser vistos.

Etapa 3: Executar uma consulta de teste para verificar

Execute uma consulta na coluna de exibição para determinar se a função personalizada ANALYST vê dados mascarados ou não mascarados.

USE ROLE analyst;

SELECT * FROM mydb.mysch.myview;
Copy

Uso de IS_GRANTED_TO_INVOKER_ROLE

A função IS_GRANTED_TO_INVOKER_ROLE pode ser passada para um corpo de política de mascaramento como parte de uma condição. Quando a função é avaliada como TRUE, a função no argumento da função está na hierarquia INVOKER_ROLE.

Considere o seguinte corpo de política de mascaramento que é aplicado a uma coluna de exibição de números de previdência social (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

Para determinar se um usuário específico que executa uma consulta na coluna de exibição tem autorização para ver os dados, complete as seguintes etapas:

  1. Avalie as condições da política de mascaramento.

  2. Determine se a função especificada está na hierarquia de funções do invocador. Por exemplo, se a política for definida em uma exibição, a função especificada deverá estar na hierarquia de funções do proprietário da exibição para retornar TRUE. Para obter mais detalhes, consulte notas de uso.

  3. Realize uma consulta de teste para verificar.

Etapa 1: Avaliar as condições da política de mascaramento

A tabela a seguir resume as consequências das condições do corpo da política de mascaramento aplicadas a uma coluna de exibição e a exibição de dados na coluna de exibição.

Contexto

Dados não mascarados

Dados parcialmente mascarados

Dados mascarados

A função personalizada payroll está na hierarquia de funções do proprietário da exibição.

A função personalizada analyst está na hierarquia de funções do proprietário da exibição.

Nenhuma das funções personalizadas payroll e analyst está na hierarquia do proprietário da exibição.

Etapa 2: Determinar se a função especificada está na hierarquia de funções do proprietário da exibição

Se as funções payroll ou analyst personalizadas estiverem na hierarquia do proprietário da exibição, então a execução de um comando SHOW GRANTS na função do proprietário da exibição pode verificar a hierarquia de funções. Por exemplo:

SHOW GRANTS TO ROLE view_owner_role;
Copy

As saídas da instrução SQL indicarão se a função de proprietário da exibição recebeu a função personalizada payroll ou analyst.

Etapa 3: Executar uma consulta de teste para verificar

Execute uma consulta na coluna que tem a política de mascaramento neste exemplo aplicada a essa coluna para verificar como o usuário vê os dados na coluna de exibição.

USE ROLE payroll;

SELECT * FROM mydb.mysch.myview;

USE ROLE analyst;

SELECT * FROM mydb.mysch.myview;
Copy

Combinação de CURRENT_ROLE e INVOKER_ROLE em políticas de mascaramento

O Snowflake suporta a criação de uma única política de mascaramento para diferenciar a função em uso para a sessão que executa uma consulta (ou seja, CURRENT_ROLE) e o proprietário do objeto que executa uma consulta (por exemplo, proprietário da exibição, INVOKER_ROLE). Os casos de uso deste tipo são normalmente mais complicados do que simplesmente determinar um conjunto de valores para mascarar e um público relativamente pequeno (por exemplo, usuários com a função analyst personalizada) que pode ver valores não mascarados.

Funções de hashing, criptografia e codificação em políticas de mascaramento

Funções de hashing e criptografia/soma de verificação podem ser usadas em políticas de mascaramento para mascarar dados confidenciais.

Antes de implementar qualquer uma destas funções em uma política de mascaramento, é importante considerar se seu caso de uso com estas funções envolve operações JOIN. Sob certas implementações de políticas de mascaramento, operações criativas JOIN que envolvem tabelas e exibições podem levar à engenharia reversa do valor mascarado ao seu verdadeiro valor com base na seguinte limitação:

  • É possível que ocorram colisões porque pode não haver uma representação 1:1 do valor real (ou seja, entrada) e o valor com hash, criptografia ou soma de verificação baseado no número total de valores (ou seja, a saída, o intervalo de valores) a transformar.

Uma representação 1:1 é mais provável de ocorrer até que o número total de valores de entrada atinja a raiz quadrada dos valores de saída a transformar.

Por exemplo, se os valores de saída do hash forem 144, então é razoável esperar que os primeiros 12 valores (ou seja, 144^(1/2) – a raiz quadrada de 144) sejam únicos e que possam ocorrer colisões para os 132 valores restantes. Como esta limitação e sua consequência são possíveis, é aconselhável nunca utilizar funções com hashing, criptografia ou soma de verificação em políticas de mascaramento cujos valores podem ser utilizados em operações JOIN.

Dica

Se o caso de uso da política de mascaramento priorizar a prevenção de colisões para maior segurança, implemente a tokenização externa. A tokenização não resulta em colisões porque há sempre uma representação 1:1 dos valores de entrada e saída.

Se a tokenização não for possível, uma alternativa é implementar uma política de mascaramento para diferenciar entre a função da sessão que executa uma consulta (ou seja, CURRENT_ROLE) e o proprietário do objeto que executa uma consulta (ou seja, INVOKER_ROLE).

Por exemplo, a seguinte política de mascaramento assume duas funções personalizadas diferentes, CSR_EMPL_INFO e DBA_EMPL_INFO, para regular o acesso às informações dos funcionários.

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

Se a política for aplicada à tabela, então a política será herdada para qualquer exibição criada a partir da tabela. Se a função personalizada dba_empl_info for proprietária da exibição criada a partir desta tabela (ou seja, se tiver o privilégio OWNERSHIP na exibição), então somente usuários com esta função personalizada podem ver os valores reais se consultarem a exibição. Os usuários com a função csr_empl_info personalizada sempre veem um valor com hash se a consulta for feita na tabela ou exibição. Todos os outros usuários veem NULL.