【GCP】Cloud Storage のbucket へのアクセス権

Google Cloud Platform を使っています。Storage のbucket へアクセス権が無く怒られてしまい、ハマったのでメモしておきます。

問題はGCP にデプロイしたコンテナがCloud Storage にアクセスするためにpython script でStorage からダウンロードするために ```client.get_bucket("my_bucket")``` とすると、

```
Forbidden('GET https://storage.googleapis.com/storage/v1/b/projectname-bucketname?projection=noAcl:service_acount@myproject.iam.gserviceaccount.com 
does not have storage.bucket.get access to the Google Cloud Storage Bucket`
```

と言われてエラーになるという症状でした。(内部でREST API を呼んでいるんですね。。。）

### 当初のStorage へのアクセス権の設定は不十分でした

そもそも何をしていたか。Project 用にサービスアカウントを作成し、その後、Storage への読み書きのつもりでサービスアカウントに role を付与しました。これで十分かと思っていました。

```
project=$(gcloud config get-value core/project 2> /dev/null)
gcloud iam service-accounts create $sa_name \
        --description "サービスアカウントの説明" \
        --display-name "$sa_name"
gcloud projects add-iam-policy-binding ${project} \
 --member serviceAccount:$sa_name@${project}.iam.gserviceaccount.com \
 --role roles/storage.objectCreator
```

ですが、Storage object へのアクセス権の設定で、bucket へのアクセスには不十分でした。何故なら。。。

### Storage.objectViwer には bucket アクセス権が無い

Storage に関するアクセス権はここにあるように、object と bucket で異なります。

- https://cloud.google.com/storage/docs/access-control/iam-permissions?hl=ja

以下で確認できます。

```
$ gcloud iam roles describe roles/storage.objectViewer
description: Read access to GCS objects.
etag: AA==
includedPermissions:
- resourcemanager.projects.get
- resourcemanager.projects.list
- storage.objects.get
- storage.objects.list
name: roles/storage.objectViewer
stage: GA
title: Storage Object Viewer
```

一方で、storage.admin には上記に加えて、

```
- storage.buckets.create
- storage.buckets.delete
- storage.buckets.get
- storage.buckets.getIamPolicy
- storage.buckets.list
- storage.buckets.setIamPolicy
- storage.buckets.update
```

も付与されています。ですが、実際にサービスアカウントにStorage admin というのも良くないと思われます。

現在のサービスアカウントのroles は、以下のコマンドで確認できます。

```
$ gcloud projects get-iam-policy プロジェクト --flatten="bindings[].members" --format='table(bindings.rol
e)' --filter='bindings.members:サービスアカウント名@プロジェクト.iam.gserviceaccount.com'
ROLE
roles/pubsub.admin
roles/pubsub.editor
roles/pubsub.publisher
roles/storage.objectCreator
roles/storage.objectViewer
```

### bucket へのアクセス権を設定する

今回は急いでいたので、console.cloud.goole.com からの操作で行いました。
Storage で対象としているbucket を選択し、「バケットの権限を編集」を... を縦に並べたのをクリックして選択すると、以下のようになります。

![コメント 2020-06-06 004228.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294040/9579008a-8fd1-67fa-1a2e-187acacbc035.png)

ここで、サービスアカウントを追加します。追加するときに、下記のように"Cloud Storage レガシー" でバケットの読み書きの権限を付与できます。


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294040/7a79556b-107c-b8a9-2455-0ccd843b4fe4.png" width=50%>

今回はこれで乗り切れましたが、こちらもコマンドラインで操作できるのかもしれません。
疲れた。。。

### 参考

同じようなことで悩まれて解決された先人の知恵を拝借いたしました。

- https://future-architect.github.io/articles/20190708/
- https://qiita.com/kouchanne/items/3505b88185f614a1453c
- https://stackoverflow.com/questions/47006062/how-do-i-list-the-roles-associated-with-a-gcp-service-account (How do I list the roles associated with a gcp service account?)


(2020/06/05)

## 追記

### fine-granted/uniform access
どちらかを選択するらしい。とりあえずメモする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294040/2024e81a-7978-5c6c-58b2-9bb594d61ffb.png)

(2020/06/06)