web-dev-qa-db-ja.com

Cloud Runサービスアカウントには署名する権限がありません

Google Cloud Runで実行され、Google Cloudストレージにファイルが保存されているプログラムを開発しています。

私が経験している問題は、通常はプライベートなCloud Storageからファイルをダウンロードするための署名付きURLを生成しようとしたときに発生します。私のローカルマシンでは問題なく動作しますが、Cloud Runで実行すると動作しません。

ローカルで、Storage Object Adminの役割が割り当てられているサービスアカウントを使用しています。クラウドコンソールからダウンロードしたキーの.jsonファイルへの絶対パスを値に含むGOOGLE_APPLICATION_CREDENTIALSという環境変数を使用して、権限をロードします。

Cloud Runでは、サービスを実行するのと同じ役割をサービスアカウントに付与しました。しかし、そこに署名しようとすると、例外が発生します。

Java.io.IOException:提供されたバイトに署名しようとするエラーコード403:呼び出し元に権限がありません

私のコードでは、サービスアカウントを明示的に選択していません。SDKのドキュメントでは、これが自動的に行われると信じているからです。 Cloud Runでは、GOOGLE_APPLICATION_CREDENTIALS変数が設定されていません。これも自動的に行われると思ったためです。

私を混乱させるのは、Cloud Runで実行されているアプリケーションがファイルをCloud Storageに正常にアップロードできることです。そのため、どこかにある形式の認証情報があると思います。

何が悪いのですか?

1
cascer1

TL; DR:サービスアカウントに_iam.serviceAccounts.signBlob_権限があることを確認します。


Cloud Runで認証情報を取得するために使用した方法をさらに調査した後:

_GoogleCredentials credentials = ComputeEngineCredentials.create();
Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();
_

ComputeEngineCredentialsの-​​ javadoc を読みます:

Google Compute Engine VMの組み込みサービスアカウントを表すOAuth2認証情報。 Google Compute Engineメタデータサーバーからアクセストークンをフェッチします。これらの認証情報は、IAM APIを使用してデータに署名します。詳細については、sign(byte [])を参照してください。

この後、私は javadoc for sign(byte[])を読みました(私の強調):

サービスアカウントに関連付けられた秘密鍵を使用して、提供されたバイトに署名します。 Compute EngineのプロジェクトでIdentity and Access Management(IAM)APIを有効にする必要があり、インスタンスのサービスアカウントにiam.serviceAccounts.signBlob権限が必要です。

そのため、_iam.serviceAccounts.signBlob_権限のみを持つ新しい役割を作成し、それをCloud Run構成が使用するサービスアカウントに割り当てました。この後、問題はすぐになくなりました(再展開する必要はありません)

3
cascer1