控制对数据集的访问权限

本文档介绍了如何在 BigQuery 中控制对数据集的访问权限。

您还可以在表/视图级层以及 Cloud IAM 资源层次结构中的较高级层控制访问权限。

您可以利用 BigQuery 的列级安全性来限制对列的访问权限。

概览

数据集级层权限决定着可以访问特定数据集中的表、视图和表数据的用户、群组和服务帐号。例如,如果将 bigquery.dataOwner Cloud IAM 角色授予特定数据集上的用户,则该用户可以在该数据集中创建、更新、删除表和视图。

您可以通过调用 datasets.insert API 方法在数据集创建期间应用访问权限控制。

使用 Cloud Console、经典版 BigQuery 网页界面或 bq 命令行工具创建数据集期间,您 无法 应用访问权限控制。

您可以在创建数据集之后通过以下方式对数据集应用访问权限控制:

  • 使用 Cloud Console 或经典版 BigQuery 网页界面
  • bq 命令行工具中使用 bq update 命令
  • 调用 datasets.patch API 方法
  • 使用客户端库

所需权限

如需分配或更新数据集访问权限控制,您至少必须具有 bigquery.datasets.updatebigquery.datasets.get 权限。以下预定义的 Cloud IAM 角色包含 bigquery.datasets.updatebigquery.datasets.get 权限:

  • bigquery.dataOwner
  • bigquery.admin

此外,如果用户具有 bigquery.datasets.create 权限,则当该用户创建数据集时,系统会为其授予该数据集的 bigquery.dataOwner 访问权限。借助 bigquery.dataOwner 访问权限,用户可以更新其创建的数据集。

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

控制对数据集的访问权限

如需分配对数据集的访问权限控制,请执行以下操作:

Console

  1. 资源中选择一个数据集,然后点击窗口右侧附近的共享数据集

    向数据集添加人员

  2. 共享数据集面板的数据集权限标签页中,在添加成员文本框中输入要添加的实体。您可以添加以下任何实体:

    • Google 帐号电子邮件地址:向某个 Google 帐号授予对数据集的访问权限
    • Google 群组:向某个 Google 群组的所有成员授予对数据集的访问权限
    • Google Apps 网域:向某个 Google 网域中的所有用户和群组授予对数据集的访问权限
    • 服务帐号:向某个服务帐号授予对数据集的访问权限
    • 任何人:输入“allUsers”可向公众授予访问权限
    • 所有 Google 帐号:输入“allAuthenticatedUsers”可向任何已登录到 Google 帐号的用户授予访问权限
  3. 对于选择角色,请选择 BigQuery 并为新成员选择适当的预定义 IAM 角色。如需详细了解分配给每个预定义 BigQuery 角色的权限,请参阅访问权限控制页面的角色部分。

  4. 点击完成

经典版界面

  1. 点击数据集右侧的下拉箭头并选择 Share Dataset

  2. Share Dataset 对话框中,对于 Add People,点击该字段左侧的下拉列表,然后选择适当的选项。当您使用经典版网页界面对数据集应用访问权限控制时,您可以向以下用户和群组授予访问权限:

    • 用户(按电子邮件地址)(User by e-mail) - 向某个 Google 帐号授予对数据集的访问权限
    • 群组(按电子邮件地址)(Group by e-mail) - 向某个 Google 群组的所有成员授予对数据集的访问权限
    • 网域 - 向某个 Google 网域中的所有用户和群组授予对数据集的访问权限
    • 所有经过身份验证的用户 (All Authenticated Users) - 向所有 Google 帐号拥有者授予对数据集的访问权限(将数据集设为公开)
    • 项目所有者 (Project Owners) - 向所有项目所有者授予对数据集的访问权限
    • 项目查看者 (Project Viewers) - 向所有项目查看者授予对数据集的访问权限
    • 项目编辑者 (Project Editors) - 向所有项目编辑者授予对数据集的访问权限
    • 已获授权的视图 (Authorized View) - 向视图授予对数据集的访问权限

  3. 在文本框中输入一个值。例如,如果选择 User by e-mailGroup by e-mail,请输入相应用户或群组的电子邮件地址。

  4. Add People 字段右侧,点击 Can view 并从列表中选择适当的角色。

    向数据集添加人员

  5. 点击 Add,然后点击 Save changes

bq

  1. 使用 show 命令将现有数据集信息(包括访问权限控制设置)写入 JSON 文件。如果数据集不属于默认项目,请按以下格式将相应项目 ID 添加到数据集名称中:project_id:dataset

    bq show \
    --format=prettyjson \
    project_id:dataset > path_to_file
    

    其中:

    • project_id 是您的项目 ID。
    • dataset 是您的数据集的名称。
    • path_to_file 是本地机器上 JSON 文件的路径。

    示例:

    输入以下命令可将 mydataset 的访问权限控制写入 JSON 文件。mydataset 属于默认项目。

      bq show --format=prettyjson mydataset > /tmp/mydataset.json
    

    输入以下命令可将 mydataset 的访问权限控制写入 JSON 文件。mydataset 属于 myotherproject

      bq show --format=prettyjson \
      myotherproject:mydataset > /tmp/mydataset.json
    
  2. 对 JSON 文件的 "access" 部分进行更改。您可以添加或移除任意 specialGroup 条目:projectOwnersprojectWritersprojectReadersallAuthenticatedUsers。还可以添加、移除或修改以下任一项:userByEmailgroupByEmaildomain

    例如,某个数据集的 JSON 文件的 access 部分可能如下所示:

    {
     "access": [
      {
       "role": "READER",
       "specialGroup": "projectReaders"
      },
      {
       "role": "WRITER",
       "specialGroup": "projectWriters"
      },
      {
       "role": "OWNER",
       "specialGroup": "projectOwners"
      },
      {
       "role": "READER",
       "specialGroup": "allAuthenticatedUsers"
      },
      {
       "role": "READER",
       "domain": "domain_name"
      },
      {
       "role": "WRITER",
       "userByEmail": "user_email"
      },
      {
       "role": "READER",
       "groupByEmail": "group_email"
      }
     ],
     ...
    }
    

  3. 修改完成后,运行 update 命令,并用 --source 标志包括该 JSON 文件。如果数据集不属于默认项目,请按以下格式将相应项目 ID 添加到数据集名称中:project_id:dataset

    bq update \
    --source path_to_file \
    project_id:dataset
    

    其中:

    • path_to_file 是本地机器上 JSON 文件的路径。
    • project_id 是您的项目 ID。
    • dataset 是您的数据集的名称。

    示例:

    输入以下命令可更新 mydataset 的访问权限控制。mydataset 属于默认项目。

        bq update --source /tmp/mydataset.json mydataset
    

    输入以下命令可更新 mydataset 的访问权限控制。mydataset 属于 myotherproject

        bq update --source /tmp/mydataset.json myotherproject:mydataset
    
  4. 如需验证您的访问权限控制发生了变化,请再次输入 show 命令,但不要将信息写入文件。

    bq show --format=prettyjson dataset
    

    bq show --format=prettyjson project_id:dataset
    

API

在创建数据集后,使用已定义的数据集资源调用 datasets.insert,以应用访问权限控制。调用 datasets.patch 并使用数据集资源中的 access 属性更新访问权限控制。

由于 datasets.update 方法会替换整个数据集资源,因此建议使用 datasets.patch 方法来更新访问权限控制。

Go

在尝试此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Go 设置说明进行操作。如需了解详情,请参阅 BigQuery Go API 参考文档

使用数据集的访问权限控制设置 dataset.access_entries 属性,然后调用 client.update_dataset() 函数来更新该属性。

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// updateDatasetAccessControl demonstrates how the access control policy of a dataset
// can be amended by adding an additional entry corresponding to a specific user identity.
func updateDatasetAccessControl(projectID, datasetID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	ds := client.Dataset(datasetID)
	meta, err := ds.Metadata(ctx)
	if err != nil {
		return err
	}
	// Append a new access control entry to the existing access list.
	update := bigquery.DatasetMetadataToUpdate{
		Access: append(meta.Access, &bigquery.AccessEntry{
			Role:       bigquery.ReaderRole,
			EntityType: bigquery.UserEmailEntity,
			Entity:     "sample.bigquery.dev@gmail.com"},
		),
	}

	// Leverage the ETag for the update to assert there's been no modifications to the
	// dataset since the metadata was originally read.
	if _, err := ds.Update(ctx, update, meta.ETag); err != nil {
		return err
	}
	return nil
}

Python

在尝试此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Python 设置说明进行操作。如需了解详情,请参阅 BigQuery Python API 参考文档

使用数据集的访问权限控制设置 dataset.access_entries 属性,然后调用 client.update_dataset() 函数来更新该属性。
from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

# TODO(developer): Set dataset_id to the ID of the dataset to fetch.
# dataset_id = 'your-project.your_dataset'

dataset = client.get_dataset(dataset_id)  # Make an API request.

entry = bigquery.AccessEntry(
    role="READER",
    entity_type="userByEmail",
    entity_id="sample.bigquery.dev@gmail.com",
)

entries = list(dataset.access_entries)
entries.append(entry)
dataset.access_entries = entries

dataset = client.update_dataset(dataset, ["access_entries"])  # Make an API request.

full_dataset_id = "{}.{}".format(dataset.project, dataset.dataset_id)
print(
    "Updated dataset '{}' with modified user permissions.".format(full_dataset_id)
)

后续步骤