我有几个在AWS中运行的微服务,其中一些相互通信,其中一些具有外部客户端或作为外部服务的客户端。
要实现我的服务,我需要一些秘密(RSA密钥对来签名/验证令牌,对称密钥,API密钥等)。我正在为此使用AWS SecretsManager,并且工作正常,但是我正在为密钥旋转实施适当的支持,并且我有几点想法。
比方说,服务A需要为服务B提供密钥K:
这是最好的方法还是还有其他考虑的方法?
然后,在某些情况下,我具有在同一服务中使用的对称密钥J,例如用于加密某些会话的密钥。因此,在对服务C的一个请求中,会话用密钥J1加密,然后需要在以后的阶段用J1解密。我有C服务的多个实例。
这里的问题是,如果同一秘密同时用于加密和解密,则旋转它会变得更加混乱-如果将密钥旋转为具有值J2且一个实例已刷新以便可以使用J2进行加密,则另一个实例仍然看不到J2,解密将失败。
我可以在这里看到一些方法:
与上述类似,使用单独的旋转方案分成两个秘密,然后一次旋转一个秘密。相同的值(除了轮流使用它们之间的间隔时间)会增加处理额外秘密的开销。
让解密在失败时强制刷新机密:
在密钥窗口中使用三个密钥,并始终使用中间的密钥进行加密,因为它应始终在所有其他实例的窗口中(除非已旋转几次,比刷新间隔快)。这会增加复杂性。
还有哪些其他选择?这似乎是一个标准的用例,但我仍在努力寻找最佳方法。
编辑------------------
根据JoeB的回答,到目前为止,我想出的算法是: 假设最初,机密的CURRENT值为K1,PENDING值为null。
正常运行
AWSCURRENT
,AWSPENDING
和自定义标签ROTATING
,并接受它们(如果存在)->所有服务都接受[{{ 1}} = K1] AWSCURRENT
= K1 按键旋转
AWSCURRENT
= K1,AWSCURRENT
= K2] AWSPENDING
添加到K1版本中,然后将ROTATING
移到K2版本中,然后从K2中删除AWSCURRENT
标签(似乎没有原子交换标签)。直到T秒过去,有些客户端将使用K2和某些K1,但是所有服务都接受这两者AWSPENDING
= K2,AWSCURRENT
= K1],所有客户端都使用AWSPENDING
= K2 AWSCURRENT
阶段。请注意,K1仍将处于ROTATING
阶段。AWSPREVIOUS
= K2],而K1实际上已失效。这应该适用于单独的机密和用于加密和解密的对称机密。
不幸的是,我不知道如何使用内置的旋转机制,因为它需要几个步骤,并且之间存在延迟。一种想法是发明一些自定义步骤,并使AWSCURRENT
步骤创建一个CloudWatch cron事件,该事件将在T秒后再次调用该函数,并通过步骤setSecret
和swapPending
对其进行调用。如果SecretsManager可以自动支持此功能,那就太棒了,例如,通过支持该函数返回一个值,该值指示应在T秒后调用下一步。
答案 0 :(得分:3)
对于您的凭证问题,只要服务B支持两个活动凭证,就不必在应用程序中同时保留当前凭证和先前凭证。为此,您必须确保在准备好凭据之前,不要将其标记为AWSCURRENT。然后,应用程序始终总是获取并使用AWSCURRENT凭证。为此,请在轮播Lambda中执行以下步骤:
这些是机密管理器在创建多用户RDS旋转lambda时采取的相同步骤。确保使用AWSPENDING标签,因为密钥管理器会对此加以特殊对待。如果服务B不支持两个活动凭据或多个用户共享数据,则可能无法执行此操作。参见secrets manager rotation docs。
此外,Secrets Manager旋转引擎是异步的,并且在失败后将重试(这就是每个Lambda步骤必须为幂等的原因)。首先进行一组重试(大约5次),然后再进行一些日常重试。您可以通过在例外情况下使第三步(测试密码)失败,直到满足传播条件,来利用这一点。另外,您可以将Lambda执行时间增加到15 minutes,并等待适当的时间以等待传播完成。但是,睡眠方法的缺点是不必要地占用资源。
当您删除挂起阶段或将AWSCURRENT移到挂起阶段时,请紧记,旋转引擎将停止。如果应用程序B接受当前和未决(如果希望更加安全,则接受当前,未决和先前),如果添加您描述的延迟,则上述四个步骤将起作用。您还可以查看AWS Secrets Manager Sample Lambdas,以获取有关如何针对数据库旋转操作阶段的示例。
对于您的加密问题,我看到的最好方法是将加密密钥的标识符与加密数据一起存储。因此,当您使用密钥J1加密数据D1时,您将存储或以其他方式将其传递给下游应用程序,例如秘密ARN和应用程序的版本(例如V)。如果服务A通过消息M(...)向服务B发送加密的数据,它将按以下方式工作:
请注意,密钥可以同时由A和B进行缓存。如果要长期存储加密数据,则必须确保直到加密数据不再存在或重新获得密钥后才删除密钥。 -使用当前密钥加密。您还可以通过传递不同的ARN来使用多个机密(而不是版本)。
另一种替代方法是使用KMS进行加密。服务A将发送加密的KMS数据密钥而不是密钥标识符以及加密的有效负载。 B可以通过调用KMS来解密已加密的KMS数据密钥,然后使用该数据密钥来解密有效载荷。