授权令牌
安全插件允许您配置两种类型的授权令牌:代表令牌(On-Behalf-Of,OBO)和服务账户令牌。
代表认证
以下各节描述了 OBO 令牌的用途、配置、结构和端点。
用法
代表令牌是一种特殊形式的 JSON Web 令牌(JWT),用于管理用户客户端和扩展之间的认证请求。这些令牌“即时”操作,意味着在需要认证之前立即颁发令牌。令牌具有可配置的有效期窗口(最长持续时间为五分钟),在此之后,它将过期且无法使用。
扩展可以使用 OBO 令牌与 OpenSearch 集群交互,并使用其所代表用户的相同权限。这就是为什么这些令牌被称为“代表”的原因。由于这些令牌不受限制,它们使得服务能够像原始用户一样运行,直到令牌过期。这意味着该功能的适用性不仅限于扩展相关用例,还允许更广泛的用途。
配置
在安全 config.yml
文件中,OBO 配置位于动态配置部分。它包含用于令牌签名的签名密钥和用于令牌负载(角色信息)解密的加密密钥。
config:
dynamic:
on_behalf_of:
enabled: #'true'/non-specified will be consider as 'enabled'
signing_key: #encoded signing key here
encryption_key: #encoded encryption key here
...
签名 JWT 的默认编码算法是 HMAC SHA512。签名密钥和加密密钥都经过 base64 编码,并存储在 OpenSearch 节点的文件系统上。所有主机上的密钥应相同。否则,加密和解密操作可能会失败。密钥的部署由集群操作员管理。
令牌结构
OBO 令牌的负载必须包含 JWT 的所有标准配置,以及加密和解密的角色。根据插件向后兼容模式设置,后端角色也应包含在角色声明中。缺少任何这些声明会导致令牌格式不正确,无法满足认证所需标准。
OBO 令牌包含以下声明:
- 颁发者(
iss
):OpenSearch 集群标识符- 作为安全控制措施的一部分,验证颁发者至关重要。此策略具有前瞻性,尤其是在潜在的多租户场景(如 OpenSearch Serverless)中,其中不同的加密密钥可能与每个颁发者相关联。通过检查颁发者的值,每个 OBO 令牌都仅限于其关联的颁发者。
- 颁发时间(
iat
):此令牌的当前颁发时间- 用作过期时间的参考。
- 不早于(
nbf
):令牌可使用的最早时间点- 鉴于 OBO 令牌旨在即时使用,其
nbf
应与颁发时间(iat
)对齐,表示令牌创建的时刻。
- 鉴于 OBO 令牌旨在即时使用,其
- 过期时间(
exp
):过期时间- 每个 OBO 令牌都包含一个过期机制,在接收时进行验证。一旦颁发令牌,就无法撤销。相反,令牌仅在过期时才失效。此外,扩展生成 OBO 令牌受动态设置的约束。此功能通过在某些条件下阻止颁发未来的令牌来保护系统。
- 默认配置为 OBO 令牌设置 300 秒的过期时间。鉴于不同的场景可能需要不同的令牌持续时间,OpenSearch 允许用户自定义此过期时间。令牌的最长持续时间上限为 600 秒,以维护安全性。
- 关于 OBO 令牌的当前设计,由于其旨在即时使用和短暂生命周期,令牌撤销目前不是一个问题。但是,如果未来的调整需要延长此令牌的生命周期,将添加令牌撤销功能。将采用此策略来改进和巩固与 OBO 令牌使用相关的安全措施。
- 主题(
sub
):用户标识符- 与此 OBO 令牌关联的用户的名称。
- 受众(
aud
):扩展的唯一标识符- 对于扩展用例,
aud
字段是目标服务所代表的特定扩展的引用。 - 对于 REST API 用例,API 参数
service
允许指定使用此令牌的目标服务。默认值设置为self-issued
。
- 对于扩展用例,
- 角色:安全权限评估
OpenSearch 安全插件处理加密和解密过程。这种方法确保即使在 OpenSearch 和任何第三方服务之间的信任边界上,用户信息也能得到保护。
API 端点
您可以访问安全插件上的 POST /_plugins/_security/api/generateonbehalfoftoken
API 端点,以创建短期、自颁发的 OBO 令牌,代表用户执行某些操作。
要访问此 API 端点,请求正文应包含三个 API 参数:
description
:此参数允许用户阐明请求此令牌的目的,提供清晰度和透明度。service
(可选):此参数指向 OBO 令牌的受众声明。它为用户提供了指定他们打算使用令牌的目标服务的机会。尽管这是一个可选参数,如果未指定,默认值将设置为self-issued
。durationSeconds
(可选):此参数允许用户根据其预期用途自定义令牌的过期时间。为维护安全性,最大持续时间上限为 600 秒。如果未指定,默认持续时间设置为 300 秒。以下是为用户“admin”请求一个有效期为 3 分钟的 OBO 令牌的示例,用于测试目的:
POST /_plugins/_security/api/generateonbehalfoftoken
{
"description":"Testing",
"service":"Testing Service",
"durationSeconds":"180"
}
附加授权限制
尽管关于 OBO 令牌使用的讨论仍在继续,但管理某些边缘情况至关重要。尽管 OBO 令牌可以作为任何 API 访问的有效 Bearer 授权头,但仍需要某些限制。例如,禁止使用 OBO 令牌访问 API 端点以颁发另一个 OBO 令牌。同样,禁止使用 OBO 令牌访问重置密码 API 以修改用户的认证信息。这些预防措施对于维护系统的完整性和安全性是必要的。
更多信息请参见相关讨论。
服务账户
服务账户令牌是安全插件支持的第二种认证令牌。
介绍
服务账户是一种新的authC/authZ路径,允许扩展在不承担活跃用户角色(或多个角色)的情况下运行请求。服务账户是与每个扩展关联的一种特殊类型的**主体**,并拥有一组权限。分配给服务账户的权限授予相关扩展运行任何已映射操作的授权,而无需承担活跃用户的角色,也无需在临时用户上下文中隐藏用户的角色(或多个角色)。
目前,服务账户只允许对与已映射扩展关联的系统索引执行操作。
背景
在引入服务账户之前,扩展无法在不承担活跃用户角色(或多个角色)的情况下处理请求。相反,当请求被处理时,会创建一个临时的“插件用户”。该插件用户随后会承担当前已认证操作员(人类用户)的所有权限。结果是,插件用户代表扩展行事,但拥有操作员的所有权限。通过这种方式,可以说以前的模型让扩展“模拟”操作员。这种模拟方法导致了两个主要问题:
- 模拟操作损害了**引用完整性**,这意味着审计员很难识别哪些请求是由扩展运行的,哪些是由操作员运行的。一个具有引用完整性的系统会在其审计日志中维护事务记录。该记录提供了在特定时间由不同主体执行的操作的清晰历史。当扩展在代表操作员发出的请求和自行发送的请求中都模拟用户时,审计日志就缺乏引用完整性。
- 模拟操作还使得不可能限制扩展的权限,使其超出其模拟用户的权限。当扩展承担活跃主体的角色时,它会复制所有角色。这甚至包括那些对其预期操作来说不必要的权限。这种做法不仅偏离了**最小权限原则**,还增加了威胁面。每授予插件用户一项额外的权限,配置错误或恶意扩展可能造成的潜在影响就会增加。
优势
服务账户通过定义一个独立的、自运行扩展的状态来解决“背景”部分描述的问题。服务账户通过引入一个独特的、扩展在代表自己发送请求时运行的状态来维护引用完整性。审计日志随后可以记录扩展何时自行运行(它对服务账户进行authC/authZ调用),或者它是否代表操作员运行操作,从而使用**OBO令牌**。
同样,服务账户通过将扩展承担的角色与操作员或通用硬编码用户(例如internal_users.yml
文件中的用户)的角色分开,来解决威胁暴露问题。服务账户不会承担操作员的角色,而是拥有其在服务账户中列出的自己的特权。因此,与服务账户关联的角色可以尽可能地严格,以符合最小权限原则。为避免向扩展提供过于宽泛的服务账户,扩展作者应充分理解其扩展希望运行的操作类型。
API 端点
如其名称所示,布尔标志service
表示给定内部用户账户是否为服务账户。如果一个账户不是服务账户,则任何为其生成相关授权令牌的尝试都将失败。类似地,enabled
字段决定何时可以由扩展使用服务账户来执行操作。如果服务账户未enabled
,则获取其授权令牌的尝试将被阻止,并且服务账户将无法使用先前颁发的认证令牌自行运行请求。以下是为您的服务或扩展创建具有ALL PERMISSIONS
的服务账户的示例。
PUT /_plugins/_security/api/internalusers/admin_service
{
"opendistro_security_roles": ["all_access"],
"backend_roles": [],
"attributes": {
"enabled": "true",
"service": "true"
}
处理 OBO 和服务账户请求
虽然OBO令牌处理和服务账户可以被视为独立功能,但当它们结合使用时才能实现最显著的优势。具体来说,OpenSearch公开了一个客户端,用于连接到OpenSearch集群,并为插件提供了运行请求的能力。有了OBO令牌和服务账户,该客户端现在可以用于处理同时使用这两种功能的请求。当客户端发出需要扩展使用OBO令牌的请求时,处理该请求的第一步是将请求转发到安全插件。在安全插件中,请求会根据活跃用户进行认证和授权。如果活跃用户被允许,请求会返回到OpenSearch的核心代码库,在那里创建一个请求,以便使用活跃用户的身份为目标扩展创建OBO令牌。生成OBO令牌的这个请求随后由IdentityPlugin
实现处理。在标准场景中,这是安全插件,因此请求会返回到安全插件对TokenManager
接口的实现,该实现为请求生成一个新的OBO令牌。生成令牌后,安全插件将带有OBO令牌的请求转发给扩展。此时,扩展可以使用该令牌调用OpenSearch的REST方法。然后将评估与令牌关联的权限以授权请求。如果令牌传达了操作所需的权限,则将执行该操作,并将响应发送回扩展。处理OpenSearch的响应后,扩展会将其自身对响应的处理转发给客户端。如果OBO令牌不包含启动目标操作所需的权限,则会将禁止响应返回给扩展。
代表自身行事的扩展也使用OpenSearch公开的客户端。当扩展首次在OpenSearch中初始化时,会触发IdentityPlugin
为其创建一个新的服务账户并提供相关的服务账户令牌。在默认配置中,安全插件是IdentityPlugin
并处理这些过程。OpenSearch收到服务账户令牌后,将其转发给相关扩展。扩展收到令牌后,客户端发出的利用与该扩展关联的服务账户的请求即可操作。在这些场景中,扩展从客户端接收请求,然后将请求连同服务账户令牌转发给OpenSearch。OpenSearch进一步将数据包传输到安全插件,在那里令牌被解析,并且请求被视为在InternalAuthenticationBackend
中使用“基本认证”的传统请求。
在OBO和服务账户令牌请求流中,IdentityPlugin
使用其TokenManager
接口来处理令牌的分发和处理。此接口由安全插件作为IdentityPlugin
实现,并包含颁发OBO或服务账户令牌的逻辑。