[英]Synchronously load secrets in an HTTP Google Cloud Function (NodeJS)
I have a Google Cloud Function that provides a login API endpoint. 我有一个提供登录API端点的Google Cloud Function。 The function signs a JWT using a private key.
该函数使用私钥对JWT进行签名。
Now, when deploying the function I need to securely load the private key used to sign the JWT. 现在,在部署功能时,我需要安全地加载用于签名JWT的私钥。 I cannot use environment variables or embed it in any part of the code, of course, as that is visible to anyone who can read the function in gcloud.
我当然不能使用环境变量或将其嵌入代码的任何部分,因为任何在gcloud中可以读取该函数的人都可以看到。
The options I've considered are: 我考虑过的选项有:
Create a dedicated service account for the function, plus a GCS bucket that only that service account can access, and store the secret in plain text in there. 为该功能创建专用的服务帐户,以及仅该服务帐户可以访问的GCS存储桶,并在其中以纯文本格式存储密码。 When the function loads, load the secrets (
await loadMySecrets(...)
) and carry on. 当函数加载时,加载秘密(
await loadMySecrets(...)
)并继续。
The recommended way: create a KMS key, encrypt the secrets with that key and upload the ciphertext along with the function code. 推荐的方法:创建一个KMS密钥,用该密钥加密秘密,然后将密文和功能代码一起上传。 At runtime, ask KMS to decrypt the key (
await decryptSecret(...)
). 在运行时,要求KMS解密密钥(
await decryptSecret(...)
)。
Problem is: as far as I can see, when an HTTP function is loaded, the entire loading process has to be synchronous . 问题是:据我所知,当加载HTTP函数时,整个加载过程必须是同步的 。
Your function returns a request handler and GCF then executes it. 您的函数返回一个请求处理程序,然后GCF执行该请求处理程序。 There is no opportunity to
await
a Promise before you return your request handler, and GCF does not support return Promises for HTTP functions. 返回请求处理程序之前没有机会
await
Promise,并且GCF不支持HTTP函数的返回Promises。 The GCS and KMS APIs are Promise-based, there are no *Sync()
calls supported. GCS和KMS API是基于Promise的,不支持
*Sync()
调用。
How have others gotten around this problem? 其他人如何解决这个问题? I cannot synchronously wait on my Promise to resolve (eg via
sleep()
), as that will block the Node event loop. 我无法同步等待Promise解决(例如,通过
sleep()
),因为那样会阻塞Node事件循环。 Am I forced to somehow provision the secrets synchronously or is there a way to do it async that plays nice with GCF? 我是否被迫以某种方式同步提供机密,或者是否有一种方法可以使其与GCF完美兼容?
Note: this is plain Google Cloud Functions, not Firebase. 注意:这是普通的Google Cloud Functions, 而不是 Firebase。
Note 2: there is a nuclear option, which is to move the async aspect of this into Express middleware. 注意2:有一个核心选择,即将异步方面转移到Express中间件中。 I really, really don't want to do that as I have to wrap things like
cookie-parser
and passport
, which expect secrets to be available when the middleware is first created, in async middleware which loads my secrets then delegates. 我真的非常不想这样做,因为我不得不包装
cookie-parser
和passport
类的东西,它们希望在初次创建中间件时可以使用秘密,然后在异步中间件中加载我的秘密然后委托。 Ugly and might affect performance. 丑陋,可能会影响性能。
You can make the entire function handler async (requires node 8+): 您可以使整个函数处理程序异步(需要节点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}`)
}
I saw your note about middleware. 我看到了您关于中间件的说明。 If you post a code sample, I'll try to update this to match better.
如果您发布代码示例,我将尝试对其进行更新以使其更好地匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.