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 dois exemplos sobre como implementar políticas de acesso a linhas:

  • Uma política típica de acesso a linhas com uma busca na tabela de mapeamento.

  • Substituindo as subconsultas existentes da política de acesso a linhas por funções memoizáveis para aumentar o desempenho da consulta.

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 de contexto IS_ROLE_IN_SESSION. Para exemplos de políticas, consulte a seção Exemplos na função IS_ROLE_IN_SESSION.

    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.

Etapa 1: Criar uma tabela para os dados

Crie uma tabela para os dados de vendas.

CREATE TABLE sales (
  customer   varchar,
  product    varchar,
  spend      decimal(20, 2),
  sale_date  date,
  region     varchar
);
Copy

Etapa 2: Criar uma tabela de mapeamento, função personalizada e conceda o privilégio SELECT

No esquema security, crie uma tabela de mapeamento como mostrado no exemplo representativo. Esta tabela define quais linhas na tabela sales os gerentes de vendas podem ver.

CREATE TABLE security.salesmanagerregions (
  sales_manager varchar,
  region        varchar
);
Copy

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;
Copy

Etapa 3: Criar uma política de acesso a linhas

Usando a função de proprietário do esquema, crie uma política de acesso a linhas com as duas condições a seguir:

  1. Os usuários com a função sales_executive_role personalizada podem visualizar todas as linhas.

  2. Os usuários com a função sales_manager personalizada podem visualizar linhas com base na tabela de mapeamento salesmanagerregions.

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
          )
;
Copy

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.

RETURNS BOOLEAN ->

Especifica a aplicação da política de acesso a linhas.

Observe que o expression da política de acesso a linhas segue imediatamente a linha da direita (isto é, ->).

A expressão pode ser qualquer expressão SQL com valor booleano. O Snowflake oferece suporte às expressões que invocam UDFs, funções externas e expressões que utilizam subconsultas.

'sales_executive_role' = CURRENT_ROLE()

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).

Etapa 4: Conceder privilégios a funções personalizadas

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;
Copy

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.

Etapa 5: Adicionar a política de acesso a linhas a uma tabela

Qualquer tabela ou exibição no Snowflake só pode oferecer suporte a uma política de acesso a linhas de cada vez.

Adicione (ou seja, 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);
Copy

Etapa 6: Permitir que uma função consulte os dados da tabela protegida

Conceda o privilégio SELECT para os dados protegidos sales à função personalizada sales_manager_role.

GRANT SELECT ON TABLE sales TO ROLE sales_manager_role;
Copy

Etapa 7: Testar a política

Depois que os dados de vendas preencherem os dados 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;
Copy

Exemplo: substituição de 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)
  ;
Copy

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:

  1. Criar uma função personalizada chamada functions_admin para gerenciar a função memoizável:

    USE ROLE USERADMIN;
    
    CREATE ROLE functions_admin;
    
    Copy
  2. Conceder os seguintes privilégios à função functions_admin para permitir a criação da função memoizável em um esquema existente chamado governance.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;
    
    Copy
  3. 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';
    
    Copy
  4. 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())
      ;
    
    Copy