Usar a segurança no nível da linha

Este documento explica como usar a segurança no nível da linha no BigQuery para restringir o acesso aos dados no nível da linha da tabela. Antes de ler este documento, familiarize-se com a visão geral sobre a segurança no nível da linha lendo a Introdução à segurança no nível da linha do BigQuery.

É possível executar as seguintes tarefas com políticas de acesso no nível da linha:

Antes de começar

Atribua papéis do Identity and Access Management (IAM) que concedam aos usuários as permissões necessárias para realizar cada tarefa deste documento. As permissões necessárias para executar uma tarefa (se houver) são listadas na seção "Permissões necessárias".

Criar ou atualizar uma política de acesso no nível da linha

É possível criar ou atualizar uma política de acesso no nível da linha em uma tabela no BigQuery com uma instrução de linguagem de definição de dados (DDL, na sigla em inglês).

Permissões necessárias

Para criar uma política de acesso no nível da linha em uma tabela do BigQuery, você precisa das seguintes permissões do IAM:

  • bigquery.rowAccessPolicies.create
  • bigquery.rowAccessPolicies.setIamPolicy
  • bigquery.tables.getData (na tabela de destino e em todas as tabelas referenciadas nas políticas de acesso no nível da linha da subconsulta)
  • bigquery.jobs.create para executar o job de consulta DDL

Para atualizar uma política de acesso no nível da linha em uma tabela do BigQuery, você precisa das seguintes permissões do IAM:

  • bigquery.rowAccessPolicies.update
  • bigquery.rowAccessPolicies.setIamPolicy
  • bigquery.tables.getData (na tabela de destino e em todas as tabelas referenciadas nas políticas de acesso no nível da linha da subconsulta)
  • bigquery.jobs.create para executar o job de consulta DDL

Cada um dos seguintes papéis predefinidos do IAM inclui as permissões necessárias para criar e atualizar uma política de acesso no nível da linha:

  • roles/bigquery.admin
  • roles/bigquery.dataOwner

Papel bigquery.filteredDataViewer

Quando você cria uma política de acesso no nível da linha, o BigQuery concede automaticamente o papel bigquery.filteredDataViewer aos membros da lista de beneficiários. Quando você lista as políticas de acesso no nível da linha de uma tabela no console do Google Cloud, esse papel é exibido em associação aos membros da lista de beneficiários da política.

Não conceda o bigquery.filteredDataViewer manualmente com o IAM. Para mais informações, consulte as práticas recomendadas para segurança no nível da linha.

Criar ou atualizar políticas de acesso no nível da linha

Para criar ou atualizar uma política de acesso no nível da linha, use uma das seguintes instruções de DDL:

  • CREATE ROW ACCESS POLICY cria uma nova política de acesso no nível da linha.

  • CREATE ROW ACCESS POLICY IF NOT EXISTS cria uma nova política de acesso no nível da linha, se já não houver uma na tabela especificada.

  • A instrução CREATE OR REPLACE ROW ACCESS POLICY atualiza uma política de acesso na linha com o mesmo nome na tabela especificada.

Exemplos

Crie uma nova política de acesso de linha. O acesso à tabela é restrito ao usuário abc@example.com. Somente as linhas em que region = 'APAC' é visível:

CREATE ROW ACCESS POLICY apac_filter
ON project.dataset.my_table
GRANT TO ('user:abc@example.com')
FILTER USING (region = 'APAC');

Atualize a política de acesso para aplicar à conta de serviço example@exampleproject.iam.gserviceaccount.com:

CREATE OR REPLACE ROW ACCESS POLICY apac_filter
ON project.dataset.my_table
GRANT TO ('serviceAccount:example@exampleproject.iam.gserviceaccount.com')
FILTER USING (region = 'APAC');

Crie uma política de acesso de linha que conceda acesso a um usuário e dois grupos:

CREATE ROW ACCESS POLICY sales_us_filter
ON project.dataset.my_table
GRANT TO ('user:john@example.com',
          'group:sales-us@example.com',
          'group:sales-managers@example.com')
FILTER USING (region = 'US');

allAuthenticatedUsersComo criar uma política de acesso de linha com como beneficiário

CREATE ROW ACCESS POLICY us_filter
ON project.dataset.my_table
GRANT TO ('allAuthenticatedUsers')
FILTER USING (region = 'US');

Como criar uma política de acesso de linha com um filtro com base no usuário atual

CREATE ROW ACCESS POLICY my_row_filter
ON dataset.my_table
GRANT TO ('domain:example.com')
FILTER USING (email = SESSION_USER());

ARRAYComo criar uma política de acesso de linha com um filtro em uma coluna com um tipo

CREATE ROW ACCESS POLICY my_reports_filter
ON project.dataset.my_table
GRANT TO ('domain:example.com')
FILTER USING (SESSION_USER() IN UNNEST(reporting_chain));

Crie uma política de acesso de linha com uma subconsulta para substituir várias políticas por uma comparação de região configurada por usuário:

Para enviar feedback ou receber suporte com esse recurso, envie um e-mail para bigquery-row-level-security-support@google.com.

Pense na tabela a seguir, lookup_table:

+-----------------+--------------+
|      email      |    region    |
+-----------------+--------------+
| xyz@example.com | europe-west1 |
| abc@example.com | us-west1     |
| abc@example.com | us-west2     |
+-----------------+--------------+
CREATE OR REPLACE ROW ACCESS POLICY apac_filter
ON project.dataset.my_table
GRANT TO ('domain:example.com')
FILTER USING (region IN (
    SELECT
      region
    FROM
      lookup_table
    WHERE
      email = SESSION_USER()));

O uso da subconsulta em lookup_table permite evitar a criação de várias políticas de acesso de linha. Por exemplo, a instrução anterior produz o mesmo resultado que a seguir, com menos consultas:

CREATE OR REPLACE ROW ACCESS POLICY apac_filter
ON project.dataset.my_table
GRANT TO ('user:abc@example.com')
FILTER USING (region = 'us-west1');

CREATE OR REPLACE ROW ACCESS POLICY apac_filter
ON project.dataset.my_table
GRANT TO ('user:abc@example.com')
FILTER USING (region IN 'us-west1', 'us-west2');

CREATE OR REPLACE ROW ACCESS POLICY apac_filter
ON project.dataset.my_table
GRANT TO ('user:xyz@example.com')
FILTER USING (region = 'europe-west1');

Para mais informações sobre a sintaxe e as opções disponíveis, consulte a referência de instrução DDL CREATE ROW ACCESS POLICY.

Combinar políticas de acesso no nível da linha

Se duas ou mais políticas de acesso no nível da linha concederem a um usuário ou grupo acesso à mesma tabela, o usuário ou grupo terá acesso a todos os dados cobertos por qualquer uma das políticas. Por exemplo, as seguintes políticas concedem ao usuário acesso abc@example.com às linhas especificadas na tabela my_table:

CREATE ROW ACCESS POLICY shoes
ON project.dataset.my_table
GRANT TO ('user:abc@example.com')
FILTER USING (product_category = 'shoes');
CREATE OR REPLACE ROW ACCESS POLICY blue_products
ON project.dataset.my_table
GRANT TO ('user:abc@example.com')
FILTER USING (color = 'blue');

No exemplo anterior, o usuário abc@example.com tem acesso às linhas na tabela my_table que contém o campo product_category definido como shoes, e abc@example.com também tem acesso às linhas que têm o campo color definido como blue. Por exemplo, abc@example.com seria capaz de acessar linhas com informações sobre sapatos vermelhos e carros azuis.

Isso equivale ao acesso fornecido pela seguinte política de acesso de nível de linha único:

CREATE ROW ACCESS POLICY shoes_and_blue_products
ON project.dataset.my_table
GRANT TO ('user:abc@example.com')
FILTER USING (product_category = 'shoes' OR color = 'blue');

Por outro lado, use um filtro com um operador AND para especificar o acesso que depende de mais de uma condição verdadeira. Por exemplo, as seguintes concessões de política de acesso no nível da linhaabc@example.com acessar somente as linhas que tenham o campo product_category definido como shoes e o campo color definido como blue.

CREATE ROW ACCESS POLICY blue_shoes
ON project.dataset.my_table
GRANT TO ('user:abc@example.com')
FILTER USING (product_category = 'shoes' AND color = 'blue');

Com a política de acesso no nível da linha anterior, abc@example.com poderia acessar informações sobre sapatos azuis, mas não sobre sapatos vermelhos ou carros azuis.

Listar políticas de acesso no nível da linha da tabela

É possível listar e visualizar todas as políticas de acesso no nível da linha em uma tabela usando o console do Google Cloud, a ferramenta de linha de comando bq ou o método RowAccessPolicies.List da API.

Permissões necessárias

Para listar as políticas de acesso no nível da linha em uma tabela do BigQuery, é preciso ter a permissão bigquery.rowAccessPolicies.list do IAM.

Para ver os membros de uma política de acesso no nível da linha em uma tabela do BigQuery, é preciso ter a permissão bigquery.rowAccessPolicies.getIamPolicy do IAM.

Cada um dos seguintes papéis predefinidos do IAM inclui as permissões necessárias para listar e visualizar políticas de acesso no nível da linha:

  • roles/bigquery.admin
  • roles/bigquery.dataOwner

Para mais informações sobre os papéis e as permissões do IAM no BigQuery, consulte Papéis e permissões predefinidos.

Listar políticas de acesso no nível da linha da tabela

Para listar políticas de acesso no nível da linha, faça o seguinte:

Console

  1. Para visualizar as políticas de acesso no nível da linha, acesse a página do BigQuery no console do Google Cloud.

    Ir para o BigQuery

  2. Clique no nome da tabela para ver os detalhes e, em seguida, clique em Ver políticas de acesso de linha.

    Visualizar políticas de acesso de linha

  3. Quando o painel Políticas de acesso da linha for aberto, você verá uma lista de todas as políticas de acesso no nível da linha na tabela por nome e o filter_expression de cada política.

    Detalhes das políticas de acesso da linha

  4. Para ver todos os papéis e usuários afetados por uma política de acesso no nível da linha, clique em VISUALIZAR ao lado da política. Por exemplo, na imagem abaixo, é possível ver no painel Visualizar permissões que os membros da lista de beneficiários têm o papel bigquery.filteredDataViewer.

    Detalhes das políticas de acesso da linha

bq

Insira o comando bq ls e forneça a sinalização --row_access_policies. Os nomes do conjunto de dados e da tabela são obrigatórios.

    bq ls --row_access_policies dataset.table

Por exemplo, o comando a seguir lista informações sobre as políticas de acesso no nível da linha de uma tabela chamada my_table em um conjunto de dados com o ID my_dataset.

    bq ls --row_access_policies my_dataset.my_table

API

Use o método RowAccessPolicies.List na seção de referência da API REST.

Excluir políticas de acesso no nível da linha

É possível excluir uma ou todas as políticas de acesso no nível da linha em uma tabela usando uma instrução DDL tendo as permissões corretas.

Permissões necessárias

Para descartar uma política de acesso no nível da linha, é preciso ter as seguintes permissões do IAM:

  • bigquery.rowAccessPolicies.delete
  • bigquery.rowAccessPolicies.setIamPolicy
  • bigquery.jobs.create para executar o job de consulta DDL

Para descartar todas as políticas de acesso no nível da linha em uma tabela ao mesmo tempo, você precisa das seguintes permissões do IAM:

  • bigquery.rowAccessPolicies.delete
  • bigquery.rowAccessPolicies.setIamPolicy
  • bigquery.rowAccessPolicies.list
  • bigquery.jobs.create para executar o job de consulta DDL

Cada um dos seguintes papéis predefinidos do IAM inclui as permissões necessárias para excluir políticas de acesso no nível da linha:

  • roles/bigquery.admin
  • roles/bigquery.dataOwner

Para mais informações sobre os papéis e as permissões do IAM no BigQuery, consulte Papéis e permissões predefinidos.

Excluir políticas de acesso no nível da linha

Para excluir uma política de acesso de linha de uma tabela, use as seguintes instruções de DDL:

  • A instrução DROP ROW ACCESS POLICY exclui uma política de acesso no nível da linha na tabela especificada.

  • A instrução DROP ROW ACCESS POLICY IF EXISTS excluirá uma política de acesso no nível da linha se ela existir na tabela especificada.

  • A instrução DROP ALL ROW ACCESS POLICIES exclui todas as políticas de acesso no nível da linha na tabela especificada.

Exemplos

Exclui uma política de acesso no nível da linha de uma tabela

DROP ROW ACCESS POLICY my_row_filter ON project.dataset.my_table;

Como excluir todas as políticas de acesso no nível da linha de uma tabela

DROP ALL ROW ACCESS POLICIES ON project.dataset.my_table;

Para mais informações sobre como excluir uma política de acesso no nível da linha, consulte a referência de instrução DDL DROP ROW ACCESS POLICY.

Consultar tabelas com políticas de acesso de linha

Um usuário primeiro precisa ter acesso a uma tabela do BigQuery para consultá-la, mesmo que esteja na grantee_list de uma política de acesso da linha nessa tabela. Sem essa permissão, a consulta falha com um erro access denied.

Permissões necessárias

Para consultar uma tabela do BigQuery com políticas de acesso no nível da linha, você precisa das permissões bigquery.tables.getData e bigquery.rowAccessPolicies.getFilteredData do IAM. Você precisa ter a permissão bigquery.tables.getData do IAM em todas as tabelas relevantes.

Para receber essas permissões com papéis predefinidos, você precisa receber os papéis IAM roles/bigquery.dataViewer e roles/bigquery.filteredDataViewer.

Você precisa ter a permissão datacatalog.categories.fineGrainedGet em todas as colunas relevantes com segurança no nível da coluna. Para receber essa permissão com papéis predefinidos, você precisa do papel datacatalog.categoryFineGrainedReader.

Ver os resultados da consulta

No console do Google Cloud, quando você consulta uma tabela com uma política de acesso no nível da linha, o BigQuery exibe um aviso em banner indicando que os resultados podem ser filtrados por uma política de acesso no nível da linha. Esse aviso será exibido mesmo que você seja membro da lista de beneficiários da política.

Resultado da consulta na tabela com política de acesso no nível da linha

Estatísticas do job

Quando você consulta uma tabela com uma política de acesso no nível da linha usando a API Job, o BigQuery indica se a consulta lê tabelas com políticas de acesso de linha no objeto de resposta Job:

Exemplo

Para simplificar, a resposta ao objeto Job foi truncada:

{
  "configuration": {
    "jobType": "QUERY",
    "query": {
      "priority": "INTERACTIVE",
      "query": "SELECT * FROM dataset.table",
      "useLegacySql": false
    }
  },
  ...
  "statistics": {
    ...
    rowLevelSecurityStatistics: {
      rowLevelSecurityApplied: true
    },
    ...
  },
  "status": {
    "state": "DONE"
  },
  ...
}

A seguir