Google 云功能:支持 Google 云 KMS

Google Cloud Function : support for Google Cloud KMS

我正在使用带有 Pubsub 触发器的 Google 云函数 (GCF),该触发器向第三方发送 HTTP 请求 API。

GCF 从服务使用的 Pubsub 主题接收通知,该服务不应知道第三方 API。

第三方 API 需要使用基本 HTTP 身份验证进行身份验证。

为了不必在我的源代码中对密码进行硬编码,我使用 Google KMS 在每次部署我的函数时生成一个新的加密密钥。每次实例化函数时,我都使用 Google Cloud KMS 来解密秘密。

为了使用 KMS 解密,我必须向 NodeJS 提供服务帐户的私钥 Google API。

我今天的主要问题是,如果我想让我的 GCF 正常工作,我必须将我的私钥推送到 GCloud Bucket。

是否可以使用运行时配置器或部署管理器为 Google 云功能配置机密?

谢谢。

Is it possible by using either the Runtime Configurator or the Deployment Manager to configure secrets for a Google Cloud Function?

目前没有内置服务可以让您将密文配置为由 Google Cloud Functions 直接访问,因此您当前使用的方法是在 Cloud 上处理密文的正确方法暂时发挥作用。这可能会改变,因为该产品仍处于测试阶段。

如果您愿意,可以使用适当的 issue tracker.

向 Cloud Function 团队提出功能请求

最近几个月才出现的另一个解决方案是使用 Google Cloud Runtime Configuration with Firebase for Functions: https://firebase.google.com/docs/functions/config-env

Firebase for Functions 似乎提供了对通过其他方式尚不可用的多项功能的访问。

Runtime Configurator 不收取使用费,但强制执行以下 API 限制和配额:

  • 1200 Queries Per Minute (QPM) for delete, create, and update requests
  • 600 QPM for watch requests.
  • 6000 QPM for get and list requests.
  • 4MB of data per user, which consists of all data written to the Runtime Configurator service and accompanying metadata.

https://cloud.google.com/deployment-manager/pricing-and-quotas#runtime_configurator


顺便说一句,我发现 Firebase for Functions 中的这个冲突很滑稽:

The Firebase SDK for Cloud Functions offers built-in environment configuration to make it easy to store and retrieve this type of data for your project without having to redeploy your functions.

然后稍后:

After running functions:config:set, you must redeploy functions to make the new configuration available.


KMS 解决方案是一个可行的替代方案,但它的功能成本似乎很高。 KMS 的收费标准为每个活动密钥每月 0.06 美元,以及每 10,000 次操作 0.03 美元。

这会将您的 Cloud Functions 的成本从每百万次调用 0.40 美元更改为每百万次调用 3.40 美元。真是飞跃。

截至 2019 年 12 月,在 Google 云上存储和管理机密的首选方式是 Secret Manager

$ echo -n "user:pass" | gcloud beta secrets create "my-basic-auth" \
  --data-file=- \
  --replication-policy "automatic"

您还可以从 API:

创建和管理机密
// Import the library
const {SecretManagerServiceClient} = require('@google-cloud/secret-manager');

// Create the client
const client = new SecretManagerServiceClient();

// Create the secret
const [secret] = await client.createSecret({
  parent: "projects/<YOUR-PROJECT-ID>",
  secretId:"my-basic-auth",
  secret: {
    replication: {
      automatic: {},
    },
  },
});

// Add the version with your data
const [version] = await client.addSecretVersion({
  parent: secret.name,
  payload: {
    data: Buffer.from("user:pass", "utf8"),
  },
});

然后,在您的云函数中:

const [version] = await client.accessSecretVersion({
  name:"projects/<YOUR-PROJECT-ID>/secrets/<MY-SECRET>/versions/1",
});

const auth = version.payload.data.toString('utf-8');

// auth is user:pass

用于部署 Cloud Function 的服务帐户需要 roles/secretmanager.secretAccessor 权限。

还有一个 Google 云密钥管理服务:Node.js Client

cd functions
npm install @google-cloud/kms

例如:

// Imports the Cloud KMS library
const {KeyManagementServiceClient} = require('@google-cloud/kms');

// Instantiates a client
const client = new KeyManagementServiceClient();

// Build the location name
const locationName = client.locationPath(functions.config().firebase.projectId, functions.config().firebase.locationId);

async function listKeyRings() {
  const [keyRings] = await client.listKeyRings({
    parent: locationName,
  });
  for (const keyRing of keyRings) {
    console.log(keyRing.name);
  }
  return keyRings;
}

return listKeyRings();