Appearance
OpenClaw 的凭证资质判断与解析规则决定了 auth profile 是否可用、如何排序以及模型鉴权是否能通过。本文覆盖 token 凭证的 expires 校验(无效值导致 invalid_expires)、OAuth SecretRef 禁止用法、agent 只读继承机制,以及兼容旧脚本的报错格式。关键验证命令:models status --probe、doctor-auth。
OpenClaw Auth 凭证语义:资质与解析规则
本文定义以下流程共用的凭证资质判断与解析语义:
resolveAuthProfileOrderresolveApiKeyForProfilemodels status --probedoctor-auth
目标是保持选择时(selection-time)与运行时(runtime)的行为一致。
稳定错误码(probe reason codes)
models status --probe 输出的 reasonCode 字段取下列枚举值之一:
| 错误码 | 含义 |
|---|---|
ok | 验证通过 |
excluded_by_auth_order | 被显式 auth order 排除 |
missing_credential | 凭证缺失(token 和 tokenRef 均无) |
invalid_expires | expires 字段格式或值无效 |
expired | 凭证已过期 |
unresolved_ref | tokenRef 或 keyRef 无法解析 |
no_model | 无可用模型用于探测 |
Token 凭证
Token 凭证(type: "token")支持内联 token 字段和/或 tokenRef 引用。
资质判断规则
- 当
token和tokenRef都缺失时,该 profile 标记为 ineligible(不可用)。 expires为可选字段。- 如果
expires存在,它必须是大于0的有限数值。 - 如果
expires无效(NaN、0、负数、非有限值或类型错误),该 profile 不可用,错误码为invalid_expires。 - 如果
expires值指向过去的时刻,该 profile 不可用,错误码为expired。 tokenRef不能绕过expires校验——即使通过引用获取 token,过期时间仍会被检查。
解析规则
- 解析器对
expires的处理与资质判断规则一致。 - 对于可用的 profile,token 实际值可从内联
token或tokenRef解析。 - 无法解析的引用会在
models status --probe输出中显示unresolved_ref。
Agent 只读继承(Agent copy portability)
Agent(智能体)的 auth 继承是透读(read-through) 的。当 agent 没有本地 profile 时,它可以在运行时从默认/主 agent 存储中解析 profile,而无需将密钥材料复制到自己的 auth-profiles.json 中。
显式复制流程(如 openclaw agents add)使用以下便携性策略:
api_key类 profile 默认可复制(除非设置copyToAgents: false)。token类 profile 默认可复制(除非设置copyToAgents: false)。oauth类 profile 默认不可复制,因为 refresh token 可能是一次性的或对轮换敏感。- 由 provider 拥有的 OAuth 流程可以启用
copyToAgents: true,但仅当确认跨 agent 复制 refresh 材料是安全的。
不可复制的 profile 仍可通过透读继承使用,除非目标 agent 独立登录并创建了自己的本地 profile。
纯配置路由(Config-only auth routes)
auth.profiles 中 mode: "aws-sdk" 的条目是路由元数据,而非存储的凭证。它们仅在以下场景有效:
- 目标 provider 在
models.providers.<id>.auth: "aws-sdk"中声明,或 - 使用内置的 Amazon Bedrock 默认 AWS SDK 路由。
这些 profile id 可以出现在 auth.order 和会话覆盖中,即使 auth-profiles.json 中没有对应条目。
不要在 auth-profiles.json 中写 type: "aws-sdk"。如果旧安装遗留了这样的标记,运行 openclaw doctor --fix 会将其移动到 auth.profiles 并从凭证存储中移除该标记。
显式 auth order 过滤
- 当某个 provider 设置了
auth.order.<provider>(或 auth-store 的 order 覆盖),models status --probe只会探测该 provider 已解析的 auth order 中的 profile ids。 - 已存储但被显式 order 排除的 profile 不会在之后被悄悄重试。probe 输出会报告它,携带
reasonCode: excluded_by_auth_order和说明Excluded by auth.order for this provider.
Probe 目标解析
- Probe 目标可以来自 auth profiles、环境变量凭证或
models.json。 - 如果某个 provider 有凭证,但 OpenClaw 无法为其解析出可探测的模型候选,
models status --probe会报告status: no_model并附带reasonCode: no_model。
外部 CLI 凭证发现
- 由外部 CLI 拥有的运行时凭证仅在以下情况被发现:
- 该 provider、运行时或 auth profile 当前操作范围内,或
- 已有针对该外部来源的本地存储 profile。
- Auth-store 调用方应选择显式的外部 CLI 发现模式:
none:仅使用持久化/插件认证;existing:刷新已存储的外部 CLI profile;scoped:针对具体的 provider/profile 集合。
- 只读/状态查询路径会传入
allowKeychainPrompt: false,它们仅使用文件备份的外部 CLI 凭证,不会读取或复用 macOS Keychain 的结果。
OAuth SecretRef 策略防护
- SecretRef 输入仅适用于 静态凭证。
- 如果 profile 凭证是
type: "oauth",则该 profile 的凭证材料不支持 SecretRef 对象。 - 如果
auth.profiles.<id>.mode是"oauth",使用 SecretRef 支持的keyRef/tokenRef输入会被拒绝。 - 违反上述限制会导致启动/重载认证解析路径的硬失败(hard failure)。
兼容旧脚本的报错格式
为保持脚本兼容性,probe 错误的第一行保持不变:
Auth profile credentials are missing or expired.后续行可以添加人性化说明和稳定错误码。
常见问题
models status --probe 报 "excluded_by_auth_order" 是什么原因?
该 profile 在 auth.order.<provider> 或 auth-store 的 order 覆盖中被显式排除。检查 auth.order 配置,确保需要的 profile id 在列表中;被排除的 profile 不会被后续尝试。
token 的 expires 设置成 0 会怎样?
expires 为 0 属于无效值,probe 会报告 invalid_expires。必须设置为大于 0 的有限数值(例如 Unix 时间戳)。如果过期时间已过,报 expired。
OAuth 凭证能否通过 openclaw agents add 复制到 agent?
默认不行。OAuth profile 不可复制(copyToAgents 默认为 false)。项目所有者需确认 refresh token 安全后手动设置 copyToAgents: true;否则 agent 只能通过透读继承使用主存储中的 OAuth 凭证。