Política de segurança em nível de linha
Aplica-se a: ✅Microsoft Fabric✅Azure Data Explorer
Use a associação ao grupo ou o contexto de execução para controlar o acesso a linhas em uma tabela de banco de dados.
A Segurança ao Nível de Linha (RLS) simplifica o design e a codificação da segurança. Ele permite que você aplique restrições no acesso à linha de dados em seu aplicativo. Por exemplo, limite o acesso do usuário a linhas relevantes para seu departamento ou restrinja o acesso do cliente apenas aos dados relevantes para sua empresa.
A lógica de restrição de acesso está localizada na camada de banco de dados, em vez de longe dos dados em outra camada de aplicativo. O sistema de banco de dados aplica as restrições de acesso sempre que o acesso aos dados é tentado a partir de qualquer camada. Esta lógica torna o seu sistema de segurança mais fiável e robusto, reduzindo a área de superfície do seu sistema de segurança.
A RLS permite-lhe fornecer acesso a outras aplicações e utilizadores, apenas a uma determinada parte de uma tabela. Por exemplo, você pode querer:
- Conceder acesso apenas a linhas que atendam a alguns critérios
- Anonimizar dados em algumas das colunas
- Todos os itens acima
Observação
Quando uma política RLS é habilitada em uma tabela, o acesso é totalmente substituído pela consulta RLS definida na tabela. A restrição de acesso aplica-se a todos os utilizadores, incluindo administradores de bases de dados e o criador da RLS. A consulta RLS deve incluir explicitamente definições para todos os tipos de usuários aos quais você deseja conceder acesso.
Para obter mais informações, consulte comandos de gerenciamento para gerenciar a diretiva de Segurança em Nível de Linha.
Dica
Estas funções são geralmente úteis para consultas row_level_security:
Limitações
- Não há limite para o número de tabelas nas quais a diretiva de Segurança em Nível de Linha pode ser configurada.
- A política de Segurança em Nível de Linha não pode ser configurada em Tabelas Externas.
- A política RLS não pode ser ativada numa tabela nas seguintes circunstâncias:
- Quando é referenciada por uma política de atualização consulta, enquanto a política de atualização não está configurada com uma identidade gerenciada.
- Quando é referenciado por um de exportação contínua que usa um método de autenticação diferente da representação.
- Quando um de política de acesso restrito ao modo de exibição é configurado para a tabela.
- A consulta RLS não pode fazer referência a outras tabelas que tenham a política de Segurança em Nível de Linha habilitada.
- A consulta RLS não pode fazer referência a tabelas localizadas em outros bancos de dados.
Exemplos
Limitar o acesso à tabela Vendas
Em uma tabela chamada Sales
, cada linha contém detalhes sobre uma venda. Uma das colunas contém o nome do vendedor. Em vez de dar aos seus vendedores acesso a todos os registros no Sales
, habilite uma política de Segurança em Nível de Linha nesta tabela para retornar apenas registros em que o vendedor é o usuário atual:
Sales | where SalesPersonAadUser == current_principal()
Você também pode mascarar o endereço de e-mail:
Sales | where SalesPersonAadUser == current_principal() | extend EmailAddress = "****"
Se quiser que cada vendedor veja todas as vendas de um país/região específico, pode definir uma consulta semelhante a:
let UserToCountryMapping = datatable(User:string, Country:string)
[
"john@domain.com", "USA",
"anna@domain.com", "France"
];
Sales
| where Country in ((UserToCountryMapping | where User == current_principal_details()["UserPrincipalName"] | project Country))
Se você tiver um grupo que contenha os gerentes, convém dar-lhes acesso a todas as linhas. Aqui está a consulta para a política de Segurança em Nível de Linha.
let IsManager = current_principal_is_member_of('aadgroup=sales_managers@domain.com');
let AllData = Sales | where IsManager;
let PartialData = Sales | where not(IsManager) and (SalesPersonAadUser == current_principal()) | extend EmailAddress = "****";
union AllData, PartialData
Expor dados diferentes a membros de diferentes grupos do Microsoft Entra
Se você tiver vários grupos do Microsoft Entra e quiser que os membros de cada grupo vejam um subconjunto diferente de dados, use essa estrutura para uma consulta RLS.
Customers
| where (current_principal_is_member_of('aadgroup=group1@domain.com') and <filtering specific for group1>) or
(current_principal_is_member_of('aadgroup=group2@domain.com') and <filtering specific for group2>) or
(current_principal_is_member_of('aadgroup=group3@domain.com') and <filtering specific for group3>)
Aplicar a mesma função RLS em várias tabelas
Primeiro, defina uma função que receba o nome da tabela como um parâmetro de cadeia de caracteres e faça referência à tabela usando o operador table()
.
Por exemplo:
.create-or-alter function RLSForCustomersTables(TableName: string) {
table(TableName)
| ...
}
Em seguida, configure o RLS em várias tabelas desta forma:
.alter table Customers1 policy row_level_security enable "RLSForCustomersTables('Customers1')"
.alter table Customers2 policy row_level_security enable "RLSForCustomersTables('Customers2')"
.alter table Customers3 policy row_level_security enable "RLSForCustomersTables('Customers3')"
Produzir um erro em caso de acesso não autorizado
Se você quiser que os usuários não autorizados da tabela recebam um erro em vez de retornar uma tabela vazia, use a função assert()
. O exemplo a seguir mostra como produzir esse erro em uma função RLS:
.create-or-alter function RLSForCustomersTables() {
MyTable
| where assert(current_principal_is_member_of('aadgroup=mygroup@mycompany.com') == true, "You don't have access")
}
Você pode combinar essa abordagem com outros exemplos. Por exemplo, você pode exibir resultados diferentes para usuários em diferentes grupos do Microsoft Entra e produzir um erro para todos os outros.
Permissões de controle em bancos de dados de seguidores
A política RLS que você configurar no banco de dados de produção também terá efeito nos bancos de dados de seguidores. Não é possível configurar diferentes políticas RLS nos bancos de dados de produção e seguidores. No entanto, você pode usar a função current_cluster_endpoint()
em sua consulta RLS para obter o mesmo efeito, como ter consultas RLS diferentes em tabelas de seguidores.
Por exemplo:
.create-or-alter function RLSForCustomersTables() {
let IsProductionCluster = current_cluster_endpoint() == "mycluster.eastus.kusto.windows.net";
let DataForProductionCluster = TempTable | where IsProductionCluster;
let DataForFollowerClusters = TempTable | where not(IsProductionCluster) | extend EmailAddress = "****";
union DataForProductionCluster, DataForFollowerClusters
}
Observação
A função RLS acima não tem qualquer impacto no desempenho das consultas no cluster líder. O impacto no desempenho das consultas nos clusters de seguidores será afetado apenas pela complexidade do DataForFollowerClusters
.
Permissões de controle em bancos de dados de atalho
A política RLS configurada no banco de dados de produção também terá efeito nos bancos de dados de atalho. Não é possível configurar diferentes políticas RLS nos bancos de dados de produção e atalho. No entanto, você pode usar a função current_cluster_endpoint()
em sua consulta RLS para obter o mesmo efeito, como ter consultas RLS diferentes em tabelas de atalho.
Por exemplo:
.create-or-alter function RLSForCustomersTables() {
let IsProductionCluster = current_cluster_endpoint() == "mycluster.eastus.kusto.windows.net";
let DataForProductionCluster = TempTable | where IsProductionCluster;
let DataForFollowerClusters = TempTable | where not(IsProductionCluster) | extend EmailAddress = "****";
union DataForProductionCluster, DataForFollowerClusters
}
Observação
A função RLS acima não tem qualquer impacto no desempenho das consultas na base de dados de origem. O impacto no desempenho das consultas nos bancos de dados de atalho será afetado apenas pela complexidade do DataForFollowerClusters
.
Mais casos de uso
- Uma pessoa de suporte de call center pode identificar os chamadores por vários dígitos de seu número de segurança social. Este número não deve ser totalmente exposto à pessoa de apoio. Uma política RLS pode ser aplicada na tabela para mascarar todos, exceto os últimos quatro dígitos do número de segurança social no conjunto de resultados de qualquer consulta.
- Defina uma política de RLS que mascare informações de identificação pessoal (PII) e permita que os desenvolvedores consultem ambientes de produção para fins de solução de problemas sem violar os regulamentos de conformidade.
- Um hospital pode definir uma política de SPI que permita aos enfermeiros visualizar linhas de dados apenas para os seus pacientes.
- Um banco pode definir uma política de RLS para restringir o acesso a linhas de dados financeiros com base na divisão de negócios ou função de um funcionário.
- Um aplicativo multilocatário pode armazenar dados de muitos locatários em um único conjunto de tabelas (o que é eficiente). Eles usariam uma política RLS para impor uma separação lógica das linhas de dados de cada locatário das linhas de todos os outros locatários, para que cada locatário possa ver apenas suas linhas de dados.
Impacto no desempenho das consultas
Quando uma política RLS é habilitada em uma tabela, haverá algum impacto no desempenho das consultas que acessam essa tabela. O acesso à tabela será substituído pela consulta RLS definida nessa tabela. O impacto no desempenho de uma consulta RLS normalmente consistirá em duas partes:
- Verificações de associação no Microsoft Entra ID: as verificações são eficientes. Você pode verificar a associação em dezenas, ou até mesmo centenas de grupos sem grande impacto no desempenho da consulta.
- Filtra, associa e outras operações aplicadas aos dados: o impacto depende da complexidade da consulta
Por exemplo:
let IsRestrictedUser = current_principal_is_member_of('aadgroup=some_group@domain.com');
let AllData = MyTable | where not(IsRestrictedUser);
let PartialData = MyTable | where IsRestrictedUser and (...);
union AllData, PartialData
Se o usuário não fizer parte do some_group@domain.com, IsRestrictedUser
será avaliado para false
. A consulta avaliada é semelhante a esta:
let AllData = MyTable; // the condition evaluates to `true`, so the filter is dropped
let PartialData = <empty table>; // the condition evaluates to `false`, so the whole expression is replaced with an empty table
union AllData, PartialData // this will just return AllData, as PartialData is empty
Da mesma forma, se IsRestrictedUser
avalia para true
, então apenas a consulta para PartialData
será avaliada.
Melhorar o desempenho da consulta quando a RLS é usada
- Se um filtro for aplicado em uma coluna de alta cardinalidade, por exemplo, DeviceID, considere usar política de particionamento ou política Ordem de Linha
- Se um filtro for aplicado em uma coluna de cardinalidade média-baixa, considere usar política Ordem de Linha
Impacto no desempenho na ingestão
Não há impacto no desempenho na ingestão.