📂

【Google Cloud Storage】マネージドフォルダの権限で出来ること

2024/05/17に公開

概要

2024年4月に一般公開となった Google Cloud Storage のマネージドフォルダについて、
マネージドフォルダの各権限でそれぞれ出来ることを検証してみました。

想定読者

  • Google Cloud の Identity and Access Management(IAM) を触ったことのある方
  • Google Cloud の Cloud Storage を触ったことのある方

マネージドフォルダとは

簡潔に述べると実体のあるフォルダです。
https://cloud.google.com/storage/docs/managed-folders

通常 Cloud Storage バケット上に作成したフォルダは、シミュレートされたフォルダと呼ばれ、実体を持たず、フォルダとしての体裁を維持するために内部にオブジェクトが存在する必要があります。

Cloud コンソールからフォルダを作成すると、一見して空のフォルダが作成されたように見えますが、中にゼロバイトの隠しオブジェクトが作成されています。

この隠しオブジェクトを削除すると、シミュレートされたフォルダも消えてしまいます。

マネージドフォルダはシミュレートされたフォルダと異なり実体を持つため、内部にオブジェクトが無くても存在します。
また、マネージドフォルダ階層レベルでのロール付与が可能です。

マネージドフォルダの権限

以下6つの権限が用意されています。

  • storage.managedFolders.create
  • storage.managedFolders.delete
  • storage.managedFolders.get
  • storage.managedFolders.list
  • storage.managedFolders.getIamPolicy
  • storage.managedFolders.setIamPolicy

本記事では取り扱いませんが、Cloud Storage 用の事前定義ロールにも上記権限が含まれています。
マネージドフォルダの操作に特化した事前定義ロールも用意されています。
Storage Object Admin

権限の検証

カスタムロールを作成して、マネージドフォルダの権限で出来ることをそれぞれ確認します。
プロジェクト階層レベル、バケット階層レベル、マネージドフォルダ階層レベルで必要な権限を持つカスタムロールをそれぞれ用意します。
上位のリソース階層で付与されたロールは下位のリソース階層に継承されます。

事前準備

以下手順を検証に使用する Google Cloud プロジェクトの Cloud Shell から実施します。

本検証をするに当たり、バケット作成、カスタムロールの作成および付与を行うためのオーナーロールを所持するアカウントと、実際にマネージドフォルダ権限で操作を行う検証用のアカウントを用意しています。

検証用のバケットとカスタムロールの作成

1. 検証用バケットの作成

検証用の Cloud Storage バケットを作成します。

gcloud storage buckets create gs://managed-folders-abaq-trial \
  --project=[プロジェクトID] \
  --default-storage-class=STANDARD \
  --location=us-central1 \
  --no-public-access-prevention \
  --uniform-bucket-level-access

2. プロジェクト階層レベルのカスタムロール作成・付与

Google Cloud のプロジェクト自体にアクセスするのと、Cloud Storage バケットを一覧表示するのに必要な下記権限を持つカスタムロールを作成し、プロジェクト階層レベルで検証用アカウントに付与します。

  • resourcemanager.projects.get
  • storage.buckets.list
# カスタムロールの作成
gcloud iam roles create storageBucketViewer \
  --project=[プロジェクトID] \
  --title="Custom Storage Bucket Viewer Role" \
  --permissions="resourcemanager.projects.get,storage.buckets.list"

# カスタムロールを検証用アカウントに付与
gcloud projects add-iam-policy-binding [プロジェクトID] \
  --member='user:[検証アカウントID]' \
  --role='projects/[プロジェクトID]/roles/storageBucketViewer'

検証用アカウントで作成したバケットを参照できることを確認します。

gcloud storage ls --project=[プロジェクトID] | grep managed-folders-abaq-trial

バケット内のオブジェクトを参照しようとすると、storage.objects.list権限が無い旨のエラーメッセージが表示されます。

gcloud storage ls -l -a gs://managed-folders-abaq-trial

3. バケット、マネージドフォルダ階層レベルのカスタムロール作成

マネージドフォルダの操作に必要な下記の権限を持つカスタムロールを1つずつ作成します。
この段階ではまだ検証用アカウントに付与しません。

  • storage.managedFolders.create
  • storage.managedFolders.delete
  • storage.managedFolders.get
  • storage.managedFolders.list
  • storage.managedFolders.getIamPolicy
  • storage.managedFolders.setIamPolicy
gcloud iam roles create storageManagedFoldersCreator \
  --project=[プロジェクトID] \
  --title="Managed Folders Creator Role" \
  --permissions="storage.managedFolders.create"

gcloud iam roles create storageManagedFoldersDeleter \
  --project=[プロジェクトID] \
  --title="Managed Folders Deleter Role" \
  --permissions="storage.objects.get,storage.objects.list,storage.managedFolders.get,storage.managedFolders.delete"

gcloud iam roles create storageManagedFoldersGetter \
  --project=[プロジェクトID] \
  --title="Managed Folders Getter Role" \
  --permissions="storage.managedFolders.get"

gcloud iam roles create storageManagedFoldersViewer \
  --project=[プロジェクトID] \
  --title="Managed Folders Viewer Role" \
  --permissions="storage.managedFolders.list"

gcloud iam roles create storageManagedFoldersIamPolicyGetter \
  --project=[プロジェクトID] \
  --title="Managed Folders Iam Policy Getter Role" \
  --permissions="storage.managedFolders.getIamPolicy"

gcloud iam roles create storageManagedFoldersIamPolicySetter \
  --project=[プロジェクトID] \
  --title="Managed Folders Iam Policy Setter Role" \
  --permissions="storage.objects.get,storage.objects.list,storage.managedFolders.get,storage.managedFolders.setIamPolicy"

1. storage.managedFolders.create

Cloud Storage バケット配下にマネージドフォルダを作成する権限です。
バケット階層レベルで検証用アカウントに本権限のみを持つカスタムロールを付与します。

gcloud storage buckets add-iam-policy-binding gs://managed-folders-abaq-trial \
  --member="user:[検証用アカウントID]" \
  --role="projects/[プロジェクトID]/roles/storageManagedFoldersCreator"

次に検証用アカウントで下記のコマンドを実行しマネージドフォルダを作成します。

gcloud storage managed-folders create gs://[バケット名]/[マネージドフォルダ名]


「managed-folder-a」「managed-folder-b」「managed-folder-c」の3フォルダを作成しました。

storage.managedFolders.create権限を持つロールが付与されていない場合、以下のエラーが発生します。

2. storage.managedFolders.delete

Cloud Storage バケット配下のマネージドフォルダを削除する権限です。
マネージドフォルダの削除には本権限以外に下記権限も必要となります。

  • storage.objects.get
  • storage.objects.list
  • storage.managedFolders.get

バケット階層レベルで検証用アカウントにマネージドフォルダの削除に必要な権限を持つカスタムロールを付与します。

gcloud storage buckets add-iam-policy-binding gs://managed-folders-abaq-trial \
  --member="user:[検証用アカウントID]" \
  --role="projects/[プロジェクトID]/roles/storageManagedFoldersDeleter"

次に検証用アカウントで下記のコマンドを実行しマネージドフォルダを削除します。

gcloud storage managed-folders delete gs://[バケット名]/[マネージドフォルダ名]/


前項で作成した「managed-folder-c」を削除しました。

storage.managedFolders.delete権限を持つロールが付与されていない場合、以下の警告でマネージドフォルダの削除に失敗したことが通知されます。

3. storage.managedFolders.get

マネージドフォルダのメタデータを取得する権限です。

前項でstorage.managedFolders.get権限を持つカスタムロールをバケット階層レベルで付与したので、バケット配下全てのマネージドフォルダにも権限が継承されています。
指定のマネージドフォルダのみ参照できることを検証するために、前項のカスタムロールを剥奪します。

gcloud storage buckets remove-iam-policy-binding gs://managed-folders-abaq-trial \
  --member="user:[検証用アカウントID]" \
  --role="projects/[プロジェクトID]/roles/storageManagedFoldersGetter"

ポリシーファイル(JSON)を作成し、マネージドフォルダ階層レベルで検証用アカウントに本権限のみを持つカスタムロールを付与します。
今回は「managed-folder-a」に設定します。

# ポリシーファイルを作成
echo '{
  "bindings": [
    {
      "role": "projects/[プロジェクトID]/roles/storageManagedFoldersGetter",
      "members": [
        "user:[検証用アカウントID]"
      ]
    }
  ]
}' > policy-managed-folders-getter.json

# カスタムロールを検証用アカウントに付与
gcloud storage managed-folders set-iam-policy \
gs://managed-folders-abaq-trial/managed-folder-a policy-managed-folders-getter.json

次に検証用アカウントで下記のコマンドを実行しマネージドフォルダの情報を参照します。

gcloud storage managed-folders describe gs://managed-folders-abaq-trial/managed-folder-a

gcloud storage managed-folders describe gs://managed-folders-abaq-trial/managed-folder-b


マネージドフォルダ階層レベルでロールを付与した「managed-folder-a」の情報は参照でき、ロールを持たない「managed-folder-b」の情報は参照できない(403 エラー)ことを確認できました。

4. storage.managedFolders.list

Cloud Storage バケットやマネージドフォルダ配下のマネージドフォルダ一覧を取得する権限です。

バケット階層レベルで検証用アカウントに本権限のみを持つカスタムロールを付与します。

gcloud storage buckets add-iam-policy-binding gs://managed-folders-abaq-trial \
  --member="user:[検証用アカウントID]" \
  --role="projects/[プロジェクトID]/roles/storageManagedFoldersViewer"

次に検証用アカウントで下記のコマンドを実行しバケット配下のマネージドフォルダ一覧を参照します。

gcloud storage managed-folders list gs://managed-folders-abaq-trial


削除した「managed-folder-c」は表示されず、「managed-folder-a」「managed-folder-b」は表示されることを確認できました。

storage.managedFolders.list権限を持つロールが付与されていない場合、以下のエラーが発生します。

5. storage.managedFolders.getIamPolicy

マネージドフォルダのポリシー情報を取得する権限です。

バケット階層レベルで検証用アカウントに本権限のみをカスタムロールを付与します。
storage.managedFolders.get権限とは異なり、バケット階層以上のレベルで付与する必要があります。

gcloud storage buckets add-iam-policy-binding gs://managed-folders-abaq-trial \
  --member="user:[検証用アカウントID]" \
  --role="projects/[プロジェクトID]/roles/storageManagedFoldersIamPolicyGetter"

次に検証用アカウントで下記のコマンドを実行しマネージドフォルダのポリシー情報を参照します。

gcloud storage managed-folders get-iam-policy gs://managed-folders-abaq-trial/managed-folder-a

gcloud storage managed-folders get-iam-policy gs://managed-folders-abaq-trial/managed-folder-b


3. storage.managedFolders.get の項で「managed-folder-a」に付与したカスタムロールが表示され、「managed-folder-b」には直接付与されたロールが無いことを確認できました。

storage.managedFolders.getIamPolicy権限を持つロールが付与されていない場合、以下のエラーが発生します。

6. storage.managedFolders.setIamPolicy

マネージドフォルダへポリシーを設定する権限です。
マネージドフォルダのポリシー設定には本権限以外に下記権限も必要となります。

  • storage.objects.get
  • storage.objects.list
  • storage.managedFolders.get

バケット階層レベルで検証用アカウントにマネージドフォルダのポリシー設定に必要な権限を持つカスタムロールを付与します。

gcloud storage buckets add-iam-policy-binding gs://managed-folders-abaq-trial \
  --member="user:[検証用アカウントID]" \
  --role="projects/[プロジェクトID]/roles/storageManagedFoldersIamPolicySetter"

次に検証用アカウントから自身に対してマネージドフォルダへのカスタムロールを付与します。
「managed-folder-b」にstorage.managedFolders.get権限を持つカスタムロールを付与します。

# ポリシーファイルを作成
echo '{
  "bindings": [
    {
      "role": "projects/[プロジェクトID]/roles/storageManagedFoldersGetter",
      "members": [
        "user:[検証用アカウントID]"
      ]
    }
  ]
}' > policy-managed-folders-getter.json

# カスタムロールを検証用アカウントに付与
gcloud storage managed-folders set-iam-policy \
gs://managed-folders-abaq-trial/managed-folder-b policy-managed-folders-getter.json

# カスタムロールが付与されたかを確認
gcloud storage managed-folders describe gs://managed-folders-abaq-trial/managed-folder-b


ロールの付与後、「managed-folder-b」のメタデータが参照可能になったことを確認できました。

storage.managedFolders.setIamPolicy権限を持つロールが付与されていない場合、以下のエラーが発生します。

Cloud コンソール上のアクセス制御

3. storage.managedFolders.get4. storage.managedFolders.list の検証結果から、
Cloud コンソール上のマネージドフォルダ参照可否も制御できるかと思っていましたが、バケット階層以上のレベルでstorage.objects.list権限が必要でした。

storage.objects.list権限をバケット階層レベルで付与してしまうと、storage.managedFolders.getstorage.managedFolders.list権限の有無に関わらずバケット配下の全オブジェクトが参照できてしまうため、残念ながら Cloud コンソール上から一部のマネージドフォルダのみ参照させる、といった制御は出来ないようです。今後のアップデートに期待ですね。
同じバケットでもサービスアカウント毎にアクセス可能なフォルダを分けたい、といったケースには適用できると思います。

※2024/05/20 訂正

フォルダ含めたURLで直にアクセスすることで Cloud コンソールから権限を持つマネージドフォルダと配下オブジェクトを参照できました。

Cloud コンソールの[Bucket]ページから該当バケットをクリックすると権限を持つマネージドフォルダのみ表示される、といった制御は出来ませんが、フォルダ付きURLをそのフォルダの権限を持つユーザに共有して直接アクセスしてもらうといった使い方は可能です。

Discussion