AWS Lambda:如何将秘密存储到外部 API?
Posted
技术标签:
【中文标题】AWS Lambda:如何将秘密存储到外部 API?【英文标题】:AWS Lambda: How to store secret to external API? 【发布时间】:2015-06-05 00:10:26 【问题描述】:我正在构建一个基于 AWS Lambda 的监控工具。给定一组指标,Lambda 应该能够使用Twilio API 发送 SMS。为了能够使用 API,Twilio 提供了一个帐户 SID 和一个身份验证令牌。
我应该如何以及在哪里存储这些秘密?
我目前正在考虑使用AWS KMS,但可能还有其他更好的解决方案。
【问题讨论】:
使用 AWS 参数存储:hackernoon.com/… 或者使用环境变量。 【参考方案1】:这是我想出的。我正在使用 AWS KMS 将我的秘密加密到一个文件中,然后我将其与代码一起上传到 AWS Lambda。然后当我需要使用它们时解密它。
以下是要遵循的步骤。
首先创建一个 KMS 密钥。你可以在这里找到文档:http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html
然后加密您的秘密并将结果放入文件中。这可以通过 CLI 实现:
aws kms encrypt --key-id some_key_id --plaintext "This is the scret you want to encrypt" --query CiphertextBlob --output text | base64 -D > ./encrypted-secret
然后,您需要将此文件作为 Lambda 的一部分上传。您可以按如下方式在 Lambda 中解密和使用密钥。
var fs = require('fs');
var AWS = require('aws-sdk');
var kms = new AWS.KMS(region:'eu-west-1');
var secretPath = './encrypted-secret';
var encryptedSecret = fs.readFileSync(secretPath);
var params =
CiphertextBlob: encryptedSecret
;
kms.decrypt(params, function(err, data)
if (err) console.log(err, err.stack);
else
var decryptedSecret = data['Plaintext'].toString();
console.log(decryptedSecret);
);
我希望你会发现这很有用。
【讨论】:
这很好,但是由于解密需要回调,这是否意味着您的函数可能会在您获得秘密之前执行?假设 lambda 需要秘密来执行这可能是一个问题。 当然如果你在解密调用之后执行需要秘钥的代码,你必须确保它是在解密回调执行之后执行的。你可以使用 Promise(我自己从来没有使用过)或者来自 caolan.github.io/async 的类似 async.waterfall 的东西 您可以更进一步,将加密的秘密存储在 S3 中。给 lambda 函数一个角色,它可以从特定存储桶中获取对象,这样您就不必在密钥更改时更新 lambda 函数,也不必担心将 API 存储在机器上。 没有。 AWS 将自动知道使用哪个密钥来解密密钥。 只是为了澄清这段代码应该在处理程序之外。这样它只会运行一次,并且不会在每个函数调用中解密秘密。更多信息:forums.aws.amazon.com/thread.jspa?messageID=686261【参考方案2】:从 AWS Lambda 对 NodeJS 4.3 的支持开始,正确的答案是使用 Environment Variables 到 store sensitive information。此功能与 AWS KMS 集成,因此如果默认值不够,您可以使用自己的主密钥来加密密钥。
【讨论】:
环境变量可以工作,但是一旦你必须多次添加变量,它就会变得更难维护。 Secrets Manager 可能更合适。【参考方案3】:嗯...这就是 KMS 的用途 :) 而且肯定比在 Lambda 函数中以明文形式存储令牌或委托给第三方服务更安全。
如果您走这条路,请查看this blog post 以获取现有的使用示例,以便更快地启动和运行。特别是,您需要将以下内容添加到您的 Lambda 执行角色策略中:
"kms:Decrypt",
"kms:DescribeKey",
"kms:GetKeyPolicy",
上面例子的其余代码有点复杂;在这种情况下,你真的应该只需要describeKey()
。
【讨论】:
您好,非常感谢您的回答,但我认为您可能还没有完全理解 KMS 背后的概念。或者也许我没有理解你的答案。 KMS 不是“密钥存储”,您无法向其中添加自定义密钥。您必须使用亚马逊为您创建的那些。最好的问候,乔纳森。 我正在考虑将 KMS 用于我的配置。如果我理解正确,我可以加密我的配置文件(键/值)。将其加密存储到 KMS。并在我需要该文件时调用它并解密?【参考方案4】:有一个 Nodejs Lambda 函数的蓝图,它首先从 kms 解密 api 密钥。它提供了一种使用 Promise 接口进行解密的简单方法。它还为您提供了授予 lambda 函数以访问 kms 所需的角色权限。蓝图可以通过搜索“algorithmia-blueprint”找到
【讨论】:
链接到任何参考文献 这是一个有用的答案。一旦进入 console.aws.amazon.com/lambda,就很容易找到该蓝图。从蓝图中创建一个函数,如果您没有存储桶并且只想查看代码,请删除 S3 触发器。还在接受的答案下方回答@KerrM 问题。【参考方案5】:无论您选择做什么,都应使用GitMonkey 之类的工具来监控您的代码存储库,并确保您的密钥未被提交或推送给它们。
【讨论】:
以上是关于AWS Lambda:如何将秘密存储到外部 API?的主要内容,如果未能解决你的问题,请参考以下文章
如何将JSON数据添加到HTML AWS lambda响应主体?
如何使用 JSON 格式将 lambda 请求 ID 记录到 AWS CloudWatch Api 网关日志组中?