rakumoコンサルティング部 Tech Blog

GCPの構築ノウハウをそろりと公開 コンサル部によるテックブログ

Google Cloud Storage (GCS)にIAMカスタムロールを設定する

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 コマンドを使用する必要があります。

設定するには、以下のコマンドを発行します。

$ 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"」の部分が今回追加したカスタムロールですね。

変更した JSON を再びバケットにセットします。

$ gsutil iam set iam.json gs://bucket-name

今度はエラー表示もなく、無事に設定されました。 もう一度 gsutil iam get しても、正しく更新されていることが分かります。

ということで、GCS バケットへのカスタムロールのセットには JSON を使うことで解決できます。