【问题标题】:Authenticating gcloud SDK in Cloud Run with user credentials使用用户凭据在 Cloud Run 中对 gcloud SDK 进行身份验证
【发布时间】:2023-12-06 01:57:01
【问题描述】:

我目前正在开展一个项目,该项目将自动设置一个新的 Firebase/Gcloud 项目。它严重依赖 Firebase CLIgcloud SDK 以及用户凭据来执行几个强制性步骤。

我现在正尝试将此项目移动到 Cloud Run 上的 Docker 容器。我已经能够使用他们的built-in token-based CI command 使用用户凭据对 Firebase CLI 进行身份验证。

我想问一下是否可以使用类似的方法对 gcloud SDK 进行身份验证。

为什么服务帐户可能不起作用

我意识到像这样的服务到服务程序应该使用服务帐户进行身份验证。然而,就我而言,程序的流程是这样的:

  1. 使用 Firebase CLI 创建新的 gcloud/firebase 项目
  2. 使用 gcloud SDK 为新项目添加 IAM 绑定、启用 API、计费等

我无法使用服务帐户来验证步骤 2 中的请求,因为项目刚刚创建,因此我还没有机会授予任何服务帐户编辑或下载密钥的权限-文件。这就是我想使用代表用户凭据的令牌进行身份验证的原因。

默认情况下,Cloud Run 环境实际上有权访问托管容器的项目的服务帐号。由于此服务帐号无权编辑新创建的项目,因此使用它进行身份验证毫无意义。

目前的想法

  1. gcloud auth login --no-launch-browser - 需要用户交互,并且提供的密钥似乎在每个登录会话中都是唯一的
  2. 由于 Firebase CLI 使用用户凭据进行身份验证,也许有一种方法可以使用它来验证 gcloud SDK?
  3. 是否可以让服务帐户继承用户的所有权限?我见过几个这样的例子,但它们只适用于每个项目级别。我意识到这种解决方案有多么不合时宜。
  4. gcloud SDK 似乎将用户凭据保存在 /root/.config/gcloud 文件夹中。在设置我的 Docker 容器时,我违背了所有合理的逻辑并复制了这个文件夹。这实际上有效,当我在本地 Docker 容器上运行它时,但当我在 Cloud Run 上运行它时,默认服务帐户似乎会覆盖所有其他凭据。本地 Docker 容器可以访问复制的配置,但即使文件复制成功,gcloud SDK 似乎也无法识别它们。

编辑: 我的目的是让不太懂技术的大学通过单击按钮创建一个具有大量预定义设置的新 Firebase 项目。这包括以下步骤:

  1. 设置一个新的 Firebase 项目(它会自动设置一个新的 Google Cloud 项目)
  2. 启用结算
  3. 设置用户 IAM 角色和升级/下载服务帐号
  4. 添加谷歌分析
  5. 添加云存储
  6. 创建新的云存储桶
  7. 添加 Firestore 原生模式
  8. 复制预定义的云功能和安全角色并将其部署到云中

创建的 Google Cloud 项目必须是我们 Google Cloud 组织的一部分。项目的所有者并不重要,因为我在创建后手动设置了 IAM 角色。

以上所有步骤都适用于我的本地系统,当我使用想法 #4 时,它们也适用于 Cloud Run 之外的通用 docker 容器。我正在处理的问题是验证step #2step #3 的请求。由于这两个请求都处理新创建的项目,因此 Cloud Run 的默认服务身份目前无法拥有对这些请求进行身份验证所需的角色。这就是为什么我正在寻找一种方法来通过 Firebase CLI 在步骤 #1 中使用的相同用户凭据进行身份验证,因为这些凭据默认具有所有者权限。

【问题讨论】:

    标签: docker google-cloud-platform gcloud google-cloud-run


    【解决方案1】:

    我不确定您想要实现的目标是否可行。而且即使有可能被破解,你也不知道有一天它会不会因为版本更新或 API 变化而被破解。

    此外,在虚拟机上运行的应用程序中使用个人帐户并不是一个好主意。该日志将跟踪您作为用户而不是应用程序身份(服务帐户)。您的个人操作(在您的计算机上以及您对云的访问)和应用操作(代表您执行的操作)是什么?

    如果您关心的是部署,您可以查看 terraform,甚至可以编写自己的部署脚本。

    我不确定是否已经抓住了您所有的障碍和问题,请告诉我们更多信息,也许有很好的解决方法!

    【讨论】:

    • 我已经提供了我想要的最终结果的更详细描述。我刚刚阅读了应用程序标识,这似乎很好地解释了为什么我的想法 #4 仅适用于 Cloud Run 之外。感谢您的帮助!
    • 也许我必须避免使用 gcloud SDK 并直接调用相应的 HTTP 端点(或使用客户端库)?是否可以使用存储在 /root/.config/gcloud/application_default_credentials.json 中的 client_secret 和/或 refresh_token 来检索具有所需范围的访问令牌?
    • 我强烈建议您使用客户端库。他们为您处理令牌刷新,并查看您描述的路径。但是,理想情况下,您不应再使用 ADC,而应使用 GOOGLE_APPLICATION_CREDENTIALS 环境变量。
    • 好的,我继续使用客户端库的想法。它确实需要一些重构,但至少我可以使用 refresh_token 和 client_secret 对它们进行身份验证。我从未尝试过让 GOOGLE_APPLICATION_CREDENTIALS 指向用户凭据文件,但是一旦我重写了我的程序的其余部分,我也会尝试并对此进行试验。非常感谢你们!
    最近更新 更多