Uso de políticas de acesso a linhas¶
Este tópico fornece uma introdução à implementação de políticas de acesso a linhas.
Neste tópico:
Implementação de políticas de acesso a linhas¶
As subseções a seguir fornecem exemplos sobre como implementar políticas de acesso a linhas:
Use uma política típica de acesso a linhas com uma busca na tabela de mapeamento.
Substitua as subconsultas existentes da política de acesso a linhas por funções memoizáveis para aumentar o desempenho da consulta.
Faça referência a uma tabela de mapeamento protegida por uma política de acesso a linhas em uma política de acesso a linhas diferente.
Exemplo: pesquisa da tabela de mapeamento¶
As etapas seguintes são um guia representativo para configurar privilégios de políticas de acesso a linhas e adicionar políticas de acesso a linhas a tabelas e exibições.
Estas etapas fazem as seguintes suposições:
A abordagem de gerenciamento é centralizada.
Se o caso de uso da política de acesso a linhas incluir uma abordagem de gerenciamento híbrida ou descentralizada, consulte Gerenciamento de políticas de acesso a linhas para uma distribuição representativa de funções e privilégios.
É necessária uma tabela de mapeamento, semelhante a Caso de uso representativo: uso de uma tabela de mapeamento para filtrar o resultado da consulta.
As etapas seguintes usam a função de contexto CURRENT_ROLE para determinar se os usuários veem linhas em um resultado de consulta, enquanto o caso de uso representativo se concentra no nome do usuário (ou seja, CURRENT_USER).
Se a ativação e a hierarquia de funções forem importantes, Snowflake recomenda que as condições da política utilizem a função IS_ROLE_IN_SESSION para funções de conta e a função IS_DATABASE_ROLE_IN_SESSION para funções de banco de dados. Para obter mais detalhes, consulte Hierarquia de funções ativa e tabelas de mapeamento.
O processo geral para implementar uma política de acesso a linhas com tabelas de mapeamento permanece o mesmo, embora as funções de contexto sejam diferentes.
A função SECURITYADMIN do sistema concede privilégios a funções personalizadas para gerenciar e implementar políticas de acesso a linhas.
Se você não quiser usar funções mais privilegiadas (ou seja, SECURITYADMIN ou ACCOUNTADMIN) em um ambiente de produção em vez de funções personalizadas menos privilegiadas (por exemplo,
database_admin
,finance_admin
), verifique se as funções menos privilegiadas têm os privilégios necessários para gerenciar e implementar políticas de acesso a linhas.Para obter mais informações, consulte Privilégios da política de acesso a linhas e Resumo de comandos DDL, operações e privilégios.
Há etapas separadas para criar uma tabela a ser protegida por uma política de acesso a linhas (etapa 1) e adicionar a política de acesso a linhas à tabela (etapa 5). É possível adicionar uma política de acesso a linhas à tabela quando a tabela é criada, assumindo que já exista uma política de acesso a linhas. Para obter mais informações sobre a sintaxe, consulte CREATE TABLE.
Por exemplo:
Crie uma tabela para os dados de vendas:
CREATE TABLE sales ( customer varchar, product varchar, spend decimal(20, 2), sale_date date, region varchar );
No esquema
security
, crie uma tabela de mapeamento como mostrado no exemplo representativo. Esta tabela define quais linhas na tabelasales
podem ser vistas pelos gerentes de vendas:CREATE TABLE security.salesmanagerregions ( sales_manager varchar, region varchar );
Em seguida, um administrador de segurança cria a função
mapping_role
personalizada e concede o privilégio SELECT à função personalizada. Esta concessão permite aos usuários com a função personalizada consultar a tabela de mapeamento:USE ROLE SECURITYADMIN; CREATE ROLE mapping_role; GRANT SELECT ON TABLE security.salesmanagerregions TO ROLE mapping_role;
Usando a função de proprietário do esquema, crie uma política de acesso a linhas com as duas condições a seguir:
Os usuários com a função
sales_executive_role
personalizada podem visualizar todas as linhas.Os usuários com a função
sales_manager
personalizada podem visualizar linhas com base na tabela de mapeamentosalesmanagerregions
.
Observe que a função de proprietário do esquema recebe automaticamente o privilégio CREATE ROW ACCESS POLICY. Se outras funções devem ser capazes de criar políticas de acesso a linhas, a função do proprietário do esquema pode conceder o privilégio da política CREATE ROW ACCESS a outras funções.
USE ROLE schema_owner_role; CREATE OR REPLACE ROW ACCESS POLICY security.sales_policy AS (sales_region varchar) RETURNS BOOLEAN -> 'sales_executive_role' = CURRENT_ROLE() OR EXISTS ( SELECT 1 FROM salesmanagerregions WHERE sales_manager = CURRENT_ROLE() AND region = sales_region ) ;
Onde:
security.sales_policy
O nome da política de acesso a linhas no esquema
security
.AS (sales_region varchar)
A assinatura da política de acesso a linhas.
Uma assinatura especifica o atributo da tabela de mapeamento e o tipo de dados. O valor retornado determina se o usuário tem acesso a uma determinada linha na tabela ou exibição à qual a política de acesso a linhas é adicionada.
'sales_executive_role' = CURRENT_ROLE()
O início de
body
na política de acesso a linhas.A primeira condição da expressão da política de acesso a linhas que permite aos usuários com a função
sales_executive_role
personalizada visualizar dados.OR EXISTS (select 1 from salesmanagerregions WHERE sales_manager = CURRENT_ROLE() AND region = sales_region)
A segunda condição da expressão da política de acesso a linhas que utiliza uma subconsulta.
A subconsulta requer que CURRENT_ROLE seja a função
sales_manager
personalizada com a consulta executada nos dados para especificar uma região listada na tabela de mapeamento{salesmanagerregions}
.Dica
Para aumentar o desempenho da consulta na tabela protegida por política, substitua a subconsulta de pesquisa da tabela de mapeamento na cláusula
EXISTS
por uma função memoizável.Para obter mais detalhes, consulte o exemplo de função memoizável (neste tópico).
Usando a função SECURITYADMIN do sistema, execute as duas instruções a seguir:
GRANT OWNERSHIP ON ROW ACCESS POLICY security.sales_policy TO mapping_role; GRANT APPLY ON ROW ACCESS POLICY security.sales_policy TO ROLE sales_analyst_role;
Estas duas instruções GRANT <privilégios> têm os seguintes efeitos:
A propriedade da política não recai sobre a função do sistema SECURITYADMIN. No tempo de execução da consulta, o Snowflake usa os privilégios concedidos à função personalizada porque as políticas são executadas com os direitos do proprietário, não com a função de sistema SECURITYADMIN mais privilegiada. Esta abordagem suporta o princípio de privilégio mínimo.
A função personalizada
sales_analyst_role
pode adicionar ou descartar a política de acesso a linhas a partir de uma tabela conforme necessário.
Adicione (vincule) a política de acesso a linhas à coluna da região na tabela de dados
sales
:USE ROLE SECURITYADMIN; ALTER TABLE sales ADD ROW ACCESS POLICY security.sales_policy ON (region);
Conceda o privilégio SELECT para os dados protegidos de
sales
à função personalizadasales_manager_role
:GRANT SELECT ON TABLE sales TO ROLE sales_manager_role;
Depois que os dados de vendas preencherem os dados de
sales
, teste a política de acesso a linhas:USE ROLE sales_manager_role; SELECT product, SUM(spend) FROM sales WHERE YEAR(sale_date) = 2020 GROUP BY product;
Exemplo: substitua as subconsultas de política por uma função memoizável¶
As etapas neste exemplo criam uma função memoizável para cada pesquisa de tabela de mapeamento nas condições da política de acesso a linhas. A subconsulta em cada cláusula EXISTS
especifica a pesquisa da tabela de mapeamento, onde as tabelas são nomeadas regions
, customers
e products
, respectivamente:
CREATE OR REPLACE ROW ACCESS POLICY rap_NO_memoizable_function AS (region_id number, customer_id number, product_id number) RETURNS BOOLEAN -> EXISTS(SELECT 1 FROM regions WHERE id = region_id) OR EXISTS(SELECT 1 FROM customers WHERE id = customer_id) OR EXISTS(SELECT 1 FROM products WHERE id = product_id) ;
Para as etapas seguintes, assumir que a função rap_admin
personalizada pode criar políticas de acesso a linhas (ou seja, tem o privilégio CREATE ROW ACCESS POLICY no SCHEMA).
Complete as seguintes etapas para substituir cada uma das pesquisas da tabela de mapeamento de políticas de acesso a linhas por uma função memoizável:
Criar uma função personalizada chamada
functions_admin
para gerenciar a função memoizável:USE ROLE USERADMIN; CREATE ROLE functions_admin;
Conceder os seguintes privilégios à função
functions_admin
para permitir a criação da função memoizável em um esquema existente chamadogovernance.functions
:USE ROLE SECURITYADMIN; GRANT USAGE ON DATABASE governance TO ROLE functions_admin; GRANT USAGE ON SCHEMA governance.functions TO ROLE functions_admin; GRANT CREATE FUNCTION ON SCHEMA governance.functions TO ROLE functions_admin;
Crie uma função memoizável para cada uma das cláusulas
EXISTS
de subconsulta na política de acesso a linhas. Cada definição de função memoizável assume a mesma forma. Para maior brevidade, apenas um exemplo de função é mostrado:USE ROLE functions_admin; USE SCHEMA governance.functions; CREATE OR REPLACE function allowed_regions() RETURNS array memoizable AS 'SELECT ARRAY_AGG(id) FROM regions';
Use uma instrução CREATE ROW ACCESS POLICY para definir uma nova política de acesso a linhas que substitui as subconsultas por funções memoizáveis:
A nova política de acesso a linhas permite o teste em consultas em uma tabela protegida, quando a política usa ou não as funções memoizáveis, para quantificar o impacto de desempenho do uso de funções memoizáveis nas condições da política:
USE ROLE rap_admin; CREATE OR REPLACE ROW ACCESS POLICY rap_with_memoizable_function AS (region_id number, customer_id number, product_id number) RETURNS BOOLEAN -> ARRAY_CONTAINS(region_id, allowed_regions()) OR ARRAY_CONTAINS(customer_id, allowed_customers()) OR ARRAY_CONTAINS(product_id, allowed_products()) ;
Exemplo: proteja a tabela de mapeamento com uma política de acesso a linhas¶
Este exemplo mostra como fazer referência a uma tabela de mapeamento protegida por uma política de acesso a linhas em uma política de acesso a linhas diferente. A política de acesso a linhas que protege a tabela de mapeamento chama a função de contexto IS_ROLE_IN_SESSION para dar conta da hierarquia de funções. Uma política de acesso a linhas diferente protege a tabela que o usuário consulta. Esta política de acesso a linhas usa uma subconsulta para realizar uma pesquisa na tabela de mapeamento. Por exemplo:
Crie uma tabela de mapeamento para definir funções permitidas com base em regiões geográficas de vendas e insira dados na tabela:
CREATE OR REPLACE TABLE sales.tables.regional_managers ( allowed_regions varchar allowed_roles varchar );
INSERT INTO sales.tables.regional_managers (allowed_regions, allowed_roles) VALUES ('na', 'NA_MANAGER'), ('eu', 'EU_MANAGER'), ('apac', 'APAC_MANAGER');
Crie uma política de acesso a linhas para especificar a coluna ALLOWED_ROLES na tabela de mapeamento:
CREATE OR REPLACE ROW ACCESS POLICY governance.policies.rap_map_exempt AS (allowed_roles varchar) RETURNS BOOLEAN -> IS_ROLE_IN_SESSION(allowed_roles);
Adicione a política de acesso a linhas na tabela de mapeamento usando uma instrução ALTER TABLE:
ALTER TABLE sales.tables.regional_managers ADD ROW ACCESS POLICY governance.policies.rap_map_exempt ON (allowed_roles);
Crie uma nova política de acesso a linhas que especifique a pesquisa da tabela de mapeamento na tabela de mapeamento protegida:
CREATE OR REPLACE ROW ACCESS POLICY governance.policies.rap_map_lookup AS (allowed_regions varchar) RETURNS BOOLEAN -> EXISTS ( SELECT * FROM sales.tables.regional_managers WHERE REGION = allowed_regions );
Adicione a política de acesso a linhas denominada
governance.policies.rap_map_lookup
na tabela denominadasales.tables.data
usando uma instrução ALTER TABLE:ALTER TABLE sales.tables.data ADD ROW ACCESS POLICY governance.policies.rap_map_lookup ON (allowed_regions);
Conceda privilégios às funções na tabela de mapeamento para permitir que usuários com essas funções consultem os dados protegidos. Por exemplo, estas concessões são para a função personalizada
na_manager
:USE ROLE SECURITYADMIN; GRANT USAGE ON DATABASE sales TO ROLE na_manager; GRANT USAGE ON SCHEMA sales.tables TO ROLE na_manager; GRANT SELECT ON TABLE sales.tables.regional_managers TO ROLE na_manager; GRANT SELECT ON TABLE sales.tables.data TO ROLE na_manager;
Conforme necessário, repita os comandos desta etapa para cada função na tabela de mapeamento.