Filtrar dados confidenciais da tabela com filtros de linha e máscaras de coluna
Este artigo apresenta diretrizes e exemplos para usar filtros de linha, máscaras de coluna e tabelas de mapeamento para filtrar dados confidenciais em suas tabelas. Esses recursos exigem o Unity Catalog.
O que são filtros de linha?
Os filtros de linha possibilitam que você aplique um filtro a uma tabela para as consultas retornarem somente as linhas que atenderem aos critérios do filtro. Você implementa um filtro de linha como uma função SQL definida pelo usuário (UDF). As UDFs do Python e do Scala também são compatíveis, mas somente quando são agrupadas em UDFs do SQL.
O que são máscaras de coluna?
As máscaras de coluna possibilitam a aplicação de uma função de mascaramento a uma coluna da tabela. A função de mascaramento é avaliada no tempo de execução da consulta, substituindo cada referência da coluna de destino pelos resultados da função de mascaramento. Na maioria dos casos de uso, as máscaras de coluna determinam se o valor original da coluna deve ser retornado ou redigido com base na identidade do usuário que o invoca. As máscaras de coluna são expressões escritas como UDFs SQL ou como UDFs Python ou Scala que são agrupadas em UDFs SQL.
Cada coluna da tabela pode ter apenas uma função de mascaramento aplicada a ela. A função de mascaramento recebe o valor não mascarado da coluna como entrada e retorna o valor mascarado como resultado. O valor de retorno da função de mascaramento deve ser do mesmo tipo que a coluna que está sendo mascarada. A função de mascaramento também pode receber colunas adicionais como parâmetros de entrada e usá-las em sua lógica de mascaramento.
Qual é a diferença entre esses filtros e visualizações dinâmicas?
Exibições dinâmicas, filtros de linha e máscaras de coluna possibilitam que você aplique uma lógica complexa às tabelas e processe suas decisões de filtragem no tempo de execução da consulta.
Uma exibição dinâmica é uma exibição abstrata e somente leitura de uma ou mais tabelas de origem. O usuário pode acessar uma visualização dinâmica sem ter acesso direto às tabelas de origem. A criação de uma exibição dinâmica define um novo nome de tabela que não deve corresponder ao nome de nenhuma tabela de origem ou de outras tabelas e exibições presentes no mesmo esquema.
Por outro lado, associar um filtro de linha ou máscara de coluna a uma tabela de destino aplica a lógica correspondente diretamente à tabela em si, sem introduzir novos nomes de tabela. Consultas subsequentes podem continuar a se referir diretamente à tabela de destino utilizando seu nome original.
Use exibições dinâmicas se precisar aplicar lógica de transformação, como filtros e máscaras, a tabelas somente leitura e se for aceitável que os usuários se refiram às exibições dinâmicas utilizando outros nomes. Se quiser filtrar dados ao compartilhá-los utilizando o Delta Sharing, você deverá usar visualizações dinâmicas. Utilize filtros de linha e máscaras de coluna se quiser filtrar ou calcular expressões sobre dados específicos, mas ainda assim oferecer aos usuários acesso às tabelas com seus nomes originais.
Antes de começar
Para adicionar filtros de linha e máscaras de coluna a tabelas, você deve ter:
Um espaço de trabalho preparado para o Unity Catalog.
Uma função registrada no Unity Catalog. Pode ser uma UDF SQL ou uma UDF Python ou Scala registrada no Unity Catalog e envolvida em uma UDF SQL. Para ver os detalhes, consulte O que são funções definidas pelo usuário (UDFs), Cláusula de máscara de coluna e Cláusula ROW FILTER.
Você também deve atender aos seguintes requisitos:
Para atribuir uma função que adiciona filtros de linha ou máscaras de coluna a uma tabela, você deve ter o privilégio
EXECUTE
na função,USE SCHEMA
no esquema eUSE CATALOG
no catálogo principal.Se você estiver adicionando filtros ou máscaras ao criar uma nova tabela, deverá ter o privilégio
CREATE TABLE
no esquema.Se você estiver adicionando filtros ou máscaras a uma tabela existente, deverá ser o proprietário da tabela ou ter os privilégios
MODIFY
eSELECT
na tabela.
Para acessar uma tabela que tenha filtros de linha ou máscaras de coluna, seu recurso de compute deve atender a um desses requisitos:
A SQL warehouse.
Modo de acesso compartilhado em Databricks Runtime 12.2 LTS ou acima.
Aplicar um filtro de linha
Para criar um filtro de linha, você escreve uma função (UDF) para definir a política de filtro e, em seguida, aplica a uma tabela. Cada tabela pode ter apenas um filtro de linha. Um filtro de linha aceita zero ou mais parâmetros de entrada em que cada parâmetro de entrada se vincula a uma coluna da tabela correspondente.
Você pode aplicar um filtro de linhas utilizando comandos do Explorador de Catálogos ou SQL. As instruções do Gerenciador de Catálogos pressupõem que você já tenha criado uma função e que ela esteja registrada no Unity Catalog. As instruções SQL incluem exemplos de criação de uma função de filtro de linha e aplicação a uma tabela.
No seu workspace do Databricks, clique em Catálogo.
Navegue ou pesquise a tabela que você deseja filtrar.
Na guia Overview (Visão geral ), clique em Row filter (Filtro de linha): Adicionar filtro.
Na caixa de diálogo Adicionar filtro de linha, selecione o catálogo e o esquema que contêm a função de filtro e, em seguida, selecione a função.
Na caixa de diálogo expandida, consulte a definição da função e selecione as colunas da tabela correspondentes às colunas incluídas na instrução da função.
Clique em Adicionar.
Para remover o filtro da tabela, clique em fx Row filter e clique em Remover.
Para criar um filtro de linhas e adicioná-lo a uma tabela existente, use CREATE FUNCTION
e aplique a função com ALTER TABLE
. Você também pode aplicar uma função ao criar uma tabela utilizando CREATE TABLE
.
Criar o filtro de linha:
CREATE FUNCTION <function_name> (<parameter_name> <parameter_type>, ...) RETURN {filter clause whose output must be a boolean};
Aplicar o filtro de linha a uma tabela utilizando um nome de coluna:
ALTER TABLE <table_name> SET ROW FILTER <function_name> ON (<column_name>, ...);
**Exemplos adicionais de sintaxe**:
Aplique o filtro de linha a uma tabela usando um literal constante que corresponda a um parâmetro de função:
ALTER TABLE <table_name> SET ROW FILTER <function_name> ON (<constant_literal>, ...);
Remover um filtro de linha de uma tabela:
ALTER TABLE <table_name> DROP ROW FILTER;
Modificar um filtro de linha:
Run a DROP FUNCTION statement to drop the existing function, or use CREATE OR REPLACE FUNCTION to replace it.
Excluir um filtro de linha:
ALTER TABLE <table_name> DROP ROW FILTER; DROP FUNCTION <function_name>;
Observação
Você deve executar o comando
ALTER TABLE ... DROP ROW FILTER
antes de descartar a função. Se você não fizer isso, a tabela ficará em um estado inacessível.Se a tabela tornar-se inacessível dessa maneira, altere a tabela e descarte a referência de filtro de linha órfã utilizando
ALTER TABLE <table_name> DROP ROW FILTER;
.
Consulte também a cláusula ROW FILTER.
Exemplos de filtro de linha
Este exemplo cria uma função SQL definida pelo usuário que se aplica aos membros do grupo admin
na região US
.
Quando esta função de exemplo é aplicada à tabela sales
, os membros do grupo admin
podem acessar todos os registros na tabela. Se a função for chamada por um não administrador, a condição RETURN_IF
falhará e a expressão region='US'
será avaliada, filtrando a tabela para mostrar apenas registros na região US
.
CREATE FUNCTION us_filter(region STRING)
RETURN IF(IS_ACCOUNT_GROUP_MEMBER('admin'), true, region='US');
Aplicar a função a uma tabela como um filtro de linha. Consultas subsequentes da tabela sales
retornam um subconjunto de linhas.
CREATE TABLE sales (region STRING, id INT);
ALTER TABLE sales SET ROW FILTER us_filter ON (region);
Desativar o filtro de linha. Em seguida, consultas futuras de usuários da tabela sales
retornam todas as linhas na tabela.
ALTER TABLE sales DROP ROW FILTER;
Crie uma tabela com a função aplicada como filtro de linha como parte da instrução CREATE TABLE
. Em seguida, consultas futuras da tabela sales
retornam um subconjunto de linhas.
CREATE TABLE sales (region STRING, id INT)
WITH ROW FILTER us_filter ON (region);
Aplicar uma máscara de coluna
Para aplicar uma máscara de coluna, crie uma função (UDF) e aplique-a a uma coluna da tabela.
Você pode aplicar uma máscara de coluna com o Catalog Explorer ou os comandos SQL. As instruções do Catalog Explorer pressupõem que você já tenha criado uma função e que ela esteja registrada no Unity Catalog. As instruções SQL incluem exemplos de como criar uma função de máscara de coluna e aplicá-la a uma coluna de tabela.
No seu workspace do Databricks, clique em Catálogo.
Navegue ou pesquise a tabela.
Na guia Visão geral, localize a linha à qual você deseja aplicar a máscara de coluna e clique no ícone de edição de máscara.
Na caixa de diálogo Adicionar máscara de coluna, selecione o catálogo e o esquema que contêm a função de filtro e, em seguida, selecione a função.
Na caixa de diálogo expandida, consulte a definição da função. Se a função contiver outros parâmetros além da coluna que estiver sendo mascarada, selecione as colunas da tabela para as quais deseja converter esses parâmetros adicionais da função.
Clique em Adicionar.
Para remover a máscara de coluna da tabela, clique em fx Column mask (Máscara de coluna ) na linha da tabela e clique em Remove (Remover).
Para criar uma máscara de coluna e adicioná-la a uma coluna de tabela existente, use CREATE FUNCTION
e aplique a função de mascaramento utilizando ALTER TABLE
. Você também pode aplicar uma função ao criar uma tabela utilizando CREATE TABLE
.
Use SET MASK
para aplicar a função de mascaramento. Na cláusula MASK
, você pode usar qualquer uma das funções de tempo de execução integradas do Databricks ou chamar outras funções definidas pelo usuário. Casos de uso comuns incluem inspecionar a identidade do usuário que está invocando a função utilizando current_user( )
ou obter os grupos dos quais ele é membro utilizando is_account_group_member( )
. Para obter detalhes, consulte Cláusula de máscara de coluna e Funções integradas.
Criar uma máscara de coluna:
CREATE FUNCTION <function_name> (<parameter_name> <parameter_type>, ...) RETURN {expression with the same type as the first parameter};
Aplique a máscara de coluna a uma coluna em uma tabela existente:
ALTER TABLE <table_name> ALTER COLUMN <col_name> SET MASK <mask_func_name> USING COLUMNS <additional_columns>;
**Exemplos adicionais de sintaxe**:
Aplique a máscara de coluna a uma coluna em uma tabela existente usando um literal constante que corresponda a um parâmetro de função:
ALTER TABLE <table_name> ALTER COLUMN <col_name> SET MASK <mask_func_name> USING COLUMNS (<constant_name>, ...);
Remover uma máscara de coluna de uma coluna em uma tabela:
ALTER TABLE <table_name> ALTER COLUMN <column where mask is applied> DROP MASK;
Modifique uma máscara de coluna:
DROP
na função existente ou useCREATE OR REPLACE TABLE
.Excluir máscara da coluna:
ALTER TABLE <table_name> ALTER COLUMN <column where mask is applied> DROP MASK; DROP FUNCTION <function_name>;
Observação
Você deve executar o comando
ALTER TABLE
antes de descartar a função ou a tabela ficará em um estado inacessível.Se a tabela ficar inacessível dessa forma, altere a tabela e elimine a referência da máscara órfã usando
ALTER TABLE <table_name> ALTER COLUMN <column where mask is applied> DROP MASK;
.
Exemplos de máscara de coluna
Neste exemplo, você cria uma função definida pelo usuário que mascara a coluna ssn
para que somente usuários que são membros do grupo HumanResourceDept
possam visualizar valores nessa coluna.
CREATE FUNCTION ssn_mask(ssn STRING)
RETURN CASE WHEN is_member('HumanResourceDept') THEN ssn ELSE '***-**-****' END;
Aplique a nova função a uma tabela como uma máscara de coluna. Você pode adicionar a máscara de coluna ao criar a tabela ou depois.
--Create the `users` table and apply the column mask in a single step:
CREATE TABLE users (
name STRING,
ssn STRING MASK ssn_mask);
--Create the `users` table and apply the column mask after:
CREATE TABLE users
(name STRING, ssn STRING);
ALTER TABLE users ALTER COLUMN ssn SET MASK ssn_mask;
As consultas nessa tabela agora retornam valores de coluna ssn
mascarados quando o usuário que consulta não é membro do grupo HumanResourceDept
:
SELECT * FROM users;
James ***-**-****
Para desativar a máscara de coluna para que as consultas retornem os valores originais na coluna ssn
:
ALTER TABLE users ALTER COLUMN ssn DROP MASK;
Use tabelas de mapeamento para criar uma lista de controle de acesso
Para obter segurança em nível de linha, considere definir uma tabela de mapeamento (ou lista de controle de acesso). Cada tabela de mapeamento é uma tabela de mapeamento abrangente que codifica quais linhas de dados na tabela original podem ser acessadas por determinados usuários ou grupos. As tabelas de mapeamento são úteis porque oferecem integração simples com suas tabelas de fatos por meio de junções diretas.
Essa metodologia se mostra benéfica para abordar muitos casos de uso com requisitos personalizados. Exemplos:
Impor restrições com base no usuário conectado e, ao mesmo tempo, acomodar regras diferentes para grupos de usuários específicos.
Criar hierarquias complexas, como estruturas organizacionais, que exigem diversos conjuntos de regras.
Replicação de modelos de segurança complexos de sistemas de origem externa.
Ao adotar tabelas de mapeamento dessa maneira, você pode lidar efetivamente com esses casos difíceis e garantir implementações de segurança robustas em nível de linha e coluna.
Exemplos de tabelas de mapeamento
Use uma tabela de mapeamento para verificar se o usuário atual está em uma lista:
USE CATALOG main;
Criar uma nova tabela de mapeamento:
DROP TABLE IF EXISTS valid_users;
CREATE TABLE valid_users(username string);
INSERT INTO valid_users
VALUES
('fred@databricks.com'),
('barney@databricks.com');
Criar um novo filtro:
Observação
Todos os filtros são executados com os direitos do definidor, exceto as funções que verificam o contexto do usuário (por exemplo, as funções CURRENT_USER
e IS_MEMBER
) que são executadas como invocador.
Neste exemplo, a função verifica se o usuário atual está na tabela valid_users
. Se o usuário for encontrado, a função retornará true.
DROP FUNCTION IF EXISTS row_filter;
CREATE FUNCTION row_filter()
RETURN EXISTS(
SELECT 1 FROM valid_users v
WHERE v.username = CURRENT_USER()
);
O exemplo abaixo aplica o filtro de linha durante a criação da tabela. Você também pode adicionar o filtro mais tarde utilizando uma instrução ALTER TABLE
. Ao aplicar a uma tabela inteira, use a sintaxe ON ()
. Para uma linha específica use ON (row);
.
DROP TABLE IF EXISTS data_table;
CREATE TABLE data_table
(x INT, y INT, z INT)
WITH ROW FILTER row_filter ON ();
INSERT INTO data_table VALUES
(1, 2, 3),
(4, 5, 6),
(7, 8, 9);
Selecione os dados da tabela. Isso só deve retornar dados se o usuário estiver na tabela valid_users
.
SELECT * FROM data_table;
Crie uma tabela de mapeamento com contas que sempre devem ter acesso para visualizar todas as linhas na tabela, independentemente dos valores das colunas:
CREATE TABLE valid_accounts(account string);
INSERT INTO valid_accounts
VALUES
('admin'),
('cstaff');
Agora crie uma UDF SQL que retorne true
se os valores de todas as colunas na linha forem menores que cinco ou se o usuário que faz a chamada for um membro da tabela de mapeamento acima.
CREATE FUNCTION row_filter_small_values (x INT, y INT, z INT)
RETURN (x < 5 AND y < 5 AND z < 5)
OR EXISTS(
SELECT 1 FROM valid_accounts v
WHERE IS_ACCOUNT_GROUP_MEMBER(v.account));
Finalmente, aplique o SQL UDF à tabela como um filtro de linha:
ALTER TABLE data_table SET ROW FILTER row_filter_small_values ON (x, y, z);
Suporte e limitações
Filtros de linha e máscaras de coluna não são suportados por todas as funcionalidades do Databricks ou em todos os recursos de computação. Esta seção lista as funcionalidades e limitações suportadas.
Recursos e formatos compatíveis
Essa lista de funcionalidades suportadas não é exaustiva. Alguns itens estão listados porque não eram compatíveis durante o pré-lançamento público.
Há suporte para Databricks SQL e notebooks Databricks para cargas de trabalho SQL.
Comandos DML por usuários com privilégios
MODIFY
são suportados. Filtros e máscaras são aplicados aos dados lidos por instruçõesUPDATE
eDELETE
e não são aplicados a dados gravados (incluindoINSERT
).Formatos de dados compatíveis:
Delta e Parquet para tabelas gerenciadas e externas.
Vários outros formatos de dados para tabelas estrangeiras registradas no Unity Catalog utilizando a Lakehouse Federation.
Os parâmetros de política podem incluir expressões constantes (strings, números, intervalos, booleanos, nulos).
As UDFs SQL, Python e Scala são suportadas como funções de filtro de linha ou máscara de coluna, desde que estejam registradas no Unity Catalog. UDFs Python e Scala devem ser encapsulados em uma UDF SQL.
Você pode criar exibições em tabelas que fazem referência a máscaras de coluna ou filtros de linha, mas não pode adicionar máscaras de coluna ou filtros de linha a uma exibição.
Os feeds de dados de alteração do Delta Lake são compatíveis, desde que o esquema seja compatível com os filtros de linha e as máscaras de coluna que se aplicam à tabela de destino.
Tabelas externas são suportadas.
A amostragem de tabela é suportada.
MERGE
as declarações são suportadas quando as tabelas de origem, as tabelas de destino ou ambas utilizam filtros de linha e máscaras de coluna. Isso inclui tabelas com funções de filtro de linha que contêm subconsultas simples, mas há limitações listadas na seção a seguir.
Considerações sobre o desempenho
Os filtros de linha e as máscaras de coluna garantem a visibilidade dos seus dados, assegurando que nenhum usuário possa visualizar o conteúdo dos valores das tabelas-base antes das operações de filtragem e mascaramento. Eles foram criados para ter um bom desempenho em resposta a consultas nos casos de uso mais comuns. Em aplicativos menos frequentes, nos quais o mecanismo de consulta precisa escolher entre otimizar o desempenho da consulta e oferecer proteção contra o vazamento de informações dos valores filtrados/mascarados, ele sempre tomará a decisão segura às custas de algum impacto no desempenho da consulta. Para minimizar esse impacto no desempenho, aplique os seguintes princípios:
Use funções de política simples: as funções de política com menos expressões geralmente têm um desempenho melhor do que expressões mais complexas. Evite usar tabelas de mapeamento e subconsultas de expressões, optando por funções CASE simples.
Reduza o número de argumentos das funções: o Databricks não é capaz de fazer otimizações retirando as referências a colunas da tabela de origem resultantes de argumentos de funções de política, mesmo que essas colunas não sejam usadas de outra forma na consulta. Use funções de política com menos argumentos, pois as consultas dessas tabelas geralmente terão melhor desempenho.
Evite adicionar filtros de linha com muitos conjuntos AND: como cada tabela só suporta a adição de no máximo um filtro de linha, uma abordagem comum é combinar várias funções de política desejadas com
AND
. Entretanto, em cada conjunto, aumentam as chances de que o(s) conjunto(s) inclua(m) componentes mencionados em outra parte dessa tabela que podem afetar o desempenho (como o uso de tabelas de mapeamento). Use menos conjuntos para melhorar o desempenho.Use expressões determinísticas que não possam gerar erros nas políticas da tabela e nas consultas a partir dessas tabelas: algumas expressões podem gerar erros se as entradas fornecidas forem inválidas, como a divisão ANSI. Nesses casos, o compilador SQL não deve empurrar as operações com essas expressões (como filtros) muito para baixo no plano de consulta, para evitar a possibilidade de erros como "divisão por zero", que revelam informações sobre valores anteriores antes da filtragem e/ou mascaramento. Use expressões que sejam determinísticas e nunca gerem erros, como
try_divide
neste exemplo.Execute consultas de teste em sua tabela para avaliar o desempenho: crie consultas realistas que representem a carga de trabalho esperada para a sua tabela com filtros de linha e/ou máscaras de coluna e meça o desempenho. Faça pequenas modificações nas funções da política e observe seus efeitos até alcançar um bom equilíbrio entre desempenho e expressividade da lógica de filtragem e mascaramento.
Limitações
As versões do Databricks Runtime abaixo da 12.2 LTS não oferecem suporte a filtros de linha nem a máscaras de coluna. Esses tempos de execução falham com segurança, o que significa que se você tentar acessar tabelas de versões não suportadas desses tempos de execução, nenhum dado será retornado.
O Delta Sharing não funciona com máscaras de segurança ou coluna em nível de linha.
Você não pode aplicar máscaras de segurança ou de coluna no nível da linha a uma exibição.
A viagem do tempo não funciona com segurança em nível de linha ou máscaras de coluna.
Não há suporte para o acesso baseado em caminho a arquivos em tabelas com políticas.
Não há suporte para políticas de filtro de linha nem máscara de coluna com dependências circulares em relação às políticas originais.
Clones profundos e rasos não são suportados.
MERGE
as declarações não são compatíveis com tabelas com políticas de filtro de linha que contenham aninhamento, agregações, janelas, limites ou funções não determinísticas.As APIs do Delta Lake não são suportadas.