Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

身份提供商

ZeroClaw 通过 OpenID Connect 为用户登录,并且对提供方签发的访问令牌要求严格。大多数提供方需要更改设置,部分提供方目前尚不可用。本页列出提供方的要求、使用 v0.9.0 预发布版本测试过的提供方、已知暂不可用的提供方以及当前的限制。只有 测试过的提供方 下列出的提供方已知可以正常工作。如需配置提供方,请参阅 OIDC 和 Dashboard 登录。

守护进程使用相同的规则验证每个访问令牌,无论该令牌是通过仪表板登录获得,还是来自原生客户端(zerocode,或来自 zeroclaw oidc login 的令牌)。因此,某个提供方的访问令牌若被拒绝,则在所有场景下都会被拒绝。zeroclaw oidc login 和 zeroclaw oidc token 仅负责获取令牌并将其打印出来。在这两个命令中登录成功,并不能说明守护进程会接受该令牌。

服务提供方所需条件

  • 发现机制。 <issuer>/.well-known/openid-configuration 文档声明的颁发者必须与已配置的 issuer 完全一致,包括末尾的斜杠。
  • 使用 S256 的 PKCE,用于浏览器登录。 控制台登录、zeroclaw oidc login --browser 以及网关的浏览器注册都要求发现文档在 code_challenge_methods_supported 中列出 S256。如果颁发方省略了该字段,它们会拒绝该颁发方,因为缺少该字段即表示不支持 PKCE;plain 则始终不被接受。设备授权(device grant)和 client_credentials 不读取此字段。
  • 设备授权模式,适用于 zerocode 和 zeroclaw oidc login。 zerocode 以及不带 --browser 的 zeroclaw oidc login 使用设备授权模式(RFC 8628)登录,因此提供方必须支持该模式,并在发现文档中列出 device_authorization_endpoint。控制台登录不使用此模式。
  • ZeroClaw 可以验证的访问令牌, 通过以下两种 validation 模式之一:
    • jwks:一个符合 RFC 9068 的 JWT 访问令牌,其头部 typ 为 at+jwt(或 application/at+jwt),使用 RS256 或 ES256 签名。它必须包含 iss、aud、exp、iat 和 jti,并在 client_id 中标明其客户端(对于用户令牌,可接受 azp)。颁发者密钥集中的每个密钥都需要有各自的 kid。类型为 JWT 或未设置 typ 的 JWT(许多提供方默认颁发此类令牌)会被拒绝,因为它无法与 ID 令牌区分。
    • introspection:基于 RFC 7662 的令牌内省,其响应包含 active: true、token_type: Bearer、已配置的 audience 以及 client_id。发现文档必须列出 introspection_endpoint。此模式需要条目的 client_secret。
  • 不得带有任何标识其为其他类型令牌的标记。 无论哪种模式下,令牌(或内省响应)都不得包含 nonce 声明。若存在 typ 或 token_use 声明,则必须表明其为访问令牌:typ 为 Bearer 或 at+jwt,token_use 必须严格为 access。
  • 受众。 访问令牌的 aud 必须包含已配置的 audience。
  • 无需额外作用域的角色或组。 ZeroClaw 仅请求 openid 作用域,因此 claim_path 处的值默认必须包含在访问令牌(或内省响应)中。否则,请逐个映射用户,例如使用 claim_path = "sub"。
  • 按请求进行客户端认证。 授权码交换(仪表板登录、zeroclaw oidc login --browser 以及网关的浏览器注册)会在表单正文中发送 client_secret(client_secret_post)。内省、设备授权和 client_credentials 则使用 HTTP Basic 发送它(client_secret_basic)。如果提供方只接受为客户端注册的那一种方法,那么设备授权或 client_credentials 可能需要单独的 [oidc.<alias>] 条目和客户端。使用 introspection 的仪表板登录无法这样拆分:同一个客户端既执行交换又执行内省调用,因此它必须同时接受两种方法。
  • 工作会话的令牌有效期,例如一到八小时。该控制台不使用刷新令牌,因此会话会在其访问令牌过期时结束。

测试过的提供商

每个提供方都使用仪表板登录方式测试了一个管理员账户和一个普通成员账户,并验证了其声明映射到的配置文件。在 Bearer 路径上,同一提供方的 ID 令牌、刷新令牌,以及发给该提供方另一个客户端的访问令牌,均被拒绝。测试针对 2026 年 10 月和 11 月的 v0.9.0 预发布版本进行。Keycloak 分别在网关使用 HTTP 和使用其自身 TLS 监听器的情况下测试,并通过 zerocode 和 zeroclaw oidc login 进行。Zitadel 和 Authelia 仅测试了仪表板登录。

提供者Version testedvalidation
Keycloak26.8.0jwks 或 introspection
Zitadel,自托管v4.20.1introspection
Authelia4.39.28jwks

Keycloak

  • 开启客户端的 RFC 9068 访问令牌头部(access.token.header.type.rfc9068 = true),要求 PKCE 使用 S256,并将访问令牌有效期设置为一到八小时。Keycloak 的默认值为五分钟。
  • 添加一个 audience mapper,将配置的 audience 放入访问令牌中。
  • 添加一个组成员映射器,令牌声明名称为 groups,不包含完整路径,对应 claim_path = "groups"
  • 被测试的客户端还配置了一个硬编码的 client_id 声明映射器。若没有该映射器,请参阅 Keycloak 访问令牌客户端归属。
  • 对于 introspection,还需添加一个使用客户端自身客户端 ID 的 Audience 映射器。Keycloak 26.6.2 及更高版本对于未指明请求客户端的令牌,内省结果会返回 inactive。

Zitadel

  • 创建一个 Web 应用,其身份验证方式选择 Code(HTTP Basic)或 Post。两种方式均已测试。请勿选择 PKCE 方式:它会创建不带 secret 的客户端,而 introspection 需要 secret。ZeroClaw 无论使用哪种方式都会发送 PKCE challenge。
  • 为每个人在项目中分配一个角色。被测试的项目还开启了角色断言功能。
  • 设置 audience 为项目 ID,并设置 claim_path = "urn:zitadel:iam:org:project:roles"。
  • jwks 无法使用:Zitadel 的访问令牌要么是不透明令牌,要么是类型为 JWT 的 JWT。

Authelia

  • 使用 token_endpoint_auth_method: client_secret_post、access_token_signed_response_alg: RS256 和 PKCE S256 注册客户端。默认的 client_secret_basic 会导致授权码交换失败。
  • 将客户端的 audience 设置为已配置的 audience,并使用 requested_audience_mode: implicit。Authelia 的默认值 explicit 仅在客户端请求时才添加 audience,而 ZeroClaw 不会请求。
  • 逐一映射用户(claim_path = "sub")。Authelia 的 group claim 需要 groups scope,而 ZeroClaw 不会请求该 scope。
  • introspection 无法正常工作:Authelia 的 introspection 响应中没有 token_type。
  • Authelia 仅通过 HTTPS 提供其 issuer 服务,因此其证书必须链接到守护进程信任的证书颁发机构(参见 Limitations)。

已知暂不可用

以下提供方已经过测试,在 v0.9.0 中没有可正常工作的配置:

  • Dex(v2.46.1)的 JWT 访问令牌头部没有 typ,且携带登录 nonce;其 introspection 将令牌标记为 token_use: access_token,对 ID 令牌的应答方式也相同。若接受这种令牌,ID 令牌就可能被当作访问令牌使用,因此仍然拒绝。
  • Authentik(2026.8.5)。其访问令牌的类型为 JWT,并携带登录 nonce,其内省响应中没有 token_type。
  • Logto(1.45.0,已通过 zeroclaw oidc login 测试,未使用仪表板进行测试)。除非令牌请求中指定了 RFC 8707 的 resource,否则其面向用户的访问令牌是不透明的,而 ZeroClaw 尚未发送该参数。因此用户无法登录。使用 client_credentials 的 Logto 服务客户端只有在设置了默认 API 资源,并将 Logto 签名密钥轮换为 RSA 后才能工作:其默认密钥使用 ES384 签名,而 ZeroClaw 不验证该算法。

以下提供方尚未经过测试。根据其文档、已发布的发现文档及源代码,预计它们目前还无法正常工作:

  • Amazon Cognito。 其发现文档(discovery document)中未列出 S256,其访问令牌(access token)的头部没有 typ 字段,并且它没有内省端点(introspection endpoint)。
  • Ory Hydra(v26.2.0)。其 JWT 访问令牌的类型为 JWT,其内省(introspection)接口仅在管理端口提供,且不包含在发现文档中。

除此之外的其他提供方(无论是托管的还是自托管的)尚未经过测试。请对照服务提供方需要满足的条件进行检查。常见的阻碍包括:访问令牌的类型不是 at+jwt、不透明令牌没有内省(introspection)支持,以及 discovery 文档未声明支持 S256。

v0.9.0 的限制

  • 不支持 RFC 8707 的 resource 参数。 仅在指定资源时才签发可验证访问令牌的提供方(例如 Logto)目前无法完成用户登录。
  • 不可配置作用域。 每个请求都只申请 openid,因此提供方仅在其他作用域(通常是 groups)下才会返回的声明永远不会到达。
  • 不支持为每个提供商单独配置私有证书颁发机构。 颁发方的 TLS 证书必须链接到守护进程已信任的证书颁发机构。没有可为单个提供商添加证书颁发机构的设置。
  • 当网关自行提供 TLS 服务时,CLI 的网关管理命令无法工作(#12091)。
    • 受影响的命令包括:所有形式的 zeroclaw gateway get-paircode、zeroclaw sop pending、logs、approve 和 deny,以及 zeroclaw gateway restart。
    • 他们始终通过明文 http:// 连接,因此启用 [gateway.tls] 后,连接会失败,并提示 “Failed to connect to gateway”。
    • zeroclaw gateway restart 会将该失败识别为“没有正在运行的 gateway“,并尝试在同一地址上再启动一个。
  • 当会话被再次验证时发生提供方中断,会导致仪表板用户被登出(#12096)。
    • 网关会再次验证已登录会话的令牌:
      • 在每次内省重新验证截止时间(revalidation_secs);
      • 在配置重新加载后,无论处于 validation 模式下的哪种情况;
      • 当其授权检查因策略变更而失败时(对 [oidc]、[users]、[permission_profiles] 或 security.trust_daemon_uid 的修改)。
    • 如果当时无法连接到提供方,或提供方返回错误,会话即告结束。系统采用失败关闭(fail closed)策略:任何不应被允许的内容都不会被放行。
    • 仪表板显示该会话已过期。网关日志记录的真实原因为 dashboard session ended: verifying its token again failed。
    • 用户在身份提供方恢复正常后需要重新登录。
    • 在不重新加载或更改策略的情况下,jwks 会话不会被再次验证。它会保持已验证的身份,直到其令牌或会话过期,无论提供方停机多久。
    • 五分钟密钥缓存仅对新提交的令牌生效,例如新建的 zerocode 连接。此类令牌会在上一次获取密钥之后的最多五分钟内使用缓存的密钥进行验证;超过该时间后则会被拒绝,直到提供方作出响应为止。重新加载或策略变更会从没有缓存密钥的状态开始。
  • 受限范围账户的仪表板聊天仅在其连接期间有效。 刷新页面、离开聊天或连接中断都会结束对话,新建聊天将开始一个新的对话。聊天记录会被保留,但仪表板无法重新打开该记录。参见 仪表板登录。