Skip to content

OpenClaw 的凭证资质判断与解析规则决定了 auth profile 是否可用、如何排序以及模型鉴权是否能通过。本文覆盖 token 凭证的 expires 校验(无效值导致 invalid_expires)、OAuth SecretRef 禁止用法、agent 只读继承机制,以及兼容旧脚本的报错格式。关键验证命令:models status --probedoctor-auth

OpenClaw Auth 凭证语义:资质与解析规则

本文定义以下流程共用的凭证资质判断与解析语义:

  • resolveAuthProfileOrder
  • resolveApiKeyForProfile
  • models status --probe
  • doctor-auth

目标是保持选择时(selection-time)与运行时(runtime)的行为一致。

稳定错误码(probe reason codes)

models status --probe 输出的 reasonCode 字段取下列枚举值之一:

错误码含义
ok验证通过
excluded_by_auth_order被显式 auth order 排除
missing_credential凭证缺失(token 和 tokenRef 均无)
invalid_expiresexpires 字段格式或值无效
expired凭证已过期
unresolved_reftokenRef 或 keyRef 无法解析
no_model无可用模型用于探测

Token 凭证

Token 凭证(type: "token")支持内联 token 字段和/或 tokenRef 引用。

资质判断规则

  1. tokentokenRef 都缺失时,该 profile 标记为 ineligible(不可用)。
  2. expires 为可选字段。
  3. 如果 expires 存在,它必须是大于 0 的有限数值。
  4. 如果 expires 无效(NaN0、负数、非有限值或类型错误),该 profile 不可用,错误码为 invalid_expires
  5. 如果 expires 值指向过去的时刻,该 profile 不可用,错误码为 expired
  6. tokenRef 不能绕过 expires 校验——即使通过引用获取 token,过期时间仍会被检查。

解析规则

  1. 解析器对 expires 的处理与资质判断规则一致。
  2. 对于可用的 profile,token 实际值可从内联 tokentokenRef 解析。
  3. 无法解析的引用会在 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.profilesmode: "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 凭证。