Cloud Run 服务帐号无权签名

Cloud Run 服务帐号无权签名

我正在开发一个将在 Google Cloud Run 上运行并将文件存储在 Google Cloud 存储中的程序。

我遇到的问题发生在尝试生成签名 URL 以从通常是私有的云存储中下载文件时。在我的本地机器上它可以正常工作,但在 Cloud Run 中运行时却不行。

我在本地使用已分配角色的服务帐户Storage Object Admin。我使用名为的环境变量加载权限,GOOGLE_APPLICATION_CREDENTIALS其值是我从云控制台下载的密钥 .json 文件的绝对路径。

在 Cloud Run 上,我向服务运行的服务帐户授予了相同的角色。但是,当我尝试在那里签署任何内容时,出现了异常:

java.io.IOException:错误代码 403 尝试签署提供的字节:调用者没有权限

在我的代码中,我没有明确选择任何服务帐户,因为 SDK 文档让我相信这是自动完成的。在 Cloud Run 中,我没有GOOGLE_APPLICATION_CREDENTIALS设置变量,因为我认为这也是自动完成的。

令我困惑的是,在 Cloud Run 中运行的应用程序仍然可以正常将文件上传到 Cloud Storage,所以这让我认为它确实具有来自某处的某种形式的凭据。

我究竟做错了什么?

答案1

总结:确保服务帐户具有iam.serviceAccounts.signBlob权限。


在进一步研究了我在 Cloud Run 上获取凭据的方法后:

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

我读过javadoc为了ComputeEngineCredentials

代表 Google Compute Engine VM 内置服务帐户的 OAuth2 凭据。从 Google Compute Engine 元数据服务器获取访问令牌。这些凭据使用 IAM API 签署数据。有关更多详细信息,请参阅 sign(byte[])。

在这之后我读了javadoc对于sign(byte[])(强调我的):

使用与服务帐号关联的私钥对提供的字节进行签名。Compute Engine 的项目必须启用身份和访问管理 (IAM) API,并且实例的服务帐号必须具有iam.serviceAccounts.signBlob允许。

因此,我创建了一个仅具有iam.serviceAccounts.signBlob权限的新角色,并将其分配给我的 Cloud Run 配置使用的服务帐号。此后,问题立即消失(无需重新部署)

答案2

此外,请确保您也已启用IAM Service Account Credentials API此功能。

相关内容