使用 IAM Conditions 控制访问权限
本文档介绍如何使用 IAM Conditions 控制对 BigQuery 资源的访问权限。
IAM Conditions 可让您仅在满足指定条件时才授予对 BigQuery 资源的访问权限。例如,您可以授予限定时长的资源访问权限,也可以固定地在每天的某几个小时允许访问资源。您可以在组织、文件夹、项目和数据集级别的资源中添加 IAM 条件。带条件的允许政策会由子资源继承。如需详细了解资源级别,请参阅资源层次结构。
IAM Conditions 条件可用于同时授予多个相关资源(包括尚不存在的资源)的 Identity and Access Management (IAM) 访问权限。如需授予不相关的 BigQuery 资源组的访问权限,请考虑使用 IAM 标记。
准备工作
所需的角色
如需获得将 IAM Conditions 应用于 BigQuery 资源所需的权限,请让您的管理员为您授予以下 IAM 角色:
- 
            对于项目:
              
  
  
    
      Project IAM Admin  (roles/resourcemanager.projectIamAdmin)
- 
            对于数据集:
              
  
  
    
      BigQuery Data Owner  (roles/bigquery.dataOwner)
如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
这些预定义角色可提供将 IAM Conditions 应用于 BigQuery 资源所需的权限。如需查看所需的确切权限,请展开所需权限部分:
所需权限
如需将 IAM Conditions 应用于 BigQuery 资源,需要具备以下权限:
- 
                在项目级层设置有条件的 IAM 访问权限:
                  
                
              resourcemanager.projects.setIamPolicy
- 
                为数据集设置条件式 IAM 访问权限:
                - 
                      bigquery.datasets.setIamPolicy
- 
                      bigquery.datasets.update
 
- 
                      
如需详细了解 BigQuery 中的 IAM 角色和权限,请参阅 IAM 简介。
启用 IAM API
如需启用 IAM API,请选择以下选项之一:
控制台
进入 Identity and Access Management (IAM) API 页面并启用该 API。
gcloud
gcloud services enable iam.googleapis.com
查看数据集的条件式访问权限政策
从下列选项中选择一项:
控制台
- 前往 BigQuery 页面。 
- 在左侧窗格中,点击 探索器:  - 如果您没有看到左侧窗格,请点击 展开左侧窗格以打开该窗格。 
- 在探索器窗格中,展开您的项目,点击数据集,然后选择一个数据集。 
- 点击 共享 > 权限。 
- 在关联角色旁边,点击条件 - 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 中某个组织、文件夹或项目添加条件式访问权限,请参阅带条件的允许政策。构建条件时,请参阅属性格式表。
向数据集添加有条件访问
如需向数据集添加条件,请选择以下方法之一。构建条件时,请参阅属性格式表。
控制台
- 前往 BigQuery 页面。 
- 在左侧窗格中,点击 探索器:  
- 在探索器窗格中,展开您的项目,点击数据集,然后选择一个数据集。 
- 在详细信息窗格中,点击 共享 > 权限。 
- 点击添加主账号。 
- 在新的主账号字段中,输入主账号。 
- 在选择角色列表中,选择预定义角色或自定义角色。 
- 点击添加 IAM 条件。 
- 使用条件属性向 - condition字段添加条件。
- 在添加 IAM 条件面板中,点击保存。 
- 在向 - 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 请求参数。
从数据集中移除有条件访问
如需从数据集中移除条件,请选择以下方法之一。构建条件时,请参阅属性格式表。
控制台
- 前往 BigQuery 页面。 
- 在左侧窗格中,点击 探索器:  
- 在探索器窗格中,展开您的项目,点击数据集,然后选择一个数据集。 
- 在详细信息窗格中,点击 共享 > 权限。 
- 选择要撤销其访问权限的主账号。 
- 点击 删除。 
- 在删除主账号?对话框中,点击删除。 
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 | 支持 hasTagKey、hasTagKeyId、matchTag和matchTagId。如需了解详情,请参阅资源标记。 | 
为 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 | 支持 hasTagKey、hasTagKeyId、matchTag和matchTagId。如需了解详情,请参阅资源标记。 | 
为 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.type、resource.name和resource.service使用正面条件,以提高准确性。由于不受支持的类型由空字符串表示,因此否定条件可能会匹配大量资源。如需了解详情,请参阅否定条件。
- 数据集级别的 IAM 条件应仅用于适用于数据集中资源(例如表、视图、模型和例程)的角色。不应使用这些角色来授予在数据集或项目级别(例如 bigquery.user或bigquery.jobUser)下运行的角色。
- 请勿将条件 resource.type == 'bigquery.googleapis.com/Dataset'用于数据集级政策,因为它不会影响授权。此属性旨在控制对子数据集资源(例如表、视图、例程和模型)的访问权限。
- 在条件中包含 resource.type、resource.name和resource.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 } }
后续步骤
- 详细了解如何使用 IAM Conditions 条件配置临时访问权限。
- 详细了解如何使用 IAM Conditions 条件配置基于资源的访问权限。