本文来自微信公众号“开源云中文社区”。
在当今的API背后,通常有许多服务处理一个请求。单一应用程序直接在互联网上公开并负责处理整个API请求的日子已经一去不复返了。现在,这个过程通常更加复杂——请求通过负载均衡器到达API网关,然后被转发到负责具体端点的服务。为了处理请求,该服务通常会调用其他数据源或服务,而这些数据源和服务可能会调用更多的服务等。
正如你所看到的,许多通信发生在现代的软件服务网格中。但为了遵守零信任标准,公司必须妥善确保所有这些请求的通信安全。因为在这个基于云的服务和不断增加的漏洞的新时代,仅在外围实施安全策略已经不够了。
服务必须接收足够的信息,以便在网格内实施适当的安全解决方案。这以身份数据的形式出现,以执行授权决策。有了这些数据,服务就可以知道谁在请求什么,以及代表谁提出请求。然而,这开启了身份分发试图解决的一系列新问题。
什么是身份分发?
身份分发有助于确保在由API组成的复杂服务网格中,每一方都安全地处理请求并执行明智的授权决策。它使身份数据能够连续验证,而不仅仅是在外围。
然而,身份必须安全地分布在所有系统组件之间。此外,不建议基于请求标头或正文中设置的纯值执行授权。相反,签名的令牌或证书应用于此任务,因为它们提供了验证数据真实性的方法。
不仅仅是验证用户
当考虑请求中的身份信息时,人们会立即想到发起请求的经过身份验证的用户。然而,身份分发不仅仅关乎用户。接收请求的服务应验证请求的来源。它应该验证最初发送请求的外部应用程序,并使用调用者的允许列表。服务还应该能够通过限制各方之间不必要通信的机制来验证直接内部调用方,例如API网关或转发请求的另一个服务。
缓解API安全风险
在分发用户身份时,首先想到的可能是一个简单的解决方案:在外围获取用户的凭据(如会话ID或访问令牌),并将其传递给所有其他服务。
然而,这种解决方案引入了两个问题。首先,它打破了最低特权原则。假设你将原始凭证传递给所有服务。在这种情况下,现在意味着处理请求的每个服务都具有原始调用者(前端应用程序)拥有的所有权限。如果组织内部有一个流氓行为者,这可能会造成安全漏洞。如果某个服务将特权令牌发送给外部服务,也可能会造成漏洞。
第二个问题是原始凭证可能包含有关实体(例如用户)的重要信息。其中一些信息可能是敏感的,不应与各方共享,特别是当单个请求跨越组织边界时。
身份分发是一个组织问题
身份分发的安全益处取决于所使用的技术选择和实现。最终,这都是关于令牌或证书的传递,并根据既定算法进行验证。授权决策是使用软件工具做出的,如授权管理系统或验证令牌的代码。尽管如此,身份分配问题绝不是纯粹的技术问题,而是一个组织问题。
组织应该花时间来决定哪些服务应该获得哪些身份数据来正确处理授权决策。你必须知道用户的哪些信息可以安全地跨越组织边界。这将决定数据在令牌中的显示方式,以及何时交换令牌。例如,某些服务需要用户的社会安全号码来正确授权请求,因此令牌将包含该号码作为声明。然而,这是一条敏感的信息,任何不需要它的服务都应该在没有此声明的情况下接收令牌。
一方面,需要验证哪些用户或客户端信息可以安全地与哪些服务共享。另一方面,需要具体确定这些服务需要哪些信息来执行完全知情的授权决策。
身份分发技术
不同的技术可以帮助正确实现身份分发。一旦知道哪些信息应该与凭证一起传递,哪些方应该接收这些信息,就可以考虑以下解决方案来在服务网格中充分分配身份。
确保所有流量安全
如今,传输层安全(TLS)在互联网上几乎无处不在。当从应用程序向API发送包含凭据(令牌或会话)的请求时,这是一种很好的方法,也是必须的。然而,在周界终止TLS仍然很常见。负载均衡器或API网关通常会接收到加密请求,但随后会通过普通HTTP连接不加密地转发该请求。这不是最佳实践——TLS应该端到端使用,甚至在网格中的服务之间使用。这允许你的服务控制其他服务的调用,帮助锁定基础设施。
锁定基础设施
通过在网格中的所有服务之间使用加密连接,可以引入对通信的控制。通过相互TLS(mTLS)和SPIFFE或Kubernetes入口设置等框架,你可以确保服务仅由特定服务调用。这甚至可以取代传统使用的其他形式的凭证。例如,服务可以使用mTLS而不是硬编码密码对数据库进行身份验证。mTLS还可以保护位于不同集群或数据中心的服务之间的流量。这种保护并不能取代业务级别的授权,但在创建安全的服务网格方面发挥着重要作用。
使用完善的标准
服务需要一种安全可靠地获取身份数据以做出授权决策的方法。这些数据可以以多种形式提供,但建议使用既定标准。OAuth和JSON Web令牌(JWT)是非常适合此目的的久经考验的标准示例。公司应确保发行符合OAuth流和安全最佳实践的代币,而不是开发定制解决方案。如果按照当前的最佳实践使用,JWT在服务之间分发身份数据是非常可靠的。
基于声明的授权
OWASP在其API安全漏洞排名中,将破坏的授权列为第一大API漏洞。这突出了身份分发对于向正确的服务提供正确的身份数据,以便他们能够执行正确的授权决策是多么重要。服务应该使用基于声明的授权,而不是依赖API键或范围,因为它为复杂的授权提供了最佳解决方案。使用声明允许服务轻松地将授权外部化到权利管理系统,如开放策略代理(OPA)。
不透明令牌作为隐私增强
为了更好地保护访问令牌中的身份数据,建议使用不透明令牌。与JWT不同,不透明令牌不会向前端应用程序或窃听者透露任何信息。当向第三方应用程序颁发令牌时,这一点尤为重要,因为组织无法控制令牌的使用情况。然而,使用JWT更方便服务。作为自包含的令牌,JWT不需要接收者不断地查询中央服务以检查令牌的有效性或读取相关的身份信息。为了充分利用这两者的优点,公司应该考虑实施Phantom Token方法,在这种方法中,不透明的令牌在基础设施之外使用,而相关的JWT分布在服务网格内。
使用令牌共享技术
在处理单个请求时调用其他服务的服务应确保在链中传递正确的令牌。在某些情况下,共享原始服务接收的相同令牌是可以接受的。当服务在概念上接近时,这可能是有意义的。但对于其他服务,原始服务应该发送包含尽可能少的细节的令牌。它应该有足够的细节来执行授权决策,并遵守最小特权原则。这可以通过以下令牌共享技术实现:
——嵌入令牌,以便原始令牌包含信息较少的其他令牌。
——交换令牌,其中原始服务将令牌交换为仅包含相关信息的另一个令牌。
结论
API需要身份数据来执行授权决策。在现代服务网格中,必须分发这些数据,以便参与请求处理的所有各方都能保持相同的安全级别。实施适当的身份分发技术对于保持API和用户数据安全至关重要。请记住,在设计身份分发时,应考虑到只有在必要时,才能在服务之间共享数据和凭据。