使用行级安全性

本文档介绍如何在 BigQuery 中使用行级安全性在表行级限制对数据的访问权限。在阅读本文档之前,请先阅读 BigQuery 行级安全性简介,熟悉行级安全性。

概览

您可以使用行级访问权限政策执行以下任务:

准备工作

授予为用户提供执行本文档中的每个任务所需权限的 Identity and Access Management (IAM) 角色。执行任务所需的权限(如果有)列出在任务的“所需权限”部分中。

创建或更新行级访问权限政策

您可以使用数据定义语言 (DDL) 语句在 BigQuery 中创建或更新行级访问权限政策。

所需权限

如需在 BigQuery 表上创建行级访问权限政策,您需要以下 IAM 权限:

  • bigquery.rowAccessPolicies.create
  • bigquery.rowAccessPolicies.setIamPolicy
  • bigquery.tables.getData(针对目标表以及所授予的子查询行级访问权限政策中的任何引用的表)
  • bigquery.jobs.create(用于运行 DDL 查询作业)

如需更新 BigQuery 表的行级访问权限政策,您需要以下 IAM 权限:

  • bigquery.rowAccessPolicies.update
  • bigquery.rowAccessPolicies.setIamPolicy
  • bigquery.tables.getData(针对目标表以及所授予的子查询行级访问权限政策中的任何引用的表)
  • bigquery.jobs.create(用于运行 DDL 查询作业)

以下每个预定义的 IAM 角色都包含您创建和更新行级访问权限政策所需的权限:

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

bigquery.filteredDataViewer 角色

当您成功创建行级访问权限政策后,系统会自动向被授权者列表的成员授予 bigquery.filteredDataViewer 角色。bigquery.filteredDataViewer 角色授予查看通过政策的过滤表达式定义的行的权限。当您在 Google Cloud 控制台中列出表的行级访问权限政策时,系统将根据政策的被授权者列表的成员显示此角色。

在将 bigquery.filteredDataViewer 角色与 IAM 搭配使用时,请参阅我们推荐的行级安全性最佳做法

如需详细了解 BigQuery 中的 IAM 角色和权限,请参阅预定义的角色和权限

创建或更新行级访问权限政策

如需创建或更新行级访问权限政策,请使用以下 DDL 语句之一:

  • CREATE ROW ACCESS POLICY 会创建新的行级访问权限政策。

  • 如果所指定表尚无同名的行级访问政策,则 CREATE ROW ACCESS POLICY IF NOT EXISTS 语句会创建新的行级访问权限政策。

  • CREATE OR REPLACE ROW ACCESS POLICY 语句会更新指定表的同名的现有行级访问权限政策。

示例

创建新的行访问权限政策。只有用户 abc@example.com 才能访问该表。只有 region = 'APAC' 可见的行:

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

更新访问权限政策以改为应用于服务账号 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');

创建一项行访问权限政策,用于向一个用户和两个群组授予访问权限:

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

创建被授权者为 allAuthenticatedUsers 的行访问权限政策:

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

使用基于当前用户的过滤条件创建行访问权限政策:

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

使用针对类型为 ARRAY 的列的过滤条件创建行访问权限政策:

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

创建包含子查询的行访问策略,使用为每个用户配置的简单区域比较来替换多个策略:

如需针对此功能提供反馈或请求支持,请发送电子邮件至 bigquery-row-level-security-support@google.com。

请参考下表 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()));

lookup_table 上使用子查询可让您避免创建多个行访问权限政策。例如,前面的语句会生成与下面相同的结果,查询量更少:

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

如需详细了解语法和可用选项,请参阅 CREATE ROW ACCESS POLICY DDL 语句参考。

组合行级访问权限政策

如果两个或更多行级访问权限政策向用户或群组授予对同一表的访问权限,则该用户或群组有权访问任意政策涵盖的所有数据。例如,以下政策会向用户授予对 my_table 表中指定行的 abc@example.com 访问权限:

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

在前面的示例中,用户 abc@example.com 有权访问 product_category 字段设置为 shoesmy_table 表中的行,abc@example.com 还有权访问 color 字段设置为 blue 的行。例如,abc@example.com 可以访问有关红色鞋和蓝色汽车的信息所在的行。

此访问权限等效于以下单行级访问权限政策提供的访问权限:

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

另一方面,如需指定依赖于多个条件为 true 的访问权限,请使用具有 AND 运算符的过滤条件。例如,以下行级访问权限政策会为 abc@example.com 授予仅访问 product_category 字段设置为 shoescolor 字段设置为 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');

使用上述行级访问权限政策时,abc@example.com 可以访问有关蓝色鞋的信息,但不能访问有关红色鞋或蓝色汽车的信息。

列出表行级访问权限政策

您可以使用 Google Cloud 控制台、bq 命令行工具或 RowAccessPolicies.List API 方法列出和查看表的所有行级访问权限政策。

所需权限

如需列出 BigQuery 表的行级访问权限政策,您需要拥有 bigquery.rowAccessPolicies.list IAM 权限。

如需查看 BigQuery 表的行级访问权限政策的成员,您需要拥有 bigquery.rowAccessPolicies.getIamPolicy IAM 权限。

以下每个预定义 IAM 角色都包含您列出和查看行级权限政策所需的权限:

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

如需详细了解 BigQuery 中的 IAM 角色和权限,请参阅预定义的角色和权限

列出表行级访问权限政策

如需列出行级访问权限政策,请执行以下操作:

控制台

  1. 如需查看行级访问权限政策,请转到 Google Cloud 控制台中的 BigQuery 页面。

    转到 BigQuery

  2. 点击表名称以查看其详细信息,然后点击查看行访问权限政策

    查看行访问权限政策

  3. 行访问权限政策面板打开时,您会看到表的所有行级访问权限政策的列表(按名称列出)以及每个政策的 filter_expression

    行访问权限政策详细信息

  4. 如需查看受行级访问权限政策影响的所有角色和用户,请点击政策旁边的查看。例如,在下图中,您可以在查看权限面板中看到被授予者列表的成员具有 bigquery.filteredDataViewer 角色

    行访问权限政策详细信息

bq

输入 bq ls 命令并提供 --row_access_policies 标志。必须提供数据集和表名称。

    bq ls --row_access_policies dataset.table

例如,以下命令列出了与 ID 为 my_dataset 的数据集中 my_table 表的行级访问权限政策相关的信息:

    bq ls --row_access_policies my_dataset.my_table

API

使用 REST API 参考文档部分中的 RowAccessPolicies.List 方法

删除行级访问权限政策

如果您拥有权限,则可以使用 DDL 语句删除表的一个或所有行级访问权限政策。

所需权限

如需删除行级访问权限政策,您需要以下 IAM 权限:

  • bigquery.rowAccessPolicies.delete
  • bigquery.rowAccessPolicies.setIamPolicy
  • bigquery.jobs.create(用于运行 DDL 查询作业)

如需同时删除表的所有行级访问权限政策,您需要以下 IAM 权限:

  • bigquery.rowAccessPolicies.delete
  • bigquery.rowAccessPolicies.setIamPolicy
  • bigquery.rowAccessPolicies.list
  • bigquery.jobs.create(用于运行 DDL 查询作业)

以下每个预定义 IAM 角色都包含您删除行级访问权限政策所需的权限:

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

如需详细了解 BigQuery 中的 IAM 角色和权限,请参阅预定义的角色和权限

删除行级访问权限政策

如需从表中删除行访问权限政策,请使用以下 DDL 语句:

  • DROP ROW ACCESS POLICY 语句会删除所指定表的行级访问权限政策。

  • 如果所指定表上存在行访问权限政策,则 DROP ROW ACCESS POLICY IF EXISTS 语句会删除行级访问权限政策。

  • DROP ALL ROW ACCESS POLICIES 语句会删除所指定表的所有行级访问权限政策。

示例

从表中删除行级访问权限政策:

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

从表中删除所有行级访问权限政策:

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

如需详细了解如何删除行级访问权限政策,请参阅 DROP ROW ACCESS POLICY DDL 语句参考。

使用行访问权限政策查询表

用户必须具有 BigQuery 表的访问权限才能查询该表,即使用户在该表的行访问权限政策的 grantee_list 中也是如此。如果没有此权限,查询将失败并显示 access denied 错误。

所需权限

如需查询具有行级访问权限政策的 BigQuery 表,您需要拥有 bigquery.tables.getData IAM 权限和 bigquery.rowAccessPolicies.getFilteredData IAM 权限。您必须拥有所有相关表的 bigquery.tables.getData IAM 权限。

如需通过预定义角色获得这些权限,您需要 roles/bigquery.dataViewerroles/bigquery.filteredDataViewer IAM 角色。

您必须对具有列级安全性的所有相关列拥有 datacatalog.categories.fineGrainedGet 权限。如需通过预定义角色获取此权限,您需要 datacatalog.categoryFineGrainedReader 角色。

查看查询结果

在 Google Cloud 控制台中,当您查询具有行级访问权限政策的表时,BigQuery 会显示一个横幅通知,指出您的结果可能被行级访问权限政策过滤。即使您是政策的被授权者列表的成员,系统也会显示此通知。

针对具有行级访问权限政策的表的查询结果

作业统计信息

使用 Job API 查询具有行级访问权限政策的表时,BigQuery 会在 Job 响应对象中指示查询是否读取具有行访问权限政策的任何表:

示例

为简单起见,截断了此 Job 对象响应:

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

后续步骤