Implementar mascaramento de colunas em múltiplos domínios com níveis de sensibilidade.
Este tutorial mostra como implementar mascaramento de colunas com reconhecimento de domínio e níveis de sensibilidade, combinado com filtragem de linhas baseada em região. Você usa condições AND em MATCH COLUMNS para coluna de destino por domínio e nível de sensibilidade, e cláusulas EXCEPT para isentar o grupo proprietário de cada domínio da política de máscara correspondente.
Pré-requisitos
- Databricks Runtime 16.4 ou superior, ou compute serverless .
- Permissões de administrador da conta ou administrador workspace (para criar tags governadas).
MANAGEpermissão no catálogo ou esquema de destino.EXECUTEnas UDFs.- Grupos de contas:
hr_team,finance_team,marketing_team,us_team,eu_team.
Para criar os grupos necessários, acesse Configurações do espaço de trabalho > Identidade e acesso > Grupos , clique em Adicionar grupo e crie cada um deles. Adicione-se pelo menos a hr_team e us_team para seguir a perspectiva de RH + EUA na etapa 7.
Cenário
Sua organização mantém uma tabela central employee_records compartilhada entre RH, Finanças e marketing. Cada equipe é proprietária de determinadas colunas e deve visualizar seus próprios dados sem máscara, mas não deve visualizar os dados confidenciais de outras equipes.
O tutorial usa uma tag governada chamada domain para representar qual equipe é proprietária de cada coluna. O nome é arbitrário. Você também pode usar team, department ou business_unit. A ideia key é que cada coluna é atribuída a exatamente um grupo proprietário, e uma segunda tag sensitivity controla o quão agressivamente os dados são mascarados para usuários fora desse grupo.
Coluna |
|
| Grupo autorizado |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
O comportamento de mascaramento depende do nível de sensibilidade:
- Interno : usuários fora do grupo proprietário veem uma máscara parcial (primeiro caractere +
***). - Confidencial : usuários fora do grupo proprietário veem
***REDACTED***.
Usuários em múltiplos grupos de domínio visualizam todas as colunas de seus domínios sem máscara.
o passo 1: Criar tagsgovernadas
Crie as seguintes tags controladas na interface do usuário do Explorador de Catálogo ( Catálogo > Controle > Etiquetas controladas > Criar tagcontrolada ):
keyde etiqueta | Valores permitidos |
|---|---|
| ( tag somente key ) |
|
|
|
|
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 uma única tabela employee_records compartilhada entre RH, Finanças e Marketing. Cada coluna sensível será marcada com um nível domain e um nível sensitivity no próximo passo.
CREATE CATALOG IF NOT EXISTS abac_tutorial;
USE CATALOG abac_tutorial;
CREATE SCHEMA IF NOT EXISTS domain_demo;
USE SCHEMA domain_demo;
CREATE OR REPLACE TABLE employee_records (
id INT,
employee_name STRING,
ssn STRING,
email STRING,
customer_list STRING,
cost_center STRING,
salary_band STRING,
emp_region STRING,
department STRING
);
INSERT INTO employee_records VALUES
(1, 'Alice Johnson', '123-45-6789', 'alice@acme.com', 'Tier-1 Enterprise', 'CC-4010', 'Band 7', 'us', 'Engineering'),
(2, 'Bob Smith', '234-56-7890', 'bob@acme.com', 'SMB Accounts', 'CC-3020', 'Band 5', 'us', 'Sales'),
(3, 'Carol White', '345-67-8901', 'carol@acme.com', 'Tier-1 Enterprise', 'CC-5010', 'Band 8', 'eu', 'Engineering'),
(4, 'David Lee', '456-78-9012', 'david@acme.com', 'Growth Segment', 'CC-2010', 'Band 4', 'eu', 'Marketing'),
(5, 'Eva Martinez', '567-89-0123', 'eva@acme.com', 'Mid-Market', 'CC-4020', 'Band 6', 'us', 'HR');
o passo 3: Aplicar tagsregulamentadas
Marque cada coluna sensível com seus valores domain e sensitivity . Essas duas tags juntas permitem que cada política vise uma combinação específica de domínio e sensibilidade usando condições AND em MATCH COLUMNS. A coluna emp_region recebe uma tag region somente keyporque a política só precisa identificar a coluna em vez de verificar um valor específico.
-- HR domain
ALTER TABLE employee_records
ALTER COLUMN employee_name SET TAGS ('domain' = 'hr', 'sensitivity' = 'internal');
ALTER TABLE employee_records
ALTER COLUMN ssn SET TAGS ('domain' = 'hr', 'sensitivity' = 'confidential');
-- Marketing domain
ALTER TABLE employee_records
ALTER COLUMN email SET TAGS ('domain' = 'marketing', 'sensitivity' = 'internal');
ALTER TABLE employee_records
ALTER COLUMN customer_list SET TAGS ('domain' = 'marketing', 'sensitivity' = 'confidential');
-- Finance domain
ALTER TABLE employee_records
ALTER COLUMN cost_center SET TAGS ('domain' = 'finance', 'sensitivity' = 'internal');
ALTER TABLE employee_records
ALTER COLUMN salary_band SET TAGS ('domain' = 'finance', 'sensitivity' = 'confidential');
-- Region tag for row filtering
ALTER TABLE employee_records
ALTER COLUMN emp_region SET TAGS ('region' = '');
o passo 4: Criar as UDFs
A UDF de filtro de linha aceita o valor da região da linha e uma região permitida como argumento estático e retorna TRUE quando eles correspondem. Passar a região permitida como uma constante mantém a UDF simples e reutilizável. Cada política de filtro de linha tem como alvo um grupo específico e repassa a região que esse grupo está autorizado a visualizar.
CREATE OR REPLACE FUNCTION abac_tutorial.domain_demo.region_filter(region_val STRING, allowed_region STRING)
RETURNS BOOLEAN
RETURN region_val = allowed_region;
Crie uma UDF de máscara parcial para colunas internas e uma UDF de redação completa para colunas confidenciais.
CREATE OR REPLACE FUNCTION abac_tutorial.domain_demo.partial_mask(val STRING)
RETURNS STRING
RETURN CONCAT(LEFT(val, 1), '***');
CREATE OR REPLACE FUNCTION abac_tutorial.domain_demo.redact(val STRING)
RETURNS STRING
RETURN '***REDACTED***';
o passo 5: Criar as políticas de filtro de linha
Crie uma política de filtro de linha por região. Cada política visa um grupo específico e passa a região permitida como uma constante através de USING COLUMNS.
CREATE POLICY region_filter_us
ON SCHEMA abac_tutorial.domain_demo
ROW FILTER abac_tutorial.domain_demo.region_filter
TO `us_team`
FOR TABLES
MATCH COLUMNS has_tag('region') AS region_col
USING COLUMNS (region_col, 'us');
CREATE POLICY region_filter_eu
ON SCHEMA abac_tutorial.domain_demo
ROW FILTER abac_tutorial.domain_demo.region_filter
TO `eu_team`
FOR TABLES
MATCH COLUMNS has_tag('region') AS region_col
USING COLUMNS (region_col, 'eu');
Uma alternativa é incorporar a lógica do grupo dentro da UDF usando funções de identidade como is_account_group_member(). Essa abordagem utiliza uma política única sem valores estáticos, mas move o mapeamento de grupo para região para a UDF (Função Definida pelo Usuário). Use a opção que melhor se adequar à sua organização.
o passo 6: Criar as políticas de máscara de coluna de domínio
Crie uma política para cada combinação de domínio e nível de sensibilidade. Cada política usa AND para corresponder colunas com um nível específico domain AND sensitivity e EXCEPT para isentar o grupo de domínio proprietário.
interno ( | confidencial ( | |
|---|---|---|
RH |
|
|
Finanças |
|
|
Marketing |
|
|
Como cada coluna tem exatamente um valor domain e um valor sensitivity , cada coluna corresponde a exatamente uma política por usuário. Não há conflitos.
Colunas internas (máscara parcial)
Aplicar uma máscara parcial às colunas de nível interno para usuários fora do domínio proprietário.
CREATE POLICY mask_internal_hr
ON SCHEMA abac_tutorial.domain_demo
COLUMN MASK abac_tutorial.domain_demo.partial_mask
TO `account users` EXCEPT `hr_team`
FOR TABLES
MATCH COLUMNS (
has_tag_value('domain', 'hr')
AND has_tag_value('sensitivity', 'internal')
) AS m
ON COLUMN m;
CREATE POLICY mask_internal_finance
ON SCHEMA abac_tutorial.domain_demo
COLUMN MASK abac_tutorial.domain_demo.partial_mask
TO `account users` EXCEPT `finance_team`
FOR TABLES
MATCH COLUMNS (
has_tag_value('domain', 'finance')
AND has_tag_value('sensitivity', 'internal')
) AS m
ON COLUMN m;
CREATE POLICY mask_internal_marketing
ON SCHEMA abac_tutorial.domain_demo
COLUMN MASK abac_tutorial.domain_demo.partial_mask
TO `account users` EXCEPT `marketing_team`
FOR TABLES
MATCH COLUMNS (
has_tag_value('domain', 'marketing')
AND has_tag_value('sensitivity', 'internal')
) AS m
ON COLUMN m;
Colunas confidenciais (redação completa)
Redija completamente as colunas de nível confidencial para usuários fora do domínio proprietário.
CREATE POLICY mask_confidential_hr
ON SCHEMA abac_tutorial.domain_demo
COLUMN MASK abac_tutorial.domain_demo.redact
TO `account users` EXCEPT `hr_team`
FOR TABLES
MATCH COLUMNS (
has_tag_value('domain', 'hr')
AND has_tag_value('sensitivity', 'confidential')
) AS m
ON COLUMN m;
CREATE POLICY mask_confidential_finance
ON SCHEMA abac_tutorial.domain_demo
COLUMN MASK abac_tutorial.domain_demo.redact
TO `account users` EXCEPT `finance_team`
FOR TABLES
MATCH COLUMNS (
has_tag_value('domain', 'finance')
AND has_tag_value('sensitivity', 'confidential')
) AS m
ON COLUMN m;
CREATE POLICY mask_confidential_marketing
ON SCHEMA abac_tutorial.domain_demo
COLUMN MASK abac_tutorial.domain_demo.redact
TO `account users` EXCEPT `marketing_team`
FOR TABLES
MATCH COLUMNS (
has_tag_value('domain', 'marketing')
AND has_tag_value('sensitivity', 'confidential')
) AS m
ON COLUMN m;
o passo 7: Verifique os resultados
Todas as sete políticas (dois filtros de linha e seis máscaras de coluna) estão agora ativas. Execute a seguinte consulta e verifique se os resultados correspondem ao que sua associação ao grupo permite.
SELECT * FROM abac_tutorial.domain_demo.employee_records;
Membro da equipe de RH na região dos EUA (hr_team + us_team):
| id | nome_do_funcionário | ssn | email | lista_de_clientes | centro_de_custo | faixa_salário | região_do_funcionário | departamento |
| -- | -------------- | ----------- | ------ | -------------------- | ------------ | -------------------- | ----------- | ----------- |
| 1 | Alice Johnson | 123-45-6789 | a*** | ***REDACTED*** | C*** | ***REDACTED*** | nós | engenharia |
| 2 | Bob Smith | 234-56-7890 | b*** | ***REDACTED*** | C*** | ***REDACTED*** | nós | vendas |
| 5 | Eva Martinez | 567-89-0123 | e*** | ***REDACTED*** | C*** | ***REDACTED*** | nós | RH |
As colunas HR (employee_name, ssn) são desmascaradas. O marketing interno (email) está parcialmente mascarado e o confidencial (customer_list) está redigido. As informações financeiras internas (cost_center) estão parcialmente mascaradas e as informações confidenciais (salary_band) estão redigidas.
Membro da equipe de finanças na região da UE (finance_team + eu_team):
| id | nome_do_funcionário | ssn | email | lista_de_clientes | centro_de_custo | faixa_salário | região_do_funcionário | departamento |
| -- | -------------- | -------------------- | ------ | -------------------- | ------------ | ------------ | ----------- | ----------- |
| 3 | C*** | ***REDACTED*** | c*** | ***REDACTED*** | CC-5010 | Banda 8 | eu | engenharia |
| 4 | D*** | ***REDACTED*** | d*** | ***REDACTED*** | CC-2010 | Banda 4 | eu | marketing |
As colunas de finanças (cost_center, salary_band) são desmascaradas. Todas as outras colunas de domínio estão mascaradas ou ocultadas.
Usuário em hr_team + marketing_team + us_team:
| id | nome_do_funcionário | ssn | email | lista_de_clientes | centro_de_custo | faixa_salário | região_do_funcionário | departamento |
| -- | -------------- | ----------- | ---------------------------------------- | ----------------- | ------------ | -------------------- | ----------- | ----------- |
| 1 | Alice Johnson | 123-45-6789 | alice@acme.com | Empresa de Nível 1 | C*** | ***REDACTED*** | nós | engenharia |
As colunas de RH e marketing estão visíveis porque o usuário pertence a ambos os grupos. As colunas de finanças permanecem ocultas.
Por que esse padrão funciona
Cada coluna tem exatamente um valor domain e um valor sensitivity , portanto, cada coluna corresponde a exatamente uma política por usuário. Não existem conflitos de política.
A cláusula EXCEPT é a key. Cada política se aplica a account users exceto ao grupo de domínio que possui essas colunas. Se você faz parte do grupo proprietário, a política não se aplica e você vê os dados brutos. Caso contrário, a política se aplica e os dados são mascarados. Usuários de múltiplos grupos se beneficiam naturalmente: um usuário em hr_team e marketing_team é excluído de ambos os conjuntos de políticas de RH e marketing.
Adicionar um novo domínio (por exemplo, Jurídico) requer:
- Um novo grupo (
legal_team). - Um novo valor permitido
legalpara a tagdomain. - Duas novas políticas (
mask_internal_legal,mask_confidential_legal). - etiquetas nas novas colunas.
Não é necessário alterar as políticas existentes.
Limpar
Para remover todos os objetos criados neste tutorial, execute o seguinte comando.
DROP POLICY region_filter_us ON SCHEMA abac_tutorial.domain_demo;
DROP POLICY region_filter_eu ON SCHEMA abac_tutorial.domain_demo;
DROP POLICY mask_internal_hr ON SCHEMA abac_tutorial.domain_demo;
DROP POLICY mask_internal_finance ON SCHEMA abac_tutorial.domain_demo;
DROP POLICY mask_internal_marketing ON SCHEMA abac_tutorial.domain_demo;
DROP POLICY mask_confidential_hr ON SCHEMA abac_tutorial.domain_demo;
DROP POLICY mask_confidential_finance ON SCHEMA abac_tutorial.domain_demo;
DROP POLICY mask_confidential_marketing ON SCHEMA abac_tutorial.domain_demo;
DROP FUNCTION IF EXISTS abac_tutorial.domain_demo.region_filter;
DROP FUNCTION IF EXISTS abac_tutorial.domain_demo.partial_mask;
DROP FUNCTION IF EXISTS abac_tutorial.domain_demo.redact;
DROP TABLE IF EXISTS abac_tutorial.domain_demo.employee_records;
DROP SCHEMA IF EXISTS abac_tutorial.domain_demo CASCADE;
Para remover as tags governadas region, domain e sensitivity e os grupos account (hr_team, finance_team, marketing_team, us_team, eu_team), use a interface do usuário do Explorador de Catálogo e as configurações workspace , respectivamente.