OAuth Providers Tab
Adds a polished OAuth settings tab to the OpenClaw Control UI.
What It Installs
| File | Purpose |
|---|
| INLINECODE0 | Lit HTML view — provider cards, mode tabs, OAuth spinner, manual-paste field |
| INLINECODE1 |
State management, RPC calls, provider catalogue |
|
src/gateway/server-methods/auth-login.ts | Gateway RPC handlers for all auth flows |
Plus wiring changes in:
- -
ui/src/ui/app.ts — 6 @state() properties - INLINECODE5 — render block for INLINECODE6
- INLINECODE7 — tab load trigger
- INLINECODE8 —
Tab type, TAB_PATHS, INLINECODE11 - INLINECODE12 — register INLINECODE13
- INLINECODE14 —
BUILTIN_UI_VIEWS entry - INLINECODE16 —
"ai-providers" label ("OAuth") and subtitle
Auth Flows
OpenAI — Codex PKCE OAuth
- - Button opens the system browser via INLINECODE19
- Callback captured on INLINECODE20
- Calls
loginOpenAICodex() from INLINECODE22 - Credentials written by
writeOAuthCredentials() + INLINECODE24 - WSL2 manual-paste fallback: On WSL2,
127.0.0.1:1455 is unreachable from Windows. The UI shows a paste field where the user can paste the full redirect URL (http://localhost:1455/auth/callback?code=...&state=...). The gateway RPC auth.login.openai-codex.submit-code resolves a deferred promise that races with the local callback server via onManualCodeInput. - Session state:
aiProvidersOauthSessionId set by startOpenAICodexOAuth → used by aiProvidersSubmitCode to call the RPC
Anthropic — Subscription Token (setup-token)
- - User runs
claude setup-token in terminal to generate a sk-ant-oat01-... token - Pastes token into UI
- Validated by
validateAnthropicSetupToken(), stored via buildTokenProfileId() + INLINECODE36 - Auto-detect button: Reads existing
accessToken from ~/.claude/.credentials.json (under claudeAiOauth) and stores it via auth.login.anthropic-auto RPC - ⚠️ Important: Anthropic has blocked some subscription usage outside Claude Code. The docs warn: "This credential is only authorized for use with Claude Code." Setup-token support is "technical compatibility only" with policy risk. If you get a "not authorized" error, an API key is required.
API Keys (all providers)
- - Encrypted to
~/.openclaw/secrets.json via existing secrets.write RPC - Env vars:
ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_API_KEY, INLINECODE46
Gateway RPCs
| Method | Description |
|---|
| INLINECODE47 | List all configured auth profiles |
| INLINECODE48 |
Validate + store Anthropic setup-token |
|
auth.login.anthropic-auto | Auto-detect token from
~/.claude/.credentials.json |
|
auth.login.openai-codex | Run PKCE OAuth (opens browser) |
|
auth.login.openai-codex.submit-code | Manual paste of redirect URL (WSL2 fallback) |
|
auth.login.remove | Remove a profile by
profileId |
Auth Badge System
The chat UI displays a badge next to assistant messages indicating which auth method was used.
Badge Rendering (grouped-render.ts)
| profileId pattern | Badge | CSS class |
|---|
| INLINECODE56 | OAuth (green) | INLINECODE57 |
Contains :manual or claude-cli or starts with INLINECODE60 |
OAuth (green) |
auth-badge--oauth |
| Starts with
anthropic: (catch-all) |
API (blue) |
auth-badge--api |
| Starts with
openai: |
Fallback |
auth-badge--fallback |
| Everything else |
API |
auth-badge--fallback |
The badge is determined by group.authProfileId in the message group. If the wrong profile is active, the wrong badge appears.
See references/auth-badge.ts.excerpt for the full function.
Auth Profile Order — Architecture & Troubleshooting
How Profile Selection Works
The gateway selects which auth profile to use via resolveAuthProfileOrder() in src/agents/auth-profiles/order.ts:
CODEBLOCK0
Critical: auth-profiles.json order ALWAYS wins over openclaw.json order. If auth-profiles.json has a stale order array, the correct order in openclaw.json will never be consulted.
See references/auth-order.ts.excerpt for the key code.
Common Issue: Stale Order / Ghost Profiles
Symptom: Badge shows "API" or "Fallback" even though the subscription token is configured correctly.
Cause: auth-profiles.json has an order array referencing non-existent profiles (e.g. anthropic:manual from an old setup). The existing profile (like anthropic:default) gets selected instead of the subscription token profile.
Diagnosis:
CODEBLOCK1
Fix:
CODEBLOCK2
Why Option 1 is preferred: The CLI writes to auth-profiles.json, but gateway restarts or other processes can overwrite it. Removing the stored order lets openclaw.json (which is the canonical config) be the authority.
Repair Logic
INLINECODE81 has a repair path (lines 96-100): if ALL profiles in the base order are missing from the store, it scans all stored profiles for the provider. But this only triggers when EVERY profile is missing — if even one exists (like anthropic:default), the repair doesn't kick in.
Config Verification
Ensure openclaw.json has the correct auth section:
CODEBLOCK3
The mode field in openclaw.json profiles is checked against the type field in auth-profiles.json credentials. A mode: "oauth" config is compatible with both type: "oauth" and type: "token" credentials (special-cased in resolveAuthProfileEligibility).
Installation Steps
- 1. Copy
references/view.ts → INLINECODE93 - Copy
references/controller.ts → INLINECODE95 - Copy
references/auth-login.ts → INLINECODE97 - Wire into the UI (see wiring changes above — follow patterns from other tabs like
apikeys) - Register
authLoginHandlers in INLINECODE100 - INLINECODE101 — zero new TS errors expected
- Restart gateway: INLINECODE102
- Open Settings → OAuth in the Control UI
Provider Catalogue
Defined in PROVIDER_CATALOGUE in references/controller.ts. To add a provider:
CODEBLOCK4
Known Gotchas
- 1. Auth order precedence:
auth-profiles.json order beats openclaw.json. If badge shows wrong auth mode, check for stale order in auth-profiles.json first. - Gateway restart overwrites: Manual edits to
auth-profiles.json can be overwritten by gateway processes. Prefer editing openclaw.json for persistent config. - WSL2 loopback isolation: The OpenAI Codex OAuth callback server binds to
127.0.0.1:1455 (hardcoded in @mariozechner/pi-ai). Windows browsers can't reach WSL2 localhost. Use the manual-paste field. claude setup-token requires interactive TTY: Uses Ink/raw mode — cannot be run non-interactively. The auto-detect button reads ~/.claude/.credentials.json as a workaround.- Anthropic policy risk:
sk-ant-oat01-* tokens may be blocked outside Claude Code. If API calls return authorization errors, switch to an API key. lastGood persistence: The lastGood field in auth-profiles.json can cause the gateway to skip the configured order and jump straight to a previously-working profile. Remove it along with order when troubleshooting.
Source Files
Changelog
v1.1.0
- - Added WSL2 manual-paste fallback for OpenAI Codex OAuth (
onManualCodeInput + auth.login.openai-codex.submit-code RPC) - Added Anthropic auto-detect button (
auth.login.anthropic-auto RPC) — reads from INLINECODE121 - Added auth badge rendering reference (
renderAuthBadge() from grouped-render.ts) - Added auth profile order architecture documentation with troubleshooting guide
- Added stale order/ghost profile diagnosis and fix procedures
- Documented
resolveAuthProfileOrder() precedence: stored order > config order > explicit profiles > store profiles - Added known gotchas section covering order precedence, gateway overwrites, WSL2 loopback, TTY requirements, and Anthropic policy risk
v1.0.0
- - Initial release with Anthropic setup-token, OpenAI Codex PKCE OAuth, and API key flows
OAuth 提供商选项卡
为 OpenClaw 控制界面添加了一个精美的 OAuth 设置选项卡。
安装内容
| 文件 | 用途 |
|---|
| ui/src/ui/views/ai-providers.ts | Lit HTML 视图 — 提供商卡片、模式选项卡、OAuth 加载动画、手动粘贴字段 |
| ui/src/ui/controllers/ai-providers.ts |
状态管理、RPC 调用、提供商目录 |
| src/gateway/server-methods/auth-login.ts | 所有认证流程的网关 RPC 处理器 |
以及以下文件的接线变更:
- - ui/src/ui/app.ts — 6 个 @state() 属性
- ui/src/ui/app-render.ts — state.tab === ai-providers 的渲染块
- ui/src/ui/app-settings.ts — 选项卡加载触发器
- ui/src/ui/navigation.ts — Tab 类型、TABPATHS、iconForTab
- src/gateway/server-methods.ts — 注册 authLoginHandlers
- src/gateway/server-methods/plugins-ui.ts — BUILTINUI_VIEWS 条目
- ui/src/i18n/locales/en.ts — ai-providers 标签(OAuth)和副标题
认证流程
OpenAI — Codex PKCE OAuth
- - 按钮通过 openUrl() 打开系统浏览器
- 回调在 localhost:1455/auth/callback 上捕获
- 调用 @mariozechner/pi-ai 中的 loginOpenAICodex()
- 凭据由 writeOAuthCredentials() + applyAuthProfileConfig() 写入
- WSL2 手动粘贴回退:在 WSL2 上,Windows 无法访问 127.0.0.1:1455。界面显示一个粘贴字段,用户可以在其中粘贴完整的重定向 URL(http://localhost:1455/auth/callback?code=...&state=...)。网关 RPC auth.login.openai-codex.submit-code 解析一个延迟的 Promise,该 Promise 通过 onManualCodeInput 与本地回调服务器竞争。
- 会话状态:aiProvidersOauthSessionId 由 startOpenAICodexOAuth 设置 → 由 aiProvidersSubmitCode 用于调用 RPC
Anthropic — 订阅令牌(setup-token)
- - 用户在终端中运行 claude setup-token 生成 sk-ant-oat01-... 令牌
- 将令牌粘贴到界面中
- 由 validateAnthropicSetupToken() 验证,通过 buildTokenProfileId() + upsertAuthProfile() 存储
- 自动检测按钮:从 ~/.claude/.credentials.json(在 claudeAiOauth 下)读取现有的 accessToken,并通过 auth.login.anthropic-auto RPC 存储
- ⚠️ 重要提示:Anthropic 已阻止某些在 Claude Code 之外的订阅使用。文档警告:此凭据仅授权用于 Claude Code。 设置令牌支持仅为技术兼容性,存在政策风险。如果收到未授权错误,则需要 API 密钥。
API 密钥(所有提供商)
- - 通过现有的 secrets.write RPC 加密到 ~/.openclaw/secrets.json
- 环境变量:ANTHROPICAPIKEY、OPENAIAPIKEY、GOOGLEAPIKEY、OPENROUTERAPIKEY
网关 RPC
| 方法 | 描述 |
|---|
| auth.login.status | 列出所有已配置的认证配置文件 |
| auth.login.anthropic-token |
验证并存储 Anthropic 设置令牌 |
| auth.login.anthropic-auto | 从 ~/.claude/.credentials.json 自动检测令牌 |
| auth.login.openai-codex | 运行 PKCE OAuth(打开浏览器) |
| auth.login.openai-codex.submit-code | 手动粘贴重定向 URL(WSL2 回退) |
| auth.login.remove | 按 profileId 删除配置文件 |
认证徽章系统
聊天界面在助手消息旁边显示一个徽章,指示使用了哪种认证方法。
徽章渲染(grouped-render.ts)
| profileId 模式 | 徽章 | CSS 类 |
|---|
| mode:oauth | OAuth(绿色) | auth-badge--oauth |
| 包含 :manual 或 claude-cli 或以 anthropic:oat 开头 |
OAuth(绿色) | auth-badge--oauth |
| 以 anthropic: 开头(全捕获) |
API(蓝色) | auth-badge--api |
| 以 openai: 开头 |
回退 | auth-badge--fallback |
| 其他所有情况 |
API | auth-badge--fallback |
徽章由消息组中的 group.authProfileId 决定。如果激活了错误的配置文件,则会显示错误的徽章。
完整函数请参见 references/auth-badge.ts.excerpt。
认证配置文件顺序 — 架构与故障排除
配置文件选择的工作原理
网关通过 src/agents/auth-profiles/order.ts 中的 resolveAuthProfileOrder() 选择要使用的认证配置文件:
storedOrder (auth-profiles.json) → 优先
configuredOrder (openclaw.json) → 无存储顺序时的回退
explicitProfiles (配置键) → 无显式顺序时的回退
storeProfiles (存储中的所有) → 最后手段
关键:auth-profiles.json 的顺序始终优先于 openclaw.json 的顺序。如果 auth-profiles.json 有陈旧的 order 数组,则永远不会考虑 openclaw.json 中的正确顺序。
关键代码请参见 references/auth-order.ts.excerpt。
常见问题:陈旧顺序/幽灵配置文件
症状:即使订阅令牌配置正确,徽章仍显示API或回退。
原因:auth-profiles.json 的 order 数组引用了不存在的配置文件(例如来自旧设置的 anthropic:manual)。现有的配置文件(如 anthropic:default)被选中,而不是订阅令牌配置文件。
诊断:
bash
检查当前认证状态
openclaw models status
检查 auth-profiles.json 实际内容
python3 -c
import json
with open($HOME/.openclaw/agents/main/agent/auth-profiles.json) as f:
d = json.load(f)
print(order:, d.get(order))
print(lastGood:, d.get(lastGood))
print(profiles:, list(d[profiles].keys()))
修复:
bash
选项 1:删除陈旧顺序,使 openclaw.json 成为权威
python3 -c
import json
path = $HOME/.openclaw/agents/main/agent/auth-profiles.json
with open(path) as f: d = json.load(f)
d.pop(order, None)
d.pop(lastGood, None)
with open(path, w) as f: json.dump(d, f, indent=2)
print(已删除陈旧顺序)
选项 2:通过 CLI 设置顺序(写入 auth-profiles.json)
openclaw models auth order set --provider anthropic anthropic:claude-cli anthropic:default
然后重启网关
(sleep 3 && systemctl --user restart openclaw-gateway) &
为什么选项 1 更优:CLI 写入 auth-profiles.json,但网关重启或其他进程可能会覆盖它。删除存储的顺序可以让 openclaw.json(即规范配置)成为权威。
修复逻辑
resolveAuthProfileOrder() 有一个修复路径(第 96-100 行):如果基础顺序中的所有配置文件在存储中都缺失,它会扫描存储中该提供商的所有配置文件。但这仅在每个配置文件都缺失时触发——如果即使有一个存在(如 anthropic:default),修复也不会启动。
配置验证
确保 openclaw.json 具有正确的认证部分:
json
{
auth: {
profiles: {
anthropic:claude-cli: { provider: anthropic, mode: oauth },
anthropic:default: { provider: anthropic, mode: api_key }
},
order: {
anthropic: [anthropic:claude-cli, anthropic:default]
}
}
}
openclaw.json 配置文件中的 mode 字段会与