Usar o RBAC com o ABAC

Importante

O RBAC está em Visualização Pública. O ABAC está disponível em geral. Esta página descreve como os dois funcionam juntos.

O RBAC (controle de acesso baseado em função) e o ABAC (controle de acesso baseado em atributo) no Catálogo do Unity são controles complementares projetados para trabalhar em conjunto. Eles respondem a perguntas diferentes:

  • RBAC define qual identidade um usuário assume em uma sessão. Um usuário assume uma função para agir com as permissões dessa função em vez de suas próprias. Use RBAC para conceder a um usuário vários conjuntos distintos de permissões entre os quais ele alterna explicitamente — por exemplo, separando o acesso entre ensaios clínicos, projetos ou níveis de sensibilidade.
  • O ABAC controla quais dados a identidade ativa pode ver, linha por linha ou coluna por coluna. As políticas são anexadas aos dados por meio de marcas governadas e se aplicam a qualquer identidade que execute a consulta. Use o ABAC para filtragem ou mascaramento consistente em várias tabelas controladas por atributos de dados.

O RBAC define a identidade ativa da sessão e o ABAC avalia suas políticas em relação a essa identidade. Esta página aborda como essa interação é executada na prática, o comportamento das funções SQL relacionadas à identidade e os padrões de uso combinado.

Como as funções de identidade se comportam ao assumir uma função

As funções SQL relacionadas à identidade do Unity Catalog são avaliadas com base na identidade ativa da sessão, não no usuário autenticado subjacente. Quando um usuário assume uma função, a identidade da sessão ativa se torna a função:

Função Quando o usuário age como sua identidade de usuário Quando o usuário assume uma função
current_user() Retorna o nome de usuário do usuário Retorna o nome da função assumida
is_member(group) Retorna true se o usuário for membro do grupo (um grupo local do espaço de trabalho ou um grupo da conta atribuído ao espaço de trabalho) Retorna true somente se a função assumida for um membro de group. Retorna false para grupos dos quais o usuário subjacente faz parte, mas dos quais a função assumida não faz parte.
is_account_group_member(group) Retorna true se o usuário for um membro do grupo no nível da conta O mesmo que is_member: retorna true apenas com base nas associações de grupo da função assumida, não nas do usuário subjacente.

As políticas abac que fazem referência a essas funções são avaliadas em relação à função assumida, não ao usuário. A função assumida é a identidade ativa para avaliação de política ABAC, resolução de permissões do Unity Catalog e atribuição para auditoria. Como resultado, assumir um papel altera o comportamento das políticas e visualizações existentes que foram criadas em torno da identidade de cada usuário.

Note

Uma função não é automaticamente um membro de si mesma. Quando um usuário assume o papel G, current_user() retorna G, mas is_member('G') e is_account_group_member('G') retornam false, a menos que G tenha sido explicitamente adicionado como membro de si mesmo. Para corresponder à função presumida em uma política, compare com current_user() em vez de testar o pertencimento com is_member ou is_account_group_member.

Armadilha comum: visões de segurança em nível de linha criadas em current_user()

Um padrão comum em ABAC e filtros de linha no nível da tabela é filtrar linhas fazendo uma junção com uma tabela de provisionamento (também chamada de tabela de mapeamento ou lista de controle de acesso) indexada pelo nome de usuário retornado por current_user(). Por exemplo:

CREATE OR REPLACE FUNCTION facility_filter(facility_id STRING)
RETURN EXISTS (
  SELECT 1
  FROM governance.user_facility_provisioning p
  WHERE p.user = current_user()
    AND p.facility_id = facility_id
);

Quando o mesmo usuário assume uma função, current_user() não retorna mais seu nome de usuário. Retorna o nome da função. Como a função não está na tabela de provisionamento, o filtro não retorna nenhuma linha e o usuário parece perder o acesso aos dados que lhe foram concedidos.

Adicionar a função à tabela de provisionamento

Trate a função como outro principal em seus dados de provisionamento: insira uma linha para cada função com as unidades (ou outros atributos) às quais a função deve ter acesso. Em seguida, o filtro verifica se a identidade ativa é o usuário ou o perfil assumido.

Padrões de uso combinado

Veja a seguir exemplos de como os clientes usam o RBAC e o ABAC juntos para resolver problemas reais de controle de acesso. Estes são pontos de partida, não receitas exaustivas.

Filtros de linha por projeto com base no perfil assumido

Filtrar linhas por projeto é uma necessidade comum em pesquisa clínica, marketing de contratos, consultoria de cliente e outras configurações em que uma equipe trabalha em vários projetos isolados. O exemplo a seguir usa ensaios clínicos, mas o padrão generaliza para qualquer isolamento de dados por projeto.

Uma organização de pesquisa clínica executa vários ensaios simultâneos, cada um em sua própria função de acesso. Marque cada tabela com o identificador do projeto. Os usuários veem apenas as linhas do projeto cuja função eles assumiram no momento.

Configuração:

  • As tabelas sob clinical_trials.* têm uma coluna project_id marcada com a chave da tag governed tagproject.
  • Cada projeto tem uma função de acesso correspondente chamada role-<project> (por exemplo, role-alpha, ). role-beta
  • Os usuários têm permissão Assume somente nas funções para projetos em que trabalham.

UDF para filtro de linha:

CREATE FUNCTION project_match(project_id STRING) RETURNS BOOLEAN
DETERMINISTIC
RETURN current_user() = CONCAT('role-', project_id);

Política:

CREATE POLICY per_project_row_filter
ON CATALOG clinical_trials
ROW FILTER project_match
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag('project') AS project
USING COLUMNS (project);

Essa UDF correlaciona a identidade ativa com o valor da tag project de cada linha, de modo que cláusulas direcionadas a principals, como TO / EXCEPT, não conseguem expressar isso — elas têm como alvo principals, não o conteúdo da linha. Como explica a orientação sobre direcionamento por entidade de segurança, prefira TO / EXCEPT para o escopo simples por entidade de segurança e reserve funções de identidade dentro de uma UDF para casos como este, em que uma única regra depende tanto da identidade ativa quanto do conteúdo da linha.

Uma única política se aplica a todos os projetos: USING COLUMNS (project) passa o valor da tag project de cada linha à UDF, para que você não precise de uma política separada para cada projeto. Para a forma geral dessa técnica — controlar o acesso às linhas com base em uma tabela de consulta, em vez de correspondência de nomes de função — consulte Usar tabelas de mapeamento para controle de acesso dinâmico.

Comportamento:

  • Um usuário agindo com a própria identidade de usuário não vê nenhuma linha em nenhuma tabela clinical_trials. current_user() retorna seu nome de usuário, que nunca corresponde ao role-* padrão de nomenclatura. Essa é a negação padrão pretendida.
  • Um usuário que assume role-alpha vê apenas as linhas em que project_id é igual a alpha. Mudar para role-beta troca os dados visíveis sem refazer nenhuma outra consulta.

Mascaramento de PII menos rigoroso para usuários que exercem uma função designada

Por padrão, as colunas PII (SSN, email, telefone) aparecem mascaradas para todos. Para ver os valores brutos, um usuário deve assumir explicitamente uma função designada com autorização para acessar PII. Os logs de auditoria registram o evento de assunção de função, de modo que "eu precisava consultar a PII real" se torne uma adesão explícita passível de auditoria, em vez de uma permissão implícita.

Configuração:

  • Colunas confidenciais são marcadas com a chave governed tagpii (valores permitidos, como ssn, email, phone).
  • Uma função de acesso chamada role-pii-cleared Assume é concedida aos usuários autorizados a visualizar dados brutos de PII.

UDF de máscara de coluna (estática — a política define quais identidades mascarar):

CREATE FUNCTION mask_pii(val STRING) RETURNS STRING
DETERMINISTIC
RETURN '***';

Política:

CREATE POLICY pii_default_mask
ON CATALOG customer_data
COLUMN MASK mask_pii
TO `account users`
EXCEPT `role-pii-cleared`
FOR TABLES
MATCH COLUMNS has_tag('pii') AS pii_col
ON COLUMN pii_col;

A cláusula EXCEPT exclui role-pii-cleared da política por completo, de modo que a UDF nunca é invocada quando esse papel é a identidade ativa. Consulte Prefer TO/EXCEPT para direcionamento principal para as diretrizes gerais sobre o direcionamento principal por meio de TO / EXCEPT.

Comportamento:

  • Um usuário atuando com a própria identidade de usuário vê *** em todas as colunas de PII. Este é o estado padrão para todos, incluindo usuários que têm a permissão Assume em role-pii-cleared.
  • Depois de assumir role-pii-cleared, a política não se aplica mais à sessão e o mesmo usuário vê os valores brutos.
  • Audite as entradas de log do registro identity_metadata.run_as = role-pii-clearedde sessão, para que os revisores possam ver exatamente quando a PII foi desmascarada e por quem.

Políticas de níveis de confidencialidade que variam de acordo com o perfil assumido

Os dados são classificados em níveis de sensibilidade (internal, confidential, restricted). Cada nível tem um perfil de acesso correspondente, com restricted implicando acesso também a confidential e internal. Uma UDF de filtro de linha controla a visibilidade de cada linha comparando o nível de cada linha com o papel assumido pelo usuário.

Configuração:

  • As tabelas possuem uma coluna sensitivity_level marcada com a chave tag governedsensitivity (valores permitidos: internal, confidential, restricted).
  • Três funções de acesso: role-sens-internal, , role-sens-confidential. role-sens-restricted

UDF de filtro de linha:

CREATE FUNCTION sensitivity_allowed(row_sensitivity STRING) RETURNS BOOLEAN
DETERMINISTIC
RETURN CASE
  WHEN current_user() = 'role-sens-restricted' THEN TRUE
  WHEN current_user() = 'role-sens-confidential' THEN row_sensitivity IN ('internal', 'confidential')
  WHEN current_user() = 'role-sens-internal' THEN row_sensitivity = 'internal'
  ELSE FALSE
END;

Política:

CREATE POLICY sensitivity_filter
ON CATALOG corp_data
ROW FILTER sensitivity_allowed
TO `account users`
FOR TABLES
MATCH COLUMNS has_tag('sensitivity') AS sens
USING COLUMNS (sens);

Como um papel não é membro de si mesmo, esta UDF compara current_user() com cada nome de papel, em vez de testar o pertencimento com is_account_group_member(). Consulte a observação acima para saber por que os testes de associação não correspondem à função assumida. Consulte Considerações de desempenho para políticas de filtro de linha e máscara de coluna para obter informações sobre o desempenho de funções de identidade nas UDFs.

Comportamento:

  • Um usuário que atua como sua identidade de usuário não vê linhas. O ELSE FALSE branch corresponde a qualquer coisa que não seja uma das três funções. Como no exemplo por projeto acima, essa é a negação padrão pretendida.
  • Supondo que role-sens-internal revele apenas internal linhas.
  • Supondo que role-sens-confidential revele as linhas internal e confidential.
  • Supondo que role-sens-restricted revela todas as linhas.

Os usuários assumem a camada mais alta necessária para a sessão; o filtro exclui automaticamente tudo acima dessa camada sem exigir que o usuário saiba quais tabelas contêm quais classificações.

Atribuição de auditoria

Tanto as avaliações de políticas ABAC quanto as consultas subjacentes respeitam a atribuição de RBAC run_as / run_by. As entradas do log de auditoria registram identity_metadata.run_by como o usuário autenticado e identity_metadata.run_as como a função assumida, independentemente de quais políticas ABAC foram aplicadas durante a avaliação. Consulte a referência da tabela de sistema do log de auditoria para ver o esquema do log de auditoria completo.

Próximas Etapas 

  • Acesso exclusivo de modelo: aplique padrões para configurar o acesso exclusivo usando um grupo local de conta ou um grupo sincronizado de Microsoft Entra ID. Consulte o acesso exclusivo do Modelo.
  • Alternar entre funções: Assuma uma função usando o seletor de funções, clusters com modo de acesso dedicado, a CLI, a API ou ferramentas de BI de terceiros. Consulte Alternar funções.
  • Gerenciar permissões de assumir: conceda ou revogue a permissão de assumir em um grupo para que os usuários possam assumir a função correspondente. Consulte Gerenciar permissões em um grupo.
  • Revise os conceitos centrais do ABAC: saiba como funcionam as tags governadas, as políticas e a avaliação de políticas. Consulte o controle de acesso baseado em atributo no Catálogo do Unity.