在 HTTP Google 云函数 (NodeJS) 中同步加载机密

Synchronously load secrets in an HTTP Google Cloud Function (NodeJS)

我有一个 Google 云函数,它提供了一个登录 API 端点。该函数使用私钥签署 JWT。

现在,在部署函数时,我需要安全地加载用于签署 JWT 的私钥。当然,我不能使用环境变量或将其嵌入代码的任何部分,因为任何可以在 gcloud 中阅读该函数的人都可以看到。

我考虑过的选项是:

  1. 为该函数创建一个专用服务帐户,加上一个只有该服务帐户可以访问的 GCS 存储桶,并以纯文本形式将机密存储在其中。当函数加载时,加载秘密(await loadMySecrets(...))并继续。

  2. 推荐方式:创建一个KMS密钥,用该密钥加密密文,将密文连同功能码一起上传。在运行时,要求 KMS 解密密钥 (await decryptSecret(...)).

问题是:据我所知,当加载一个HTTP函数时,整个加载过程必须是同步的

您的函数 return 是一个请求处理程序,然后 GCF 会执行它。在您 return 您的请求处理程序之前,没有机会 await Promise,并且 GCF 不支持 return HTTP 函数的 Promise。 GCS 和 KMS API 是基于 Promise 的,不支持 *Sync() 调用。

其他人是如何解决这个问题的?我不能同步等待我的 Promise 解决(例如通过 sleep()),因为这会阻塞 Node 事件循环。我是被迫以某种方式同步提供机密,还是有一种异步方式可以与 GCF 配合使用?

注意:这是普通的 Google Cloud Functions,不是 Firebase。

注2:有一个核选项,就是把这个的async方面移到Express中间件中。我真的,真的不想这样做,因为我必须包装 cookie-parserpassport 之类的东西,它们希望在首次创建中间件时在加载我的秘密的异步中间件中使用秘密然后代表。丑陋,可能会影响性能。

您可以使整个函数处理程序异步(需要节点 8+):

const decrypt = async (ciphertext) => {
  result = await client.decrypt({
      name: cryptoKeyID,
      ciphertext: ciphertext,
  });
  return result.plaintext;
}

exports.F = async (req, res) => {
  const username = await decrypt(process.env.DB_USER);
  const password = await decrypt(process.env.DB_PASS);
  res.send(`${username}:${password}`)
}

我看到了你关于中间件的说明。如果您 post 代码示例,我会尝试更新它以更好地匹配。