Pular para o conteúdo principal

Utilize tabelas de mapeamento para controle de acesso dinâmico.

Este tutorial mostra como usar uma tabela de mapeamento para controlar o acesso em nível de linha e de coluna sem gerenciar um grande número de grupos. Uma única tabela de consulta controla tanto a filtragem de linhas quanto o mascaramento de colunas. As alterações de acesso exigem apenas uma atualização de linha. Você não precisa criar novos grupos nem reescrever as políticas.

Este tutorial também demonstra o mascaramento condicional: as colunas de informações pessoais identificáveis (PII) são mascaradas de forma diferente dependendo do valor de outra coluna na mesma linha. Os pedidos marcados com confidential têm suas informações pessoais totalmente ocultadas, independentemente do nível de autorização do usuário.

Para orientações gerais sobre o design de tabelas de mapeamento, consulte Usar tabelas de mapeamento para criar uma lista de controle de acesso.

Pré-requisitos

  • Databricks Runtime 16.4 ou superior, ou compute serverless .
  • Permissões de administrador da conta ou administrador workspace (para criar tags governadas).
  • MANAGE permissão no catálogo ou esquema de destino.
  • EXECUTE nas UDFs.
  • Um notebook SQL ou editor de consultas.

Cenário

Sua organização possui funcionários em quatro regiões (Leste dos EUA, Oeste dos EUA, UE, APAC) e quatro departamentos. Cada usuário deve ver apenas as linhas que correspondem à sua região e departamento, e as colunas PII devem ser mascaradas com base em dois fatores: o nível de autorização do usuário (full, masked ou none) armazenado em uma tabela de mapeamento e o order_priority do pedido.

Com uma abordagem baseada em grupos, você precisa de um grupo para cada combinação de região e departamento. Por exemplo, você precisa de 16 grupos, um para quatro regiões e outro para quatro departamentos. Adicionar níveis de autorização de informações pessoais identificáveis triplica essa importância. Cada nova região ou departamento exige novos grupos e atualizações de políticas.

A abordagem de tabela de mapeamento substitui isso por uma única tabela de consulta: uma linha por usuário, uma coluna por dimensão de acesso. Para alterar o acesso de um usuário, você atualiza uma linha.

o passo 1: Criar tagsgovernadas

Antes de executar qualquer SQL, crie as seguintes tags governadas na interface do usuário do Explorador de Catálogo ( Catálogo > Governança > Tags governadas > Criar taggovernada ):

keyde etiqueta

Valores permitidos

region

( tag somente key )

department

( tag somente key )

pii

name, email

priority

( tag somente key )

As tags region e department indicam à política de filtro de linha quais colunas devem ser passadas para a UDF de filtro. A tag pii informa às políticas de máscara de coluna quais colunas devem ser mascaradas e qual tipo de PII elas contêm. A tag priority permite que as políticas de máscara de coluna passem o valor order_priority para a UDF de máscara para mascaramento condicional.

atenção

Os dados das tags são armazenados como texto simples e podem ser replicados globalmente. Não utilize nomes tag , valores ou descritores que possam comprometer a segurança do seu recurso. Por exemplo, não utilize nomes tag , valores ou descritores que contenham informações pessoais ou sensíveis.

o passo 2: Criar dados de exemplo

Crie um catálogo, um esquema e uma tabela de pedidos. A coluna order_priority controla a máscara condicional: os pedidos marcados com confidential têm suas informações pessoais totalmente ocultadas, mesmo para usuários com alto nível de acesso.

SQL
CREATE CATALOG IF NOT EXISTS abac_tutorial;
USE CATALOG abac_tutorial;

CREATE SCHEMA IF NOT EXISTS mapping_demo;
USE SCHEMA mapping_demo;
SQL
CREATE OR REPLACE TABLE orders (
order_id INT,
customer_name STRING,
customer_email STRING,
sales_region STRING,
dept STRING,
amount DOUBLE,
order_date DATE,
order_priority STRING
);

INSERT INTO orders VALUES
(1, 'Acme Corp', 'orders@acme.com', 'us_east', 'engineering', 50000, '2025-01-15', 'standard'),
(2, 'Beta Inc', 'sales@beta.com', 'us_east', 'sales', 75000, '2025-02-01', 'confidential'),
(3, 'Gamma LLC', 'info@gamma.com', 'us_west', 'engineering', 30000, '2025-01-20', 'standard'),
(4, 'Delta Co', 'deals@delta.com', 'us_west', 'sales', 95000, '2025-03-01', 'confidential'),
(5, 'Epsilon GmbH', 'kontakt@epsilon.de', 'eu', 'engineering', 45000, '2025-02-15', 'standard'),
(6, 'Zeta SA', 'contact@zeta.fr', 'eu', 'sales', 62000, '2025-01-30', 'standard'),
(7, 'Eta Ltd', 'hello@eta.sg', 'apac', 'marketing', 28000, '2025-03-10', 'confidential'),
(8, 'Theta Corp', 'biz@theta.com', 'us_east', 'marketing', 55000, '2025-02-20', 'standard'),
(9, 'Iota KK', 'info@iota.jp', 'apac', 'engineering', 41000, '2025-01-25', 'standard'),
(10, 'Kappa Inc', 'sales@kappa.com', 'us_west', 'marketing', 33000, '2025-03-05', 'standard');

o passo 3: Aplicar tagsregulamentadas

Marque as colunas para que as políticas ABAC possam descobri-las automaticamente. A coluna order_priority é marcada com a tag de key-somente priority para que as políticas de máscara de coluna possam corresponder a ela por meio de MATCH COLUMNS e passar seu valor para a UDF de máscara.

SQL
ALTER TABLE abac_tutorial.mapping_demo.orders
ALTER COLUMN sales_region SET TAGS ('region' = '');
ALTER TABLE abac_tutorial.mapping_demo.orders
ALTER COLUMN dept SET TAGS ('department' = '');
ALTER TABLE abac_tutorial.mapping_demo.orders
ALTER COLUMN customer_name SET TAGS ('pii' = 'name');
ALTER TABLE abac_tutorial.mapping_demo.orders
ALTER COLUMN customer_email SET TAGS ('pii' = 'email');
ALTER TABLE abac_tutorial.mapping_demo.orders
ALTER COLUMN order_priority SET TAGS ('priority' = '');

o passo 4: Criar a tabela de mapeamento

Em vez de criar grupos para cada região, departamento e combinação de autorização, você mantém uma tabela com uma linha por usuário. A coluna pii_access controla como as colunas de PII (Informações Pessoais Identificáveis) são exibidas:

  • full — veja o valor real (para pedidos com prioridade padrão)
  • masked — veja um valor parcial como A*** ou o***@acme.com
  • none - ver ***REDACTED***

A coluna expires_on define uma data de expiração para cada entrada de acesso. Após essa data, a UDF de filtro de linha deixa de corresponder à entrada e o usuário perde o acesso silenciosamente, sem necessidade de revogação manual. Isso é útil para contratados, acordos temporários de compartilhamento de dados ou projetos com prazo determinado.

Se um usuário precisar de acesso a várias combinações de região e departamento, adicione linhas adicionais.

nota

Mantenha as tabelas de mapeamento pequenas e simples. Cada consulta em uma tabela protegida executa as UDFs de filtro de linha e máscara de coluna, que por sua vez consultam a tabela de mapeamento. Tabelas de mapeamento grandes e lógica UDF complexa podem afetar o desempenho das consultas. Utilize esquemas restritos e mantenha a lógica da UDF em uma única pesquisa sempre que possível.

SQL
CREATE OR REPLACE TABLE abac_tutorial.mapping_demo.user_access (
user_email STRING,
region STRING,
department STRING,
pii_access STRING,
expires_on DATE
);

INSERT INTO abac_tutorial.mapping_demo.user_access VALUES
(current_user(), 'us_east', 'engineering', 'masked', '2099-12-31'),
('bob@example.com', 'us_west', 'sales', 'full', '2099-12-31'),
('carol@example.com', 'eu', 'engineering', 'none', '2099-12-31'),
('david@example.com', 'apac', 'marketing', 'masked', '2099-12-31');

Passo 5: Crie a UDFde filtro de linha

Esta UDF recebe os valores sales_region e dept de uma linha (passados pela política através da correspondência tag ), procura o usuário atual na tabela de mapeamento e retorna TRUE somente se existir uma entrada correspondente e ela não tiver expirado. Usuários que não estão na tabela de mapeamento, ou cujo acesso expirou, não veem nenhuma linha (design de fechamento automático em caso de falha).

SQL
CREATE OR REPLACE FUNCTION abac_tutorial.mapping_demo.access_filter(
region_val STRING,
dept_val STRING
)
RETURNS BOOLEAN
RETURN EXISTS (
SELECT 1 FROM abac_tutorial.mapping_demo.user_access
WHERE user_email = current_user()
AND region = region_val
AND department = dept_val
AND expires_on >= current_date()
);

o passo 6: Criar a UDFde máscara de coluna

Esta UDF controla como as colunas de informações pessoais identificáveis (PII) são exibidas. São necessários três argumentos: o valor da coluna, o tipo PII ('name' ou 'email') e a linha order_priority. A lógica de mascaramento possui duas camadas:

  • Camada 1 (mascaramento condicional): Se order_priority for confidential, as informações pessoais identificáveis (PII) são sempre totalmente ocultadas, independentemente do nível de autorização do usuário.
  • Camada 2 (autorização do usuário): Para linhas padrão, a UDF verifica a tabela de mapeamento para o nível pii_access do usuário e aplica a máscara correspondente. Se um usuário tiver várias entradas na tabela de mapeamento (acesso a várias regiões), a autorização mais alta entre todas as linhas será aplicada.
SQL
CREATE OR REPLACE FUNCTION abac_tutorial.mapping_demo.pii_mask(
val STRING,
pii_type STRING,
order_pri STRING
)
RETURNS STRING
RETURN CASE
WHEN order_pri = 'confidential' THEN '***REDACTED***'
WHEN EXISTS (
SELECT 1 FROM abac_tutorial.mapping_demo.user_access
WHERE user_email = current_user() AND pii_access = 'full'
) THEN val
WHEN EXISTS (
SELECT 1 FROM abac_tutorial.mapping_demo.user_access
WHERE user_email = current_user() AND pii_access = 'masked'
) THEN
CASE pii_type
WHEN 'email' THEN CONCAT(LEFT(val, 1), '***@', SUBSTRING_INDEX(val, '@', -1))
WHEN 'name' THEN CONCAT(LEFT(val, 1), '***')
ELSE CONCAT(LEFT(val, 1), '***')
END
ELSE '***REDACTED***'
END;

o passo 7: Criar as políticas

Crie três políticas, todas baseadas na mesma tabela de mapeamento. Ambas as políticas de máscara de coluna usam a mesma função pii_mask . O argumento pii_type informa à função qual estilo de máscara aplicar, portanto você não precisa de uma UDF separada para cada tipo de coluna.

A tag governada priority é usada em MATCH COLUMNS para corresponder à coluna order_priority e passar seu valor para a UDF de máscara como order_pri. É assim que o mascaramento condicional é implementado: a política passa o valor de prioridade da linha para a UDF no momento da consulta.

SQL
CREATE POLICY user_access_filter
ON SCHEMA abac_tutorial.mapping_demo
ROW FILTER abac_tutorial.mapping_demo.access_filter
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag('region') AS r, has_tag('department') AS d
USING COLUMNS (r, d);
SQL
CREATE POLICY pii_mask_name
ON SCHEMA abac_tutorial.mapping_demo
COLUMN MASK abac_tutorial.mapping_demo.pii_mask
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag_value('pii', 'name') AS m,
has_tag('priority') AS pri
ON COLUMN m
USING COLUMNS ('name', pri);

CREATE POLICY pii_mask_email
ON SCHEMA abac_tutorial.mapping_demo
COLUMN MASK abac_tutorial.mapping_demo.pii_mask
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag_value('pii', 'email') AS m,
has_tag('priority') AS pri
ON COLUMN m
USING COLUMNS ('email', pri);

o passo 8: Verifique os resultados

Sua entrada na tabela de mapeamento lhe dá acesso a us_east / engineering com autorização masked . Execute a seguinte consulta para verificar se você vê apenas o pedido nº 1, com as informações pessoais parcialmente mascaradas.

SQL
SELECT * FROM abac_tutorial.mapping_demo.orders;

O pedido nº 1 tem order_priority = 'standard', portanto, sua folga de masked se aplica.

Resultado esperado para o seu usuário:

id_do_pedido

nome_do_cliente

e-mail do cliente

região_de_vendas

departamento

quantia

data_do_pedido

prioridade_do_pedido

1

A***

o***@acme.com

leste dos EUA

engenharia

50000

2025-01-15

Standard

O que outros usuários veem:

Usuário

Ordens visíveis

prioridade_do_pedido

Comportamento PII

bob@example.com (full autorização)

#4 (us_west, vendas)

confidencial

***REDACTED*** — autorizações confidenciais full

carol@example.com (none autorização)

#5 (UE, engenharia)

Standard

***REDACTED***none significa redação completa

david@example.com (masked autorização)

#7 (APAC, marketing)

confidencial

***REDACTED*** — autorizações confidenciais masked

(proprietário do catálogo)

Todos os 10

Todos sem máscara (o proprietário está isento das políticas).

(usuário não listado)

Nenhuma

O filtro de linhas não retorna nenhuma linha.

Observe que Bob tem folga full , mas ainda vê ***REDACTED*** porque o pedido nº 4 é confidential. Isso é mascaramento condicional: o valor de prioridade da linha substitui a autorização do usuário.

o passo 9: Atualizar o acesso dinamicamente

A key vantagem da abordagem de tabela de mapeamento é que você pode alterar o acesso atualizando as linhas da tabela. Você não precisa atualizar políticas, UDFs ou associações de grupo.

Reatribuir a um departamento diferente

Mude seu departamento de engineering para sales. O pedido nº 2 (Beta Inc) é um pedido de confidential vendas, portanto, suas informações pessoais são totalmente redigidas mesmo com a autorização masked .

SQL
UPDATE abac_tutorial.mapping_demo.user_access
SET department = 'sales'
WHERE user_email = current_user();

execute a seguinte consulta para verificar. Você deverá ver o pedido nº 2 com ***REDACTED*** PII.

SQL
SELECT * FROM abac_tutorial.mapping_demo.orders;

Reverter a alteração:

SQL
UPDATE abac_tutorial.mapping_demo.user_access
SET department = 'engineering'
WHERE user_email = current_user();

Atualização da autorização PII

Altere sua folga de masked para full. Para as linhas de prioridade padrão, agora você vê os valores reais de PII (Informações Pessoais Identificáveis).

SQL
UPDATE abac_tutorial.mapping_demo.user_access
SET pii_access = 'full'
WHERE user_email = current_user();

execute a seguinte consulta para verificar. O pedido nº 1 tem prioridade standard , portanto, com a autorização full você deverá ver Acme Corp e orders@acme.com.

SQL
SELECT * FROM abac_tutorial.mapping_demo.orders;

Reverter a alteração:

SQL
UPDATE abac_tutorial.mapping_demo.user_access
SET pii_access = 'masked'
WHERE user_email = current_user();

Conceder acesso a uma região adicional

Insira uma segunda linha para conceder acesso à engenharia da UE. Não são necessários novos grupos ou políticas.

SQL
INSERT INTO abac_tutorial.mapping_demo.user_access
VALUES (current_user(), 'eu', 'engineering', 'masked', '2099-12-31');

execute a seguinte consulta para verificar. Agora você deverá ver tanto o pedido nº 1 (us_east, engenharia) quanto o pedido nº 5 (eu, engenharia), com as informações pessoais parcialmente ocultadas.

SQL
SELECT * FROM abac_tutorial.mapping_demo.orders;

Remova o acesso adicional:

SQL
DELETE FROM abac_tutorial.mapping_demo.user_access
WHERE user_email = current_user() AND region = 'eu';

Acesso expirado

Defina sua entrada de acesso para uma data passada. O filtro UDF de linha verifica expires_on >= current_date(), portanto, as entradas expiradas são ignoradas silenciosamente e o acesso é revogado automaticamente. Isso é útil para contratados, acordos de compartilhamento de dados com duração fixa ou projetos com prazo determinado.

SQL
UPDATE abac_tutorial.mapping_demo.user_access
SET expires_on = current_date() - INTERVAL 1 DAY
WHERE user_email = current_user();

Execute a seguinte consulta para verificar se você não vê nenhuma linha.

SQL
SELECT * FROM abac_tutorial.mapping_demo.orders;

Restaurar o acesso com uma data de expiração futura:

SQL
UPDATE abac_tutorial.mapping_demo.user_access
SET expires_on = '2099-12-31'
WHERE user_email = current_user();

Execute a seguinte consulta para verificar se o acesso foi restaurado.

SQL
SELECT * FROM abac_tutorial.mapping_demo.orders;

Resumo

Este tutorial demonstrou três padrões:

  • Padrão de tabela de mapeamento : uma única tabela de pesquisa controla tanto a filtragem de linhas quanto o mascaramento de colunas. As alterações de acesso são feitas atualizando as linhas, sem necessidade de alterações de política ou grupo.
  • Mascaramento condicional : a UDF de máscara verifica a coluna order_priority em cada linha para decidir como mascarar PII. As linhas confidenciais são sempre totalmente redigidas, independentemente do nível de autorização do usuário, implementado por tags order_priority e passando-as para a UDF via MATCH COLUMNS.
  • Expiração de acesso : a tabela de mapeamento inclui uma data expires_on . O filtro UDF de linha verifica esta data em relação a current_date(), portanto, as entradas expiradas são ignoradas silenciosamente e o acesso é revogado automaticamente sem intervenção manual.

Limpar

Para remover todos os objetos criados neste tutorial, execute o seguinte comando.

SQL
DROP POLICY user_access_filter ON SCHEMA abac_tutorial.mapping_demo;
DROP POLICY pii_mask_name ON SCHEMA abac_tutorial.mapping_demo;
DROP POLICY pii_mask_email ON SCHEMA abac_tutorial.mapping_demo;
DROP FUNCTION IF EXISTS abac_tutorial.mapping_demo.access_filter;
DROP FUNCTION IF EXISTS abac_tutorial.mapping_demo.pii_mask;
DROP TABLE IF EXISTS abac_tutorial.mapping_demo.orders;
DROP TABLE IF EXISTS abac_tutorial.mapping_demo.user_access;
DROP SCHEMA IF EXISTS abac_tutorial.mapping_demo CASCADE;

Para remover as tags governadas por region, department, pii e priority , use a interface do usuário do Explorador de Catálogo.