使用 IAM Conditions 控制访问权限

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

IAM Conditions 可让您仅在满足指定条件时才授予对 BigQuery 资源的访问权限。例如,您可以授予限定时长的资源访问权限,也可以固定地在每天的某几个小时允许访问资源。IAM Conditions 条件在项目、文件夹和组织级层受支持,并且可以应用于 BigQuery 数据集、表、例程和模型。

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

须知事项

启用 IAM API 并授予为用户提供执行本文档中的每个任务所需权限的 IAM 角色。

启用 IAM API

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

控制台

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

启用该 API

gcloud

运行 gcloud services enable 命令

gcloud services enable iam.googleapis.com

所需权限

如需获得将 IAM Conditions 应用于 BigQuery 资源所需的权限,请让您的管理员为您授予 Project IAM Admin (roles/resourcemanager.projectIamAdmin) IAM 角色。如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

此预定义角色可提供 resourcemanager.projects.setIamPolicy 权限,将 IAM Conditions 应用于 BigQuery 资源需要此权限。

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

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

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

条件特性

您可以根据以下属性在 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 中的数据集、表、例程或模型添加条件,请参阅带条件的允许政策。构建条件时,请参阅属性格式表

条件最佳实践

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

  • 不要为 resource.typeresource.nameresource.service 使用否定条件,因为不受支持的类型会使用空字符串并且几乎匹配所有否定条件。如需了解详情,请参阅否定条件
  • 在条件中包含 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 添加授权视图授权例程授权数据集授权。
  • 当用户拥有对数据集或表的有条件访问权限时,他们无法通过 Google Cloud 控制台修改对该资源的权限。仅支持使用 bq 工具和 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
  }
}

后续步骤