5 个不稳定版本
0.3.2 | 2022 年 8 月 1 日 |
---|---|
0.3.1 | 2022 年 8 月 1 日 |
0.3.0 | 2022 年 7 月 31 日 |
0.2.0 | 2022 年 7 月 27 日 |
0.1.0 | 2022 年 7 月 23 日 |
#2183 在 加密学 中
77KB
1.5K SLoC
rs-attenuable-jwt
Rust 中可衰减 JWT 实现
衰减有什么好处?
通常,系统以分层方式构建,其中一个组件可能会利用另一个组件代表其管理一个实体。衰减允许父组件向子组件提供范围更窄的令牌,确保该子组件只能访问它需要的资源。这种动态执行最小权限原则,确保即使在其他编程错误面前,父组件也可以确保子组件只能访问执行父请求所需的资源。
例如,可能有一个客户端系统需要管理用户和文档。不需要用户组件能够更改文档,反之亦然。客户端可以收到一个全访问 JWT 声明一些 sub
和受众 "api.example.com"。然后客户端可以衰减该 JWT,添加一个限制受众为 "users.api.example.com" 的声明,并将该衰减 JWT 交给用户组件,确保用户组件只能执行用户请求。同样,客户端可以衰减相同的初始 JWT,添加一个限制受众为 "documents.api.example.com" 的声明,并将该衰减 JWT 交给文档组件。后端只需确保每个服务验证它收到的 JWT 的 aud
声明。
可调节的JWT不会对你的用例中“衰减”的性质做出任何假设。此库的用户必须提供一个函数,该函数在给定一组现有声明和一组衰减声明后,返回衰减后的活动声明。在这种情况下,resolve_claims
函数需要确保衰减后的aud
声明是现有aud
声明的一个子域。一般来说,resolve_claims
函数的责任是确保衰减只限制权限,而不会扩展与令牌关联的权限。
概述
可调节的JWT允许你提供一个带有声明的根JWT,签名方式随意。其中之一(用于“衰减密钥”)是公共衰减密钥的JWK。通过向客户端提供JWT和私有衰减密钥,客户端可以创建另一个带有附加声明的JWT(包括aky
声明中的新公共衰减密钥的JWK),并由私有衰减密钥(与原始JWT声明中的公共衰减密钥相对应)签名,然后将JWT链和最新的私有衰减密钥传递给另一个客户端。当客户端想要使用可调节的JWT时,它创建一个带有jwts
声明的信封JWT,该声明包含JWT链的数组,并使用最终私有衰减密钥对信封JWT进行签名,该密钥与jwts
数组中最后一个JWT的aky
声明中的公共JWK相对应。验证包括
- 验证信封是否使用最终衰减密钥进行签名。
- 验证
jwts
链中的每个JWT是否使用与前面JWT中aky
声明中的公钥相对应的私钥进行签名。 - 验证
jwts
链中的第一个JWT是否使用预期的根密钥进行签名。 - 验证通常的
exp
、nbf
、iss
、aud
等声明。
安全不变量
- 一旦JWT被
sealed
,没有访问最终私有衰减密钥的情况下,衰减链中的任何声明都不能被删除。 - 只有拥有JWT链和对应于链中某个
aky
JWK的私钥的客户端才能添加声明。 - 没有任何拥有JWT链和对应于其最终
aky
JWK的私钥的客户端可以删除先前的声明或衰减。
不变量1
一旦JWT被密封,其全部内容(有序的内部JWT数组)将使用衰减密钥进行签名,该密钥的公钥是签名有效负载的一部分。签名需要访问最终私有衰减密钥,并确保无法修改有效负载。
不变量2
验证确保JWT形成一个链,其中每个JWT都使用与前面JWT中aky
声明中的公共JWK相对应的私钥进行签名。客户端需要访问对应于链中某个aky
声明的私钥,才能将JWT添加到链中。因此,如果没有对应于链中某个aky
声明的私钥,没有任何客户端可以添加JWT到链中。
不变量3
客户端只能在对应JWT的aky
JWK声明的私用衰减密钥之后立即将JWT添加到链中。因此,保持不变量3取决于确保每个客户端只能接收JWT链和对应于该链中最后一个JWT的aky
声明的私钥。这确保了每个客户端只能将其接收到的JWT链中的JWT添加到末尾。显然,客户端可以从链的末尾删除一些JWT,但使用该令牌需要提供一个密封的JWT,这需要使用与最终JWT的aky
声明中的公共JWK对应的私钥进行签名。因此,如果客户端只有对应于最终JWT的aky
声明中的公共JWK的私用衰减密钥,它必须在其希望通过验证的任何信封中包含所有到最后一个JWT的JWT。
现有技术
本方案的核心密钥链结构灵感来源于biscuit。除了支持衰减外,Biscuit还附带了一种非常出色的声明性授权语言。如果您可以使用Biscuit,我们建议您这样做。如果您需要继续使用传统的JWT,但又希望获得链式保管衰减的好处,那么attenuable-jwt可能是正确的选择。
贡献
我们欢迎贡献。除了Linux目标外,库的核心功能必须在wasm32-unknown-unknown和wasm32-wasi环境中可用,尽管可能通过功能标志提供其他功能。
依赖关系
~1–2.3MB
~49K SLoC