跳转至

Auth 凭据语义

这些语义使选择时和运行时认证行为保持一致。它们由以下部分共享:

  • resolveAuthProfileOrder(配置文件排序)
  • resolveApiKeyForProfile(运行时凭据解析)
  • openclaw models status --probe
  • openclaw doctor 认证检查(doctor-auth)

稳定探测原因代码

探测结果带有 status 桶(ok、auth、rate_limit、billing、timeout、format、unknown、no_model),并且在探测从未到达模型调用时带有稳定的 reasonCode:

reasonCode 含义
excluded_by_auth_order 该配置文件未包含在其提供方的显式认证顺序中。
missing_credential 未配置内联凭据或 SecretRef。
expired Token 的 expires 时间在过去。
invalid_expires expires 不是有效的正 Unix 毫秒时间戳。
unresolved_ref 配置的 SecretRef 无法解析。
ineligible_profile 配置文件与提供方配置不兼容(包括格式错误的密钥输入)。
no_model 凭据存在,但未解析出可探测的模型候选项。

资格检查会将可用凭据的原因代码报告为 ok。

Token 凭据

Token 凭据(type: "token")支持内联 token 和/或 tokenRef。

资格规则

  1. 当 token 和 tokenRef 均缺失时,Token 配置文件不合格(missing_credential)。
  2. expires 是可选的。若存在,它必须是有限的 Unix 纪元毫秒数,大于 0 且不超过 JavaScript Date 的最大时间戳(8640000000000000)。
  3. 如果 expires 无效(类型错误、NaN、0、负数、非有限值或超过该最大值),则配置文件不合格,原因为 invalid_expires。
  4. 如果 expires 在过去,则配置文件不合格,原因为 expired。
  5. tokenRef 不会绕过 expires 验证。

解析规则

  1. 解析器语义与 expires 的资格语义一致。
  2. 对于合格配置文件,Token 材料可以从内联值或 tokenRef 解析。
  3. 无法解析的引用会在 models status --probe 输出中产生 unresolved_ref。

手动 API 密钥

在 Models 中保存手动 API 密钥时,会等待 Gateway 应用任何已更改的提供方绑定,然后再刷新模型认证。替换绑定未更改的密钥只需要刷新认证。如果 Gateway 无法确认已应用,密钥仍会保存,并且响应中包含重启警告。这会保留已配置的重新加载策略,包括禁用的重新加载。删除密钥时,仍会拒绝并发更改的绑定或凭据。

设置替换

设置替换凭据保存在单独的配置文件 ID 下,并在现有凭据负载中包含内部 setup 描述符。它们不能进入正常轮换,不能通过显式配置文件固定解析,也不能复制到另一个 agent。只有所属设置操作可以测试所选凭据。在一次成功的无工具轮次后,设置会询问是否激活它。拒绝或测试失败会使已保存的凭据保持非活动状态,并保留当前连接。Model Setup 提供相同的已保存登录以进行新的测试,而无需再次登录。Gateway 激活会等待配置应用;必需的重启会使替换保持非活动状态,直到重试设置。普通登录仍然立即生效。描述符会保留所选模型和连接设置,以便重启后重试,而不会缓存验证结果。这不会添加数据库架构或迁移;旧运行时不会强制非活动状态。降级之前,请删除已保存的非活动替换,或恢复设置之前的状态。

非交互式设置会保存替换凭据,并打印一条 openclaw models auth activate <profileId> --agent <id> 命令,用于测试并激活已保存的登录。Model Setup 提供相同操作。交互式设置默认在测试成功后激活。重用现有凭据和首次运行的非交互式设置保留其现有行为。

Agent 复制可移植性

Agent 认证继承采用读穿方式。当 agent 没有本地配置文件时,它会在运行时从共享认证存储中解析配置文件,而不会将机密材料复制到其自身的凭据存储(agents/<agentId>/agent/openclaw-agent.sqlite)中。在 openclaw doctor --fix 执行一次性迁移后,共享存储位于 state/openclaw.sqlite。在此之前,doctor 会报告旧版 agents/main/agent/openclaw-agent.sqlite 所有者,并使该 agent 无法删除。

认证使用和冷却更新会等待其实际 agent 数据库所有者的写入许可,包括旧版共享存储。迁移后的共享状态认证使用其自身的协调器。排队更新保留其选定的状态根和共享所有者,然后在获得许可后读取当前配置文件。运行时快照在持久提交之后、下一个获准写入者之前发布;在其健康更新等待时删除配置文件不会重新创建其健康状态。冷 agent 打开会异步验证完整性,并在写入前重新检查所有权。OAuth upsert 在获得许可后、应用现有代际替换规则之前,会重新检查当前本地或继承的凭据。

内联 API 密钥失败记录通过其现有 SQLite worker 读取并更新所选 agent 的认证状态。它保留凭据字节和其他配置文件的健康状态。运行时快照发布会在线程外读取规范本地和共享行,然后保留当前主机已解析的机密和外部配置文件覆盖。发布失败不会重放已提交的健康更新。同步 SDK 存储 API 保留其现有契约。

Gateway 模型元数据在凭据、配置文件排序或所有权、或模型可用性发生变化时刷新,包括冷却状态和阻止状态转换。使用时间戳、成功历史和失败计数器会继续记录,而不会使聊天元数据失效或向已连接客户端广播变更。

Gateway 模型认证状态读取在同一代理和已发布的配置/认证代数下,跨客户端共享提供方准备结果。凭据警告和过期边界也会使准备结果失效;显式刷新绕过该准备。每个回复仍会计算当前过期时长,从其现有缓存读取辅助用量,并应用请求客户端的配置文件身份可见性。

基于文件的外部 CLI 引导健康状态跟随其读取方的时效生命周期,因为外部登录可以在无需 Gateway 发布的情况下发生变化。

当所属数据库的写入代数和文件身份保持不变时,重复的模型解析会复用已持久化的认证行。已提交的认证写入和运行时快照重载会立即使这些行失效。在暖缓存命中时,数据库、WAL 和日志身份每 100 毫秒最多探测一次;在该间隔或之后发生的首次读取会检测来自其他进程的变更。命中不会延长此时效窗口。缓存未命中仍在读取行之前和之后检查身份。作用域覆盖层、迁移拒绝和个人账户选择仍在每次请求时运行。隔离的代理作用域和私有数据库快照不共享此缓存。Gateway 缓存未命中会复用一个只读子连接,其生命周期在关闭时结束;每次读取都会重新获取其源准入,并在返回前关闭其 SQLite 句柄。

游离连接、cron、心跳和钩子回调保留该 Gateway 的只读工作作用域,而不继承启动或请求权限。关闭操作会在迟到的回调创建另一个读取器之前拒绝它们。

用量记录会使后续缓存复用失效,而已准入的读取可以完成其快照。凭据、选择、所有权和生命周期变更仍会使进行中的准备失效。

模型选择在其读取器完成清理后,会重试一次该过期读取,保留所选代理和任何显式配置文件固定。如果进程内 OAuth 刷新使该读取失效,选择会首先观察该所有者的持久结算,包括继承的凭据和被栅栏隔离的对等节点。此等待使用现有刷新超时,既不读取凭据也不启动另一个刷新。重连会释放对被替换声明的等待;仍处于栅栏隔离状态的对等节点的读取器会继续等待所有者的清理。

待处理的刷新配置文件仍可作为模型 ID/模式选择的候选;OAuth 所有者仍会在凭据可用之前完成刷新结算。调用方超时不会将其持久结算从观察中移除,等待中的模型读取也无法取消该结算。取消模型请求只会结束其结算等待;刷新所有者和其他等待中的请求会独立继续。持续变更、准入拒绝和清理失败仍作为错误处理。

通过 resolveApiKeyForProvider 和 resolveApiKeyForProfile 的凭据查找也接受可选的中止信号。取消会结束调用方对排队准入、配置文件锁或刷新的等待。排队任务会在声明凭据之前重新检查取消状态。已启动的锁获取保留其清理所有者,已声明的刷新保持其独立的持久结算。被取消的调用方无法启动后续的排队刷新或返回其凭据。省略该信号的调用方保留现有等待行为。

工作进程在行进入缓存之前确认已提交的 SQLite 可见性。带有未发布或尾部 WAL 帧的读取会正常返回,而不会被保留。

显式复制流程(例如 openclaw agents add)使用以下可移植性策略:

  • api_key 和 token 配置文件是可移植的,除非设置了 copyToAgents: false。
  • oauth 配置文件默认不可移植,因为刷新令牌可能是一次性的或对轮换敏感的。
  • 提供商拥有的 OAuth 流程只有在跨代理复制刷新材料已知安全时,才可选择 copyToAgents: true;该选择仅在配置文件携带内联的访问/刷新材料时适用。

不可移植的配置文件仍可通过共享的穿透读取基础获得,除非目标代理单独登录并创建自己的本地配置文件。

在 OAuth 刷新期间,当前凭据代数会被替换为惰性持久标记。待处理标记默认保持不合格状态,并且仅由立即将其传递给感知结算的解析器的运行时路径调度。失败的标记是终态的,需要操作者重新认证。

代理本地对等节点永远不会收到复制的已轮换刷新材料。对等节点只有在验证共享凭据属于同一账户之后,才会移除其标记并继承共享凭据。如果无法验证该身份,对等节点将保持终态栅栏隔离状态,而不是继承另一个账户。

插件 SDK OAuth 验证

从 openclaw/plugin-sdk/agent-runtime 导出的 resolveApiKeyForProfile 接受可选的 validateOAuthCredential 回调。解析器会在返回 OAuth 凭据之前以及在持久化或采用已刷新凭据之前调用该回调。当遗留的 provider:default 配置文件回退到替代的 OAuth 配置文件时,该回调同样适用。

从回调中抛出异常会拒绝该凭据。被拒绝的回退不会被返回或刷新,原始所选配置文件的刷新失败仍是面向操作者的错误。拒绝活动中的刷新或结算代数会失败关闭(fail-closed),并可能使该代数及其对等节点处于终态栅栏隔离状态,因此操作者必须重新认证。省略该回调的调用方保留现有的解析和回退行为。

openclaw agent exec 在切换到临时运行状态时保留原始共享存储根。其受限凭据作用域从该共享存储读取可移植的 api_key 和 token 配置文件,而不持久化副本;已配置代理的本地配置文件仍然优先。共享 OAuth 配置文件被排除在此临时作用域之外,即使设置了 copyToAgents: true,因此该运行不会获取另一个刷新所有者。--auth-env-only 完全禁用存储凭据的访问。

显式选择状态目录的 Auth 写入(包括隔离的 QA 预发布环境)会使用该目录的共享存储来进行所有权和 OAuth 去重。其运行时发布和回滚保留同一所有者;另一个进程本地状态根目录不是继承的基础。无关的外部数据库可能更旧、更新或不可读,但不会阻止隔离写入;不过,所选目标中不可读或更新的数据库仍会失败关闭。未显式指定状态目录的写入保留正常的 ambient 状态和 agent 目录配置。

个人模型账户

从 设置 → 个人资料 → 已连接账户 连接的账户在共享状态数据库中拥有身份范围的所有者。其凭据和使用状态绝不会进入共享或 agent 本地 auth 存储、外部 CLI 镜像或全局运行时快照。运行时最多加载由其会话选定的一个个人凭据。未关联的个人账户仍可由现有会话固定使用,但不会为新会话自动选择。

个人固定保留现有的同提供商故障转移策略:在固定账户失败后,可以尝试按顺序排列的共享账户。它们不会将他人的个人账户作为回退。重新连接只能替换连接者本人的凭据;由管理员创建的链接所引用的共享凭据不属于个人财产。参见 个人模型账户。

仅配置的 auth 路由

auth.profiles 中带有 mode: "aws-sdk" 的条目是路由元数据,不是存储的凭据。当目标提供商使用 models.providers.<id>.auth: "aws-sdk" 时,它们是有效的,这也是插件拥有的 Amazon Bedrock 设置所写入的路由。即使凭据存储中不存在匹配条目,这些 profile id 也可能出现在 auth.order 和会话覆盖中。

不要将 type: "aws-sdk" 写入凭据存储;存储的凭据只能是 api_key、token 或 oauth。如果旧版 auth-profiles.json 包含此类标记,openclaw doctor --fix 会将其移动到 auth.profiles,并从存储中移除该标记。

当所选的存储 profile 被移除时,凭据范围模型发现会在查询动态模型元数据之前报告 selected_auth_profile_unavailable。恢复凭据或选择另一个已配置的 profile;注册模型不会修复缺失的身份验证。仅配置的 AWS SDK profile 在没有存储凭据的情况下仍然有效。当显式同提供商选择的凭据消失时,聊天准入和 agent 命令会保留该显式同提供商选择,以便身份验证可以报告恢复。过期的自动选择以及针对不兼容提供商的选择仍会被清除。

OAuth 重新身份验证仅在提供商的账户身份匹配器证明新凭据属于同一账户时,才保留现有 profile id。不同或模糊的账户会保留提供商的新 profile id,因此显式会话固定不会跨越账户边界。不可用的固定项仍保持严格,并发出会话范围警告。对于在重新登录前已被移除的凭据,请使用 model@profile 有意选择一个已配置的账户,或使用 openclaw models auth login --provider <provider> --profile-id <selected-profile-id> 重新连接目标账户。升级期间不会重写任何会话行或存储凭据。

显式 auth 顺序过滤

  • 当为某个提供商设置了 auth.order.<provider> 或 auth 存储顺序覆盖时,models status --probe 仅探测该提供商已解析 auth 顺序中仍保留的 profile id。存储的覆盖优先于 auth.order 配置。
  • 该提供商的存储 profile 如果从显式顺序中省略,之后不会被静默尝试。探测输出会以 reasonCode: excluded_by_auth_order 和详情 Excluded by auth.order for this provider. 报告它。
  • 有效的会话用户固定项是显式的每会话例外:即使该 profile 从提供商顺序中省略,OpenClaw 也会先尝试该 profile,然后使用按顺序排列的同提供商 profile 作为重试候选。冷却期或禁用窗口仅适用于受影响的 profile;它不会抑制其符合条件的同级 profile。

已准备的 agent 请求使用其选定的插件元数据、配置、工作区和环境来确定 auth profile 的资格、顺序以及环境凭据证据。空的选定插件集仍具有权威性;另一个请求的插件别名不能添加 profile 或更改凭据所有者。

模型清单发现

模型发现的存储 profile 选择遵循规范的 auth 顺序和资格规则。仅限于单个模型的冷却期不会抑制账户范围的清单发现。已配置的订阅模式仍附加到直接凭据,成功的 OAuth 准备会将其解析后的当前 token 提供给其清单消费者,而不是捕获存储中的旧 token。

环境支持的 profile 会保留发现环境中可用的值,包括冷命令和工作器路径。当这些材料缺失时,只有所选 profile 的已激活快照可以提供它们;否则发现会在 catalog HTTP 之前报告 unavailable。引用名称绝不会作为凭据发送,也不会被替换为另一个 profile 的凭据。在 Gateway 上,请先恢复 secret,然后运行 openclaw secrets reload,再重试发现。

当所有符合条件的 OAuth 候选项都准备失败时,发现会报告 unavailable,并附带尝试过的 profile 身份,而不是将提供商视为未配置。兼容的先前清单仍可用。可用的回退凭据仍会提供其自身的清单结果。

当清单截止时间到期时,迟到的提供商结果会在最终确定前被丢弃。已启动的 hook 或 OAuth 刷新可能完成,包括持久化轮换后的凭据,但不能发布到已过期的清单运行。

面向 API 密钥和完整身份验证的清单回调保留其现有源优先级。插件必须保持凭据字节及其身份验证模式来自同一选择。清单失败和恢复保留 模型清单契约;它们不会更改消息执行 profile 轮换或会话固定。

探测目标解析

  • 探测目标可来自 auth 配置文件、环境凭据或 models.json(结果 source:profile、env、models.json)。
  • 如果某个提供方拥有凭据,但 OpenClaw 无法为其解析出可探测的模型候选,models status --probe 会报告 status: no_model,并附带 reasonCode: no_model。

外部 CLI 凭据发现

  • 仅当提供方、运行时或 auth 配置文件处于当前操作范围内,或该外部源已存在存储的本地配置文件时,才会发现受支持的外部 CLI 凭据。
  • Auth 存储调用方会显式选择一种外部 CLI 发现模式:none 仅用于持久化/插件 auth,existing 用于刷新已存储的外部 CLI 配置文件,scoped 用于具体的提供方/配置文件集。
  • 只读/状态路径会传递 allowKeychainPrompt: false;它们仅使用基于文件的外部 CLI 凭据,不会读取或复用 macOS Keychain 的结果。
  • /models 会复用已随其目录准备好的外部登录证据,因此这些提供方无需再次 OpenClaw 登录即可保持可见。打开默认菜单不会重复外部 CLI 发现;显式 auth 顺序和路由兼容性仍然适用。

Codex 拥有其原生登录。常规的状态和模型读取不会将其凭据导入 OpenClaw 配置文件。若要保留已配置的、基于 CLI 的 openai:default 配置文件,请使用 openclaw models auth login --provider openai --method device-code 显式导入当前的 Codex 登录。当该 OAuth 配置文件已在 auth.profiles 中声明、源为当前原生 Codex 主目录,且不存在其他受管理的 OpenAI OAuth 配置文件时,导入会保留配置文件 ID 及其现有的模型和会话固定项。已配置的模型和原生凭据文件保持不变。显式隔离的智能体主目录会继续通过其隔离的运行时使用导入的 OpenClaw 配置文件。

自 2026.9.5 起,原生 Codex 登录不再提供仅运行时使用的 openai:default 配置文件。如果该 OAuth 配置文件仍然声明,但未出现在某个智能体的规范凭据存储中,openclaw doctor --fix、Doctor lint 和 Gateway 启动时都会发出包含上述导入命令的警告。该警告不会复制凭据,也不会阻止更新。缺少配置文件的错误只会表明本地存储缺失,而不会报告提供方的 HTTP 401;该错误记录的是本地查找失败,而非提供方拒绝。对于多个智能体,请在登录命令中添加 --agent <id> 以选择受影响的智能体。

新的导入会保留账户作用域内的配置文件 ID。匹配的现有账户和用户会复用其已存储的配置文件。从另一个主目录导入、缺少账户/用户标识,或存在已管理的账户时,不会认领旧版固定项。在这些情况下,请显式使用所报告的导入配置文件。如果在持久化之前检测到源变更和冲突配置文件,则只会停止所选的导入。

OAuth SecretRef 策略守卫

SecretRef 输入仅用于静态凭据。OAuth 凭据在运行时是可变的(刷新流程会持久化轮换后的令牌),因此由 SecretRef 支持的 OAuth 材料会在不同存储之间拆分可变状态。

  • 如果某个配置文件的凭据是 type: "oauth",则对于该配置文件上的任何凭据材料字段,SecretRef 对象都会被拒绝。
  • 如果 auth.profiles.<id>.mode 为 "oauth",则该配置文件的、使用 SecretRef 的 keyRef/tokenRef 输入会被拒绝。
  • 在启动/重新加载的 secret 准备和配置文件解析路径中,违规属于硬失败(抛出错误)。

旧版兼容消息传递

当空的 SQLite auth 存储旁边存在一个已停用的 auth-profiles.json 时,运行时会检查提供方元数据,而不会导入或解析其凭据。AUTH_PROFILE_MIGRATION_REQUIRED 仅阻止这些提供方,包括其 auth 别名;不相关的提供方 auth 仍然可用。无法读取或无法识别的旧版数据会保留所有者范围的拒绝。已有数据的 SQLite 存储会保留仅警告行为。已记录的拒绝会一直保留,直到生命周期显式清除它们;更改或删除旧版文件不会解除这些拒绝。Doctor 会列出受影响的提供方,而 openclaw doctor --fix 会执行受支持的已验证导入和归档。

会话读取器会保留其本地和共享的 auth 存储所有者,并在返回凭据前检查每个所有者的当前拒绝状态。共享提供方的拒绝不会用环境或配置 auth 替换不相关的本地凭据,未解析的本地 SecretRef 仍然按故障关闭(fail closed)处理。只有被识别的凭据条目才能缩小旧版拒绝的范围;仅元数据对象和未知布局仍然保持所有者范围的拒绝。

凭据写入只会对其目标数据库进行所有者范围的迁移就绪检查。共享存储的拒绝不会阻止刷新不相关的智能体本地 OAuth 凭据;但写入目标上的拒绝仍会阻止该刷新。

会话迁移守卫使用与模型发现相同的固定运行时配置,并使用所请求模型的端点来解析依赖端点的提供方别名。准备好的会话视图会保留两个所有者的规范配置文件,并验证它们的 SecretRef;迁移元数据不会过滤这些配置文件。端点感知的请求守卫决定请求是否被允许通过。每个选定的凭据在合并和异步解析期间也会保留其实际来源所有者。该所有者持有的拒绝会继续隔离由另一个进程导入的匹配凭据,直到显式执行生命周期清除/重新加载。其他所有者的凭据保持独立。此来源信息仅在运行时存在,且绝不会存储在 SQLite 中。如果所请求的提供方需要端点来识别其凭据领域,而该上下文缺失,则任何待处理的迁移拒绝都会阻止它。显式配置的不相关端点仍然可用。

为了保持脚本兼容性,探测错误会保持第一行不变:

Auth profile credentials are missing or expired.

人类可读的详细信息和稳定的原因代码会以 ↳ Auth reason [code]: ... 的形式出现在后续行中。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw