rakumoコンサルティング部の小山(@koyhoge)です。
しばらくブログの投稿が滞ってしまいすいません。今回は Google Cloud Storage (GCS) で IAM によるアクセス制限をかけようとした際にハマったことを書きます。
GCS のアクセス制限には2種類ある
GCS にはバケット単位やオブジェクト単位でアクセス制限をかける機能があります。
https://cloud.google.com/storage/docs/access-control/iamcloud.google.com
Cloud IAM (Identity and Access Management) と呼ばれる、GCP 上で統一的にアクセス管理をする仕組みを利用するのが現在は通常です。
ただ、かつては GCP に IAM がまだ存在しなかったので、そのために GCS が独自にアクセス制限機能をもっていました。これはレガシー ACL (Access Control Lists) と呼ばれ、現在でも有効になっています。ACL と IAM は同時に使用することが可能ですが、ACL は過去の互換性のためにのみ有効になっているので、現在では IAM のみを使用してアクセス制限を実現することが推奨されています。
複数の権限をグルーピングする「ロール(役割)」
Cloud IAM は特定のアカウントやアカウントのグループに対して、機能ごとにアクセス許可を追加していく形で設定します。
https://cloud.google.com/iam/docs/overviewcloud.google.com
GCP の各サービスに関して、細かく権限を設定することができますが、それらを毎回ひとつずつ設定するのは大変なので、よく使われる基本的な権限をひとまとめにした「ロール(役割)」というものが定義されています。
(GCP のドキュメントでは「役割」という用語に統一されて翻訳されていますが、一般的にはロールと呼ばれることの方が多いように感じるので、この記事では「ロール」を採用します。)
https://cloud.google.com/iam/docs/understanding-rolescloud.google.com
Cloud IAM 以前に存在していた「オーナー」「編集者」「閲覧者」という区分は、現在はロールとして実現されています。他にもサービスによっては、あらかじめ設定されているロールが存在しています。
ユーザが任意の権限を組み合わせてロールを作ることもできます。これは「カスタムロール」と呼ばれます。自分の組織やプロジェクトに特有の、特定の権限のみをピックアップしてカスタムロールを作成することで、権限管理の設定をより楽にすることができます。
ロールを GCS バケットに設定する
ここからようやく本題に入ります。
最初に書いたように、GCS には Cloud IAM によるアクセス管理を設定できるのですが、そこでカスタムロールを指定しようとするとちょっとおかしなことになります。
その前に、まずはプリセットされたロールをを指定する方法を見てみましょう。ロールをセットするのに Web コンソールから行うことは現状ではできなくて、そのかわりに gsutil コマンドを使用する必要があります。
- hoge@example.com アカウントに
- objectCreator というロールを
- bucket-name という名前の GCS バケットに対して
設定するには、以下のコマンドを発行します。
$ gsutil iam ch user:hoge@example.com:objectCreator gs://bucket-name
ここでセットされる「objectCreator」というロール名は GCP 側ですでに用意されているものです。
gsutil iam ch ではカスタムロールを設定できない
それでは同じ方法でカスタムロールを設定してみましょう。
GCP コンソールの IAM 設定画面 → 役割からカスタムロールを作成すると、ID が
projects/<project_name>/roles/<数字>
というフォーマットで作成されます。
この ID を指定して、gsutil iam ch を実行してみると
$ gsutil iam ch user:hoge@example.com:projects/some_project/roles/99 gs://bucket-name BadRequestException: 400 Invalid argument
と Invalid argument エラーになってしまいました。いろいろ試してみましたが、gsutil iam ch コマンドでカスタムロールを設定することは、どうやらできないようでした。
JSONを用いてカスタムロールを設定する
一瞬あきらめかけていたのですが、ふと思いついて gsutil iam get/set で JSON ファイル経由でロールを設定してみたらうまくいきました。
まずは gsuilt iam get で権限情報を JSON で取得します。
$ gsutil iam get gs://bucket-name > iam.json
中身は以下のような JSON になっています。
{ "bindings": [ { "members": [ "projectEditor:some-project", "projectOwner:some-project" ], "role": "roles/storage.legacyBucketOwner" }, { "members": [ "projectViewer:some-project" ], "role": "roles/storage.legacyBucketReader" } ], "etag": "CAg=" }
ここにカスタムロールを用いた権限を追加します。
{ "bindings": [ { "members": [ "projectEditor:some-project", "projectOwner:some-project" ], "role": "roles/storage.legacyBucketOwner" }, { "members": [ "projectViewer:some-project" ], "role": "roles/storage.legacyBucketReader" }, { "members": [ "user:hoge@example.com" ], "role": "projects/some-project/roles/99" } ], "etag": "CAg=" }
「"role": "projects/some-project/roles/99"」の部分が今回追加したカスタムロールですね。
$ gsutil iam set iam.json gs://bucket-name
今度はエラー表示もなく、無事に設定されました。 もう一度 gsutil iam get しても、正しく更新されていることが分かります。