控制对数据集的访问权限

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

除此之外,您还可以实现以下目的:

概览

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

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

在通过 Cloud Console 或 bq 命令行工具创建数据集期间,无法应用访问权限控制。

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

  • 使用 Cloud Console。
  • bq 命令行工具中使用 bq update 命令。
  • 调用 datasets.patch API 方法。
  • 使用客户端库。

所需权限

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

  • bigquery.dataOwner
  • bigquery.admin

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

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

控制对数据集的访问权限

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

Console

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

    向数据集添加人员

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

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

  4. 点击完成

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
}

Java

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

import com.google.cloud.bigquery.Acl;
import com.google.cloud.bigquery.Acl.Role;
import com.google.cloud.bigquery.Acl.User;
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Dataset;
import java.util.ArrayList;

public class UpdateDatasetAccess {

  public static void main(String[] args) {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    // Create a new ACL granting the READER role to "sample.bigquery.dev@gmail.com"
    // For more information on the types of ACLs available see:
    // https://cloud.google.com/storage/docs/access-control/lists
    Acl newEntry = Acl.of(new User("sample.bigquery.dev@gmail.com"), Role.READER);

    updateDatasetAccess(datasetName, newEntry);
  }

  public static void updateDatasetAccess(String datasetName, Acl newEntry) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      Dataset dataset = bigquery.getDataset(datasetName);

      // Get a copy of the ACLs list from the dataset and append the new entry
      ArrayList<Acl> acls = new ArrayList<>(dataset.getAcl());
      acls.add(newEntry);

      bigquery.update(dataset.toBuilder().setAcl(acls).build());
      System.out.println("Dataset Access Control updated successfully");
    } catch (BigQueryException e) {
      System.out.println("Dataset Access control was not updated \n" + e.toString());
    }
  }
}

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

后续步骤