使用 IAM Conditions 控制访问权限

本文档介绍如何使用 IAM Conditions 控制对 BigQuery 资源的访问权限。

IAM Conditions 可让您仅在满足指定条件时才授予对 BigQuery 资源的访问权限。例如,您可以授予限定时长的资源访问权限,也可以固定地在每天的某几个小时允许访问资源。您可以在资源的组织、文件夹、项目和数据集级添加 IAM 条件。带条件的允许政策会由子资源继承。如需详细了解资源级别,请参阅资源层次结构

IAM Conditions 条件可用于同时向多个相关资源(包括尚不存在的资源)授予 Identity and Access Management (IAM) 访问权限。如需授予不相关的 BigQuery 资源组的访问权限,请考虑使用 IAM 标记

准备工作

  1. 向用户授予 IAM 角色,其中包含执行本文档中每项任务所需的权限。
  2. 启用 IAM API

所需的角色

如需获得将 IAM Conditions 条件应用于 BigQuery 资源所需的权限,请让您的管理员为您授予以下 IAM 角色:

如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

这些预定义角色包含将 IAM Conditions 条件应用于 BigQuery 资源所需的权限。如需查看所需的确切权限,请展开所需权限部分:

所需权限

如需将 IAM Conditions 条件应用于 BigQuery 资源,您需要具备以下权限:

  • 在项目级设置基于条件的 IAM 访问权限: resourcemanager.projects.setIamPolicy
  • 为数据集设置条件式 IAM 访问权限:
    • bigquery.datasets.setIamPolicy
    • bigquery.datasets.update

您也可以使用自定义角色或其他预定义角色来获取这些权限。

如果您计划在整个组织中使用 IAM Conditions 条件,则还需要管理组织政策的权限

如需详细了解 BigQuery 中的 IAM 角色和权限,请参阅 IAM 简介

启用 IAM API

如需启用 IAM API,请选择以下选项之一:

控制台

进入 Identity and Access Management (IAM) API 页面并启用该 API。

启用该 API

gcloud

运行 gcloud services enable 命令

gcloud services enable iam.googleapis.com

查看数据集的条件式访问权限政策

从下列选项中选择一项:

控制台

  1. 转到 BigQuery 页面。

    转到 BigQuery

  2. 浏览器窗格中,展开您的项目,然后选择数据集。

  3. 依次点击 共享 > 权限

  4. 点击关联角色旁边的 condition:TITLE,查看该角色的条件。

bq

如需在 Cloud Shell 中查看或更新条件访问权限政策,您必须使用 Cloud Shell 503.0.0 或更高版本。

如需获取现有访问权限政策并将其输出到 JSON 格式的本地文件,请使用 Cloud Shell 中的 bq show 命令

bq show --format=prettyjson PROJECT_ID:DATASET > PATH_TO_FILE

替换以下内容:

  • PROJECT_ID:您的项目 ID
  • DATASET:您的数据集的名称。
  • PATH_TO_FILE:本地机器上 JSON 文件的路径

数据集资源 JSON 文件中的 access 属性包含访问权限政策。

API

如需查看带有条件的数据集的访问权限政策,请使用 accessPolicyVersion=3 作为请求参数调用 datasets.get。数据集资源中的 access 属性包含访问权限政策。

修改资源的条件访问权限

以下部分介绍了如何添加或移除对不同资源的有条件访问权限。

向组织、文件夹或项目添加条件

如需在 BigQuery 中向组织、文件夹或项目添加有条件的访问权限,请参阅带条件的允许政策。构建条件时,请参阅属性格式表

为数据集添加有条件访问权限

如需向数据集添加条件,请选择以下方法之一。构建条件时,请参阅属性格式表

控制台

  1. 转到 BigQuery 页面。

    转到 BigQuery

  2. 浏览器窗格中,展开您的项目,然后选择数据集。

  3. 在详细信息面板中,依次点击 共享 > 权限

  4. 点击 添加主账号

  5. 新的主账号字段中,输入主账号。

  6. 选择角色列表中,选择预定义角色或自定义角色。

  7. 点击添加 IAM 条件

  8. 使用条件属性condition 字段添加条件。

  9. Add IAM condition 面板中,点击 Save

  10. DATASET 授予访问权限面板中,点击保存

bq

如需在 Cloud Shell 中查看或更新条件访问权限政策,您必须使用 Cloud Shell 503.0.0 或更高版本。

如需使用 Cloud Shell 向数据集授予条件式访问权限,请按照向数据集授予访问权限中的说明操作。您可以将条件式访问权限条件添加到数据集 JSON 文件的 access 部分。

例如,如果在数据集 JSON 文件的 access 部分中添加以下内容,系统会向 cloudysanfrancisco@gmail.com 授予 roles/bigquery.dataViewer 角色,有效期为 2032 年 12 月 31 日:

"access": [
  {
    "role": "roles/bigquery.dataViewer",
    "userByEmail": "cloudysanfrancisco@gmail.com",
    "condition": {
      "title": "Grant roles/bigquery.dataViewer until 2033",
      "description": "Role expires on December 31, 2032.",
      "expression": "request.time < timestamp('2032-12-31T12:00:00Z')"
    }
  }
]

API

如需使用 BigQuery API 授予对数据集的有条件访问权限,请按照授予对数据集的访问权限中的说明操作,并在请求参数中使用 accessPolicyVersion=3

您可以向数据集资源的 access.condition 属性添加包含访问条件的条目。

对于具有条件访问权限政策的数据集,用户可以使用标准的读取、修改和更新流程来更新无条件访问权限设置,而无需指定 accessPolicyVersion 请求参数。

从数据集中移除条件式访问权限

如需从数据集中移除条件,请选择以下方法之一。构建条件时,请参阅属性格式表

控制台

  1. 转到 BigQuery 页面。

    转到 BigQuery

  2. 浏览器窗格中,展开您的项目,然后选择数据集。

  3. 在详细信息面板中,依次点击 共享 > 权限

  4. 选择要撤消其访问权限的主账号。

  5. 点击 删除

  6. 删除主账号?对话框中,点击删除

bq

如需在 Cloud Shell 中查看或更新条件访问权限政策,您必须使用 Cloud Shell 503.0.0 或更高版本。

如需使用 Cloud Shell 移除对数据集的有条件访问权限,请按照撤消对数据集的访问权限中的说明操作。 您可以从数据集 JSON 文件的 access 部分移除带条件的条目。

API

如需使用 BigQuery API 撤消对数据集的有条件访问权限,请按照撤消对数据集的访问权限中的说明操作,并在请求参数中使用 accessPolicyVersion=3

您可以从数据集资源的 access 属性中移除包含条件的条目。

对于具有条件访问权限政策的数据集,用户可以使用标准的读取、修改和更新流程来更新无条件访问权限设置,而无需指定 accessPolicyVersion 请求参数。

条件特性

您可以根据以下属性在 BigQuery 资源上设置 IAM Conditions 条件:

  • request.time:用户尝试访问 BigQuery 资源的时间。如需了解详情和示例,请参阅日期/时间属性
  • resource.name:BigQuery 资源的路径。如需了解格式,请查看属性格式中的表。
  • resource.type:BigQuery 资源的类型。如需了解格式,请查看属性格式中的表。
  • resource.service:BigQuery 资源使用的 Google Cloud 服务。如需了解格式,请查看属性格式中的表。
  • resource.tags:附加到 BigQuery 资源的标记。只有 BigQuery 数据集、表和视图资源支持标记。如需了解格式,请参阅属性格式IAM 文档中的表。

属性格式

为 BigQuery 数据集创建条件时,请使用以下格式:

属性
resource.type bigquery.googleapis.com/Dataset
resource.name projects/PROJECT_ID/datasets/DATASET_ID
resource.service bigquery.googleapis.com
resource.tags 支持 hasTagKeyhasTagKeyIdmatchTagmatchTagId。如需了解详情,请参阅资源标记

为 BigQuery 表和视图创建条件时,请使用以下格式:

属性
resource.type bigquery.googleapis.com/Table
resource.name projects/PROJECT_ID/datasets/DATASET_ID/tables/TABLE_ID
resource.service bigquery.googleapis.com
resource.tags 支持 hasTagKeyhasTagKeyIdmatchTagmatchTagId。如需了解详情,请参阅资源标记

为 BigQuery 例程创建条件时,请使用以下格式:

属性
resource.type bigquery.googleapis.com/Routine
resource.name projects/PROJECT_ID/datasets/DATASET_ID/routines/ROUTINE_ID
resource.service bigquery.googleapis.com

为 BigQuery 模型创建条件时,请使用以下格式:

属性
resource.type bigquery.googleapis.com/Model
resource.name projects/PROJECT_ID/datasets/DATASET_ID/models/MODEL_ID
resource.service bigquery.googleapis.com

替换以下内容:

  • PROJECT_ID:项目 ID,此项目包含您要授予访问权限的资源
  • DATASET_ID:您要授予访问权限的数据集的 ID
  • TABLE_ID:您要授予访问权限的表或视图的 ID
  • ROUTINE_ID:您要授予访问权限的例程的 ID
  • MODEL_ID:您要授予访问权限的模型的 ID

条件最佳实践

在 BigQuery 中构建条件时,请遵循以下最佳实践:

  • 我们建议为 resource.typeresource.nameresource.service 使用肯定条件,以提高准确性。由于不受支持的类型由空字符串表示,因此否定条件可能会与各种资源匹配。如需了解详情,请参阅否定条件
  • 数据集级 IAM 条件应仅用于应用于数据集内资源(例如表、视图、模型和例程)的角色。不应使用这些角色来授予在数据集或项目级运行的角色,例如 bigquery.userbigquery.jobUser
  • 请勿对数据集级政策使用条件 resource.type == 'bigquery.googleapis.com/Dataset',因为它对授权没有影响。此属性旨在控制对子数据集资源(例如表、视图、例程和模型)的访问权限。
  • 在条件中包含 resource.typeresource.nameresource.service,即使不需要这样的具体程度也请这么做。这种做法有助于在工作流中的资源更改时维持您的条件,从而避免将来意外加入其他资源。
  • 授予权限时,请尽可能使用一组最小权限,以确保您不会无意中授予过于宽松的访问权限。
  • 请谨慎使用 resource.name.startsWith。BigQuery 表和视图路径以其父级项目 ID 和数据集 ID 为前缀。条件不够具体可能会授予过多的访问权限。不过,您可以使用 resource.name.startsWith 属性让用户对表运行通配符查询。例如,使用 resource.name.startsWith("projects/my_project/datasets/my_dataset/tables/table_prefix") 条件授予的访问权限可让用户运行 SELECT * FROM my_dataset.table_prefix* 查询。
  • 请勿为数据集、表、视图、例程和模型以外的 BigQuery 资源添加条件。
  • 验证您是否授予了对正确资源的正确权限。例如,用于列出资源的权限 (bigquery.RESOURCE.list) 必须在父级层授予,但用于删除资源的权限 (bigquery.RESOURCE.delete) 必须在资源级层授予。数据集删除操作(其中包含的所有资源也会被删除)需要数据集上的表、模型和例程删除权限。
  • 注意,表快照时间旅行对权限没有影响。

否定条件

resource.name != resource 等否定条件可能会无意中授予过于宽松的访问权限。不受支持的 BigQuery 资源具有空资源属性,这意味着它们会匹配所有否定条件。BigQuery 外部的服务中的资源也可能匹配否定条件。

此外,当用户使用通配符运行查询时,否定条件会造成问题。例如,假设有否定条件 resource.name != /projects/my_project/datasets/my_dataset/tables/secret。此条件会授予对除了名为 secret 的表以外所有资源的访问权限。但是,用户仍然可以使用通配符查询(如 SELECT * from my_project.my_dataset.secre*;)查询该表。

此外,表、例程和模型上的否定条件可能会授予对其父数据集的过于宽松的访问权限。然后,用户可能可以删除这些资源,因为删除权限在数据集级层进行管理。

限制

  • 您不能使用 IAM Conditions 添加已获授权的视图已获授权的例程已获授权的数据集授权。
  • 如果在查看带有条件的资源时使用了不兼容的 accessPolicyVersion,则绑定可能包含 withcond 后跟哈希值。如需了解详情,请参阅排查政策和角色绑定中的 withcond 问题
  • 拥有对数据集或表的有条件访问权限的用户无法通过 Google Cloud 控制台修改对该资源的权限。仅支持通过 bq 工具和 BigQuery API 修改权限。
  • 无法通过 IAM Conditions 条件直接支持行级和列级访问权限控制。但是,具备有条件访问权限的用户可以给自己授予表的 BigQuery Admin 角色 (roles/bigquery.admin),然后修改行和列访问权限政策。
  • 对 IAM 政策的更改最长可能需要五分钟才能生效。
  • 具备有条件访问权限的用户可能无法查询 INFORMATION_SCHEMA 视图
  • 仅拥有条件式表访问权限的用户无法运行表通配符函数

示例

以下是 BigQuery 中 IAM Conditions 条件的应用场景示例。

授予特定表的读取权限

此示例向 cloudysanfrancisco@gmail.com 授予 dataset_1 数据集中 table_1 表的 BigQuery Data Viewer 角色。拥有此角色的用户可以通过 bq 工具查询和访问该表。用户无法在 Google Cloud 控制台中查看该表,因为他们没有数据集的 bigquery.tables.list 权限。

{
  "members": [cloudysanfrancisco@gmail.com],
  "role": roles/bigquery.dataViewer,
  "condition": {
    "title": "Table dataset_1.table_1",
    "description": "Allowed to read table with name table_1 in dataset_1 dataset",
    "expression":
resource.name == projects/project_1/datasets/dataset_1/tables/table_1
&& resource.type == bigquery.googleapis.com/Table
  }
}

授予特定数据集的列出权限

此示例向 cloudysanfrancisco@gmail.com 授予 dataset_2 数据集的 BigQuery Metadata Viewer 角色。拥有此角色的用户可以列出该数据集中的所有资源,但无法对这些资源执行任何查询。

{
  "members": [cloudysanfrancisco@gmail.com],
  "role": roles/bigquery.metadataViewer,
  "condition": {
    "title": "Dataset dataset_2",
    "description": "Allowed to list resources in dataset_2 dataset",
    "expression":
resource.name == projects/project_2/datasets/dataset_2
&& resource.type == bigquery.googleapis.com/Dataset
  }
}

授予所有数据集中具有特定前缀的所有表的所有者权限

此示例向 cloudysanfrancisco@gmail.com 授予所有数据集中具有 public_ 前缀的所有表的 BigQuery Data Owner 角色:

{
  "members": [cloudysanfrancisco@gmail.com],
  "role": roles/bigquery.dataOwner,
  "condition": {
    "title": "Tables public_",
    "description": "Allowed owner access to tables in datasets with public_ prefix",
    "expression":
resource.name.startsWith("projects/project_3/datasets/public_")
&& resource.type == bigquery.googleapis.com/Table
  }
}

授予所有数据集中具有特定前缀的所有表、模型和例程的所有者权限

此示例向 cloudysanfrancisco@gmail.com 授予所有数据集中具有 general_ 前缀的表、模型和例程的 BigQuery Data Owner 角色:

{
  "members": [cloudysanfrancisco@gmail.com],
  "role": roles/bigquery.dataOwner,
  "condition": {
    "title": "Tables general_",
    "description": "Allowed owner access to tables in datasets with general_ prefix",
    "expression":
resource.name.startsWith("projects/project_4/datasets/general_")
&& resource.type == bigquery.googleapis.com/Table
  }
},
{
  "members": [cloudysanfrancisco@gmail.com],
  "role": roles/bigquery.dataOwner,
  "condition": {
    "title": "Models general_",
    "description": "Allowed owner access to models in datasets with general_ prefix",
    "expression":
resource.name.startsWith("projects/project_4/datasets/general_")
&& resource.type == bigquery.googleapis.com/Model
  }
},
{
  "members": [cloudysanfrancisco@gmail.com],
  "role": roles/bigquery.dataOwner,
  "condition": {
    "title": "Routines general_",
    "description": "Allowed owner access to routines in datasets with general_ prefix",
    "expression":
resource.name.startsWith("projects/project_4/datasets/general_")
&& resource.type == bigquery.googleapis.com/Routine
  }
}

后续步骤