9

我使用 Google Source Repository 来存储我的 Google Cloud Functions。(基本上由 Google 托管的 Git 存储库)

我的一项功能需要访问私人 Google 表格文件,因此我创建了一个服务帐户。(权利太多了,因为很难理解我们应该给服务帐户哪些确切的权利,而且以后很难更新,但我离题了)

现在,出于显而易见的原因,显然不建议将服务帐户 JSON 文件存储在 git 存储库本身中。这是它的样子(从值中剥离)

{
  "type": "service_account",
  "project_id": "",
  "private_key_id": "",
  "private_key": "",
  "client_email": "",
  "client_id": "",
  "auth_uri": "",
  "token_uri": "",
  "auth_provider_x509_cert_url": "",
  "client_x509_cert_url": ""
}

我一直在寻找环境变量来配置函数或类似的东西,但没有找到任何东西。跟踪密钥(因此可能在多个存储库中复制该文件)听起来确实不是一个好主意。但我还没有找到任何“正确”的方法来做到这一点。而且由于 Google Functions 的工作方式,除了环境变量,我想不出其他任何东西。

4

6 回答 6

7

您可以将服务帐户文件与您的函数一起上传,并在您的代码中使用它。它将在那里保持安全。大多数开发人员将使用 .gitignore 或等效机制来防止将该文件添加到源代码管理中。有一个从Firebase 示例加载服务帐户凭据的示例。(如果您不使用 Firebase SDK,则必须注意将函数定义转换为 Cloud 样式。

您也可以使用 env var,但在引用和转义值时必须特别小心,以确保它们正确地到达您的函数。这有点麻烦,但可行。

于 2018-02-03T22:14:09.407 回答
7

我将云功能与服务帐户一起使用时的解决方案是:

  1. 使用 Cloud KMS/ Vault加密您的服务帐户凭据 json 文件并将其上传到 Cloud Storage。
  2. 从 Cloud Storage 中获取服务帐户凭据 json 文件,并使用具有加密/解密权限的 Cloud KMS 服务帐户对其进行解密。

  3. 在运行时解析服务帐户凭证 json 文件并获取private_key,client_emailprojectId.

  4. 将这三个秘密变量传递给客户端库

我们将配置变量存储为云功能的环境变量,它们是纯文本,但没关系。因为它们不是秘密的东西。

我们不能存储诸如纯文本之类的秘密内容,例如云函数环境变量。

于 2019-08-17T05:58:34.927 回答
2

截至 2020 年 1 月,Google 发布了Secret Manager描述为

Secret Manager 是一项新的 Google Cloud 服务,它提供了一种安全便捷的方法来存储 API 密钥、密码、证书和其他敏感数据。Secret Manager 提供了一个中心位置和单一事实来源,用于管理、访问和审核 Google Cloud 中的机密信息。

对于 Cloud Functions,这里有一个关于如何创建密钥然后从云函数中检索它的教程。

于 2020-08-26T08:41:44.297 回答
0

这就是我解决这个问题的方法。首先在文件keys.js中创建一个逻辑来确定你是在开发还是生产(并创建相应的./dev.js和./prod.js文件,你应该在.ignore文件中包含./dev.js到确保它没有上传到您的 github 远程):

if (process.env.NODE_ENV === "production") {
  module.exports = require("./prod");
} else {
  module.exports = require("./dev");
}

其次,您需要上述逻辑所在的 keys.js 文件,并根据从 keys.js 收到的数据创建凭证对象:

const credentials = {
  type: keys.googleType,
  project_id: keys.googleProjectId,
  private_key_id: keys.googlePrivateKeyId,
  private_key: keys.googlePrivateKey,
  client_email: keys.googleClientEmail,
  client_id: keys.googleClientId,
  auth_uri: keys.googleAuthUri,
  token_uri: keys.googleTokenUri,
  auth_provider_x509_cert_url: keys.googleAuthProviderX509CertUrl,
  client_x509_cert_url: keys.googleClientX509CertUrl
};

现在,对于每个谷歌云服务,您都可以使用以下示例模式:

  const storage = new Storage({
    project_id: credentials.project_id,
    credentials
  });
  const client = new textToSpeech.TextToSpeechClient({
    project_id: credentials.project_id,
    credentials
  });
...
etc.
于 2019-04-28T15:58:12.983 回答
0

我认为您实际上不需要在代码中存储任何密钥文件。

您的函数使用指定的服务帐户(通常是“App Engine 默认服务帐户”,但您可以在高级设置中进行更改)运行。如果您有特定需求,您应该为您的功能创建一个特定的服务帐户,并为其授予所需的所有权限。

在您的函数中,身份验证将使用Application Default Credentials自动进行,因此您不必关心任何事情(忘记环境变量、密钥文件或任何东西)。只需确保您将 Google Cloud 客户端库用于您的语言,它们将为您隐式处理所有内容。

特别是,我避免像@slideshowp2 提出的那样创造性的解决方案。但我同意它们有它的用途(例如,假设我需要存储外部系统的凭据,超出 GCP 范围。在这种情况下,他的解决方案可能是一种可行的方法),但是只使用 Google 服务,让我们保留它简单的。

于 2020-08-26T05:12:55.993 回答
0

在这里,您可以找到如何使用环境变量为您的应用程序提供凭据GOOGLE_APPLICATION_CREDENTIALS

于 2018-02-07T18:44:23.657 回答