如何在没有密钥文件的情况下授予 Cloud 运行 服务访问服务帐户凭据的权限?

How can I grant a Cloud Run service access to service account's credentials without the key file?

我正在开发一个云 运行 服务,该服务使用服务帐户的机密文件和以下 python 3 代码访问不同的 Google API:

from google.oauth2 import service_account
credentials = service_account.Credentials.from_service_account_file(SECRETS_FILE_PATH, scopes=SCOPES)

为了部署它,我在 build/deploy 过程中上传了机密文件(通过 gcloud builds submitgcloud run deploy 命令)。

如何避免像这样上传机密文件?

编辑 1:

我认为重要的是要注意我需要模拟来自 GSuite/Workspace 的用户帐户(具有域范围的委托)。我处理这个问题的方法是使用上面的凭据,然后是:

delegated_credentials = credentials.with_subject(USER_EMAIL)

使用 Secret Manager might help you, as you can manage the multiple secrets you have and not have them stored as files, as you are doing right now. I would recommend you to take a look at this article here,这样您就可以获得有关如何将其与 Cloud 运行 结合使用的更多信息,从而改善您管理机密的方式。

除此之外,正如在这个类似案例中所阐明的那样 , you have two options: use default service account that comes with it or deploy another one with the Service Admin role. This way, you won't need to specify keys with variables - as clarified by a Google developer in this specific

为了提高安全性,最好的方法是永远不要在本地或 GCP 上使用服务帐户密钥文件(我 wrote an article on this)。为实现这一点,Google 云服务有一个自动加载的服务帐户,可以是默认的,也可以是自定义的。

Cloud Run,默认服务账户是Compute Engine默认服务账户(我建议你永远不要使用它,它对项目有编辑角色,太宽泛了!),或者你可以指定要使用的服务帐户(--service-account= 参数)

然后,在您的代码中,只需使用 ADC 机制(应用程序默认凭据)来获取您的凭据,例如 Python

import google.auth
credentials, project_id = google.auth.default(scopes=SCOPES)

我找到了解决问题的方法。

首先,按照的建议,我使用了google.authADC机制:

import google.auth
credentials, project_id = google.auth.default(scopes=SCOPES)

但是,由于我需要模拟 GSuite(现在是 Workspace)的帐户,因此此方法还不够,因为此方法生成的 credentials 对象没有 with_subject 属性.这让我想到了这个类似的 post 和特定的 ,它可以将 google.auth.credentials 转换为 service_account.Credentials.from_service_account_file 返回的 Credential 对象。他的解决方案存在一个问题,因为它似乎缺少身份验证范围。

我所要做的就是将 https://www.googleapis.com/auth/cloud-platform 范围添加到以下位置:

  1. 代码中的SCOPES变量
  2. Google 管理 > 安全 > API 控制 > 为我正在部署的服务帐户设置客户端 ID 和范围
  3. 在我的项目的 OAuth 同意屏幕上

之后,我的云 运行 可以访问能够在不使用密钥文件的情况下模拟用户帐户的凭据。