設定來源的存取權:Cloud Storage

Storage 移轉服務會使用 Google 管理的服務帳戶 (又稱服務代理程式),將資料從 Cloud Storage 來源值區移出。第一次呼叫 googleServiceAccounts.get 時,系統會建立這個服務代理程式。

來源 bucket 不必與服務代理程式位於相同專案。無論值區位於哪個專案,步驟都相同。

使用者權限

如要授予服務代理必要權限,您必須具備來源 bucket 的相關權限:

  • storage.buckets.getIamPolicy
  • storage.buckets.setIamPolicy

Storage 舊版值區擁有者角色 (roles/storage.legacyBucketOwner) 或 Storage 管理員角色 (roles/storage.admin) 均提供必要權限。

在 Google Cloud 控制台中自動授予權限

如果您使用 Google Cloud 主控台建立轉移作業,且具備使用者權限中列出的權限,系統就會自動將來源 bucket 的必要權限授予服務代理。

您可以略過這個頁面的步驟,直接建立轉移作業

所需權限

服務代理必須具備來源值區的下列權限:

權限 說明
storage.buckets.get 允許服務代理取得值區的位置。
storage.objects.list 允許服務代理列出值區中的物件。
storage.objects.get 允許服務代理讀取值區中的物件。
storage.objects.create

允許服務代理程式在值區中建立物件。如果轉移至檔案系統,則為必要項目。

Storage 移轉服務會在來源值區中建立並填入兩個資料夾:cloud-ingest/ 包含檔案系統資訊,storage-transfer/ 包含移轉記錄。

storage.objects.delete 允許服務代理人刪除值區中的物件。如果將 deleteObjectsFromSourceAfterTransfer 設為 true,就需提供這個屬性。
storage.objects.getIamPolicy 允許服務代理程式讀取來源物件的 ACL。如果已啟用物件 ACL 保留功能 (ACL_PRESERVE),則為必要選項。

下列預先定義的角色會授予必要權限:

  • 下列其中一項:
    • Storage 物件檢視器 (roles/storage.objectViewer),前提是轉移至另一個 Cloud Storage bucket。
    • 如果移轉至檔案系統,則需要 Storage 物件建立者 (roles/storage.objectCreator)。
  • 以及下列其中一項:
    • Storage 舊版值區寫入者 (roles/storage.legacyBucketWriter) (如需物件刪除權限)。
    • Storage 舊版值區讀取者 (roles/storage.legacyBucketReader),如果不需要物件刪除權限。
  • 此外,如果使用 ACL_PRESERVE 保留物件 ACL
    • Storage 舊版物件擁有者 (roles/storage.legacyObjectOwner)

標示為 legacy 角色的 Cloud Storage 角色只能在 bucket 層級授予。

如需 Cloud Storage 角色的完整清單及其權限,請參閱身分與存取權管理角色一文。

授予必要權限

如要授予服務代理人必要權限,請按照下列步驟操作。

找出服務代理的電子郵件地址

  1. 前往googleServiceAccounts.get參考資料頁面

    系統會開啟互動式面板,標題為「試試這個方法」

  2. 在面板的「Request parameters」下方,輸入專案 ID。您在此指定的專案必須是用於管理 Storage 移轉服務的專案,可能與來源值區的專案不同。

  3. 點選「Execute」

    服務專員的電子郵件地址會以 accountEmail 的值傳回。複製這個值。

    服務代理商的電子郵件地址格式為 project-PROJECT_NUMBER@storage-transfer-service.iam.gserviceaccount.com

將服務代理程式新增至 bucket 層級政策

控制台

  1. 前往 Google Cloud 控制台的「Cloud Storage bucket」頁面。

    前往「Buckets」(值區) 頁面

  2. 針對要將角色授予主體的值區,按一下「值區溢位」選單 ()。

  3. 選擇「編輯權限」

  4. 按一下「+ Add principal」(新增主體) 按鈕。

  5. 在「新增主體」欄位中,輸入服務代理人的帳戶電子郵件地址。

  6. 從「Select a role」(選取角色) 下拉式選單中選取 Storage Object ViewerStorage Object Creator

  7. 按一下 [Add another role] (新增其他角色)

  8. 選取「Storage Legacy Bucket Writer」或「Storage Legacy Bucket Reader」。

  9. 按一下 [儲存]

gcloud

使用 gcloud storage buckets add-iam-policy-binding 指令:

gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
--member=serviceAccount:YOUR_AGENT_EMAIL --role=roles/storage.objectViewer
gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
--member=serviceAccount:YOUR_AGENT_EMAIL --role=roles/storage.legacyBucketReader

更改下列內容:

程式碼範例

C++

如要瞭解如何安裝及使用 Cloud Storage 的用戶端程式庫,請參閱「Cloud Storage 用戶端程式庫」。詳情請參閱「Cloud Storage C++ API 參考文件」。

如要向 Cloud Storage 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證作業」。

namespace gcs = ::google::cloud::storage;
using ::google::cloud::StatusOr;
[](gcs::Client client, std::string const& bucket_name,
   std::string const& role, std::string const& member) {
  auto policy = client.GetNativeBucketIamPolicy(
      bucket_name, gcs::RequestedPolicyVersion(3));

  if (!policy) throw std::move(policy).status();

  policy->set_version(3);
  for (auto& binding : policy->bindings()) {
    if (binding.role() != role || binding.has_condition()) {
      continue;
    }
    auto& members = binding.members();
    if (std::find(members.begin(), members.end(), member) == members.end()) {
      members.emplace_back(member);
    }
  }

  auto updated = client.SetNativeBucketIamPolicy(bucket_name, *policy);
  if (!updated) throw std::move(updated).status();

  std::cout << "Updated IAM policy bucket " << bucket_name
            << ". The new policy is " << *updated << "\n";
}

C#

如要瞭解如何安裝及使用 Cloud Storage 的用戶端程式庫,請參閱「Cloud Storage 用戶端程式庫」。詳情請參閱「Cloud Storage C# API 參考文件」。

如要向 Cloud Storage 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證作業」。


using Google.Apis.Storage.v1.Data;
using Google.Cloud.Storage.V1;
using System;
using System.Collections.Generic;

public class AddBucketIamMemberSample
{
    public Policy AddBucketIamMember(
        string bucketName = "your-unique-bucket-name",
        string role = "roles/storage.objectViewer",
        string member = "serviceAccount:dev@iam.gserviceaccount.com")
    {
        var storage = StorageClient.Create();
        var policy = storage.GetBucketIamPolicy(bucketName, new GetBucketIamPolicyOptions
        {
            RequestedPolicyVersion = 3
        });
        // Set the policy schema version. For more information, please refer to https://cloud.google.com/iam/docs/policies#versions.
        policy.Version = 3;

        Policy.BindingsData bindingToAdd = new Policy.BindingsData
        {
            Role = role,
            Members = new List<string> { member }
        };

        policy.Bindings.Add(bindingToAdd);
        var bucketIamPolicy = storage.SetBucketIamPolicy(bucketName, policy);
        Console.WriteLine($"Added {member} with role {role} " + $"to {bucketName}");
        return bucketIamPolicy;
    }
}

Go

如要瞭解如何安裝及使用 Cloud Storage 的用戶端程式庫,請參閱「Cloud Storage 用戶端程式庫」。詳情請參閱「Cloud Storage Go API 參考文件」。

如要向 Cloud Storage 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證作業」。

import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/iam"
	"cloud.google.com/go/storage"
)

// addBucketIAMMember adds the bucket IAM member to permission role.
func addBucketIAMMember(w io.Writer, bucketName string) error {
	// bucketName := "bucket-name"
	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("storage.NewClient: %w", err)
	}
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, time.Second*10)
	defer cancel()

	bucket := client.Bucket(bucketName)
	policy, err := bucket.IAM().Policy(ctx)
	if err != nil {
		return fmt.Errorf("Bucket(%q).IAM().Policy: %w", bucketName, err)
	}
	// Other valid prefixes are "serviceAccount:", "user:"
	// See the documentation for more values.
	// https://cloud.google.com/storage/docs/access-control/iam
	identity := "group:cloud-logs@google.com"
	var role iam.RoleName = "roles/storage.objectViewer"

	policy.Add(identity, role)
	if err := bucket.IAM().SetPolicy(ctx, policy); err != nil {
		return fmt.Errorf("Bucket(%q).IAM().SetPolicy: %w", bucketName, err)
	}
	// NOTE: It may be necessary to retry this operation if IAM policies are
	// being modified concurrently. SetPolicy will return an error if the policy
	// was modified since it was retrieved.
	fmt.Fprintf(w, "Added %v with role %v to %v\n", identity, role, bucketName)
	return nil
}

Java

如要瞭解如何安裝及使用 Cloud Storage 的用戶端程式庫,請參閱「Cloud Storage 用戶端程式庫」。詳情請參閱「Cloud Storage Java API 參考文件」。

如要向 Cloud Storage 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證作業」。


import com.google.cloud.Binding;
import com.google.cloud.Policy;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class AddBucketIamMember {
  /** Example of adding a member to the Bucket-level IAM */
  public static void addBucketIamMember(String projectId, String bucketName) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your GCS bucket
    // String bucketName = "your-unique-bucket-name";

    // For more information please read:
    // https://cloud.google.com/storage/docs/access-control/iam
    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();

    Policy originalPolicy =
        storage.getIamPolicy(bucketName, Storage.BucketSourceOption.requestedPolicyVersion(3));

    String role = "roles/storage.objectViewer";
    String member = "group:example@google.com";

    // getBindingsList() returns an ImmutableList and copying over to an ArrayList so it's mutable.
    List<Binding> bindings = new ArrayList(originalPolicy.getBindingsList());

    // Create a new binding using role and member
    Binding.Builder newMemberBindingBuilder = Binding.newBuilder();
    newMemberBindingBuilder.setRole(role).setMembers(Arrays.asList(member));
    bindings.add(newMemberBindingBuilder.build());

    // Update policy to add member
    Policy.Builder updatedPolicyBuilder = originalPolicy.toBuilder();
    updatedPolicyBuilder.setBindings(bindings).setVersion(3);
    Policy updatedPolicy = storage.setIamPolicy(bucketName, updatedPolicyBuilder.build());

    System.out.printf("Added %s with role %s to %s\n", member, role, bucketName);
  }
}

Node.js

如要瞭解如何安裝及使用 Cloud Storage 的用戶端程式庫,請參閱「Cloud Storage 用戶端程式庫」。詳情請參閱「Cloud Storage Node.js API 參考文件」。

如要向 Cloud Storage 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證作業」。

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The role to grant
// const roleName = 'roles/storage.objectViewer';

// The members to grant the new role to
// const members = [
//   'user:jdoe@example.com',
//   'group:admins@example.com',
// ];

// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

async function addBucketIamMember() {
  // Get a reference to a Google Cloud Storage bucket
  const bucket = storage.bucket(bucketName);

  // For more information please read:
  // https://cloud.google.com/storage/docs/access-control/iam
  const [policy] = await bucket.iam.getPolicy({requestedPolicyVersion: 3});

  // Adds the new roles to the bucket's IAM policy
  policy.bindings.push({
    role: roleName,
    members: members,
  });

  // Updates the bucket's IAM policy
  await bucket.iam.setPolicy(policy);

  console.log(
    `Added the following member(s) with role ${roleName} to ${bucketName}:`
  );

  members.forEach(member => {
    console.log(`  ${member}`);
  });
}

addBucketIamMember().catch(console.error);

PHP

如要瞭解如何安裝及使用 Cloud Storage 的用戶端程式庫,請參閱「Cloud Storage 用戶端程式庫」。詳情請參閱「Cloud Storage PHP API 參考文件」。

如要向 Cloud Storage 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證作業」。

use Google\Cloud\Storage\StorageClient;

/**
 * Adds a new member / role IAM pair to a given Cloud Storage bucket.
 *
 * @param string $bucketName The name of your Cloud Storage bucket.
 *        (e.g. 'my-bucket')
 * @param string $role The role to which the given member should be added.
 *        (e.g. 'roles/storage.objectViewer')
 * @param string[] $members The member(s) to be added to the role.
 *        (e.g. ['group:example@google.com'])
 */
function add_bucket_iam_member(string $bucketName, string $role, array $members): void
{
    $storage = new StorageClient();
    $bucket = $storage->bucket($bucketName);

    $policy = $bucket->iam()->policy(['requestedPolicyVersion' => 3]);
    $policy['version'] = 3;

    $policy['bindings'][] = [
        'role' => $role,
        'members' => $members
    ];

    $bucket->iam()->setPolicy($policy);

    printf('Added the following member(s) to role %s for bucket %s' . PHP_EOL, $role, $bucketName);
    foreach ($members as $member) {
        printf('    %s' . PHP_EOL, $member);
    }
}

Python

如要瞭解如何安裝及使用 Cloud Storage 的用戶端程式庫,請參閱「Cloud Storage 用戶端程式庫」。詳情請參閱「Cloud Storage Python API 參考文件」。

如要向 Cloud Storage 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證作業」。

from google.cloud import storage


def add_bucket_iam_member(bucket_name, role, member):
    """Add a new member to an IAM Policy"""
    # bucket_name = "your-bucket-name"
    # role = "IAM role, e.g., roles/storage.objectViewer"
    # member = "IAM identity, e.g., user: name@example.com"

    storage_client = storage.Client()
    bucket = storage_client.bucket(bucket_name)

    policy = bucket.get_iam_policy(requested_policy_version=3)

    policy.bindings.append({"role": role, "members": {member}})

    bucket.set_iam_policy(policy)

    print(f"Added {member} with role {role} to {bucket_name}.")

Ruby

如要瞭解如何安裝及使用 Cloud Storage 的用戶端程式庫,請參閱「Cloud Storage 用戶端程式庫」。詳情請參閱「Cloud Storage Ruby API 參考文件」。

如要向 Cloud Storage 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證作業」。

def add_bucket_iam_member bucket_name:
  # The ID of your GCS bucket
  # bucket_name = "your-unique-bucket-name"

  require "google/cloud/storage"

  storage = Google::Cloud::Storage.new
  bucket = storage.bucket bucket_name

  role   = "roles/storage.objectViewer"
  member = "group:example@google.com"

  bucket.policy requested_policy_version: 3 do |policy|
    policy.bindings.insert role: role, members: [member]
  end

  puts "Added #{member} with role #{role} to #{bucket_name}"
end

Rust

use google_cloud_iam_v1::model::Binding;
use google_cloud_storage::client::StorageControl;

pub async fn sample(
    client: &StorageControl,
    bucket_id: &str,
    role: &str,
    member: &str,
) -> anyhow::Result<()> {
    let mut policy = client
        .get_iam_policy()
        .set_resource(format!("projects/_/buckets/{bucket_id}"))
        .send()
        .await?;
    policy
        .bindings
        .push(Binding::new().set_role(role).set_members([member]));
    let updated_policy = client
        .set_iam_policy()
        .set_resource(format!("projects/_/buckets/{bucket_id}"))
        .set_policy(policy)
        .send()
        .await?;
    println!(
        "Successfully added binding for {member} to bucket {bucket_id} policy: {updated_policy:?}"
    );
    Ok(())
}

JSON

  1. 安裝並初始化 gcloud CLI,以便為 Authorization 標頭產生存取權杖。

  2. 建立包含下列資訊的 JSON 檔案:

    {
    "bindings":[
      {
        "role": "roles/storage.objectViewer",
        "members":[
          "YOUR_AGENT_EMAIL"
        ]
      },
      {
        "role": "roles/storage.legacyBucketReader",
        "members":[
          "YOUR_AGENT_EMAIL"
        ]
      }
    ]
    }

    更改下列內容:

  3. 使用 cURL 來透過 PUT setIamPolicy 要求呼叫呼叫 JSON API

    curl -X PUT --data-binary @JSON_FILE_NAME \
    -H "Authorization: Bearer OAUTH2_TOKEN" \
    -H "Content-Type: application/json" \
    "https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/iam"

    更改下列內容:

    • JSON_FILE_NAME 是您在步驟 2 建立的檔案路徑。
    • OAUTH2_TOKEN 是您在步驟 1 產生的存取權杖。
    • BUCKET_NAME 是您要授予主體存取權的值區名稱。例如:my-bucket