のーずいだんぷ

主に自分用メモですが、もしかしたら誰かの役に立つかもしれません

GCSにサービスアカウントを設定したがPermission Denied Errorがでる

何をしようとしたのか?

GCSにファイルをアップロードする処理をPythonのgoogle-cloud-storageを使って実装していた。 その際にGCSのバケット単位でアクセス制限をかけようとし、専用のサービスアカウントを作成してそのアカウントには以下の役割を割り当てた。

  • ストレージオブジェクト管理者

ちなみに私はこれまでの業務ではAWSを使用しており、AWSに関してはIAMで適切な権限を付与する方法を知っていた。 今回GCPではあったが、構造的にIAMロール(AWS)とサービスアカウント(GCP)がほぼ対応関係にあることがわかり、同様の付与方法をでGCSに権限付与を考えており、そのやり方考え方自体は正しかった。

しかしupload_from_filename()でアップロードしようとしたところ、タイトルのエラーが出た。

原因と対策

いくつかの権限が足りていないことが判明した。具体的には以下の権限不足だった。

  • ストレージのレガシーオブジェクトオーナー
  • ストレージのレガシーバケット読み取り

正確にはストレージのレガシーオブジェクトオーナーは用途によってはもっと弱い権限でもいいかもしれない。 少なくとも上記の役割を追加で付与することで当該エラーは解決されることを確認した。

補足

AWS勢として少し困惑した部分として、GCPは継承役割とリソース役割の2回に分けて権限付与を行うようだ。 最初にサービスアカウントを作成する際に役割を設定し、この状態でGCSにバケットを作成すると既にこのサービスアカウントの権限(上記の例だとストレージオブジェクト管理者)が割り当てられている。 そして、リソース(GCSのバケット)の詳細画面で、サービスアカウントをリソースにアタッチするときに、リソース限定の役割を決定する。 ここらへんは挙動ベースの理解なので後日ちゃんと調査したい。