← Back to PRs

#10492: fix(auth): store Anthropic setup-token as type:oauth for auto-refresh

by sparck75 open 2026-02-06 15:35 View on GitHub →
commands stale
## Summary The `setup-token` authentication flow only stores Anthropic credentials as `type: "token"` (static, non-refreshable). When the OAuth access token expires (~1 hour), OpenClaw cannot auto-refresh it, causing cascading HTTP 401 failures that put the entire Anthropic provider into cooldown with no automatic recovery path. This PR modifies the setup-token flow to support storing credentials as `type: "oauth"` with refresh tokens, enabling automatic token renewal. ## Problem - Anthropic OAuth access tokens (`sk-ant-oat01-...`) expire after ~1 hour - The `setup-token` flow stores them as `type: "token"` — a static, non-refreshable credential - When the token expires, all Anthropic models become unavailable (cooldown cascade) - No automatic recovery — requires manual re-authentication - In multi-agent setups, expired tokens cause error message loops between agents ## Solution Three-path credential storage in both the onboarding wizard and `models auth` command: 1. **Full JSON credentials** — User pastes `~/.claude/.credentials.json` contents → stored as `type: "oauth"` with access token, refresh token, and expiry. Best path: fully automatic refresh. 2. **Access token + refresh token** — User pastes the access token, then is prompted for an optional refresh token → stored as `type: "oauth"` with 1h default expiry. 3. **Access token only** (fallback) — No refresh token provided → falls back to original `type: "token"` behavior. Fully backward compatible. ## Changes - **`src/commands/auth-token.ts`**: New `validateAnthropicRefreshToken()` and `tryParseClaudeCredentials()` functions. Updated `validateAnthropicSetupToken()` to also accept JSON credential blobs. - **`src/commands/auth-choice.apply.anthropic.ts`**: Onboarding wizard now supports all three credential paths with updated prompts and tips. - **`src/commands/models/auth.ts`**: Runtime `models auth` command with the same three-path logic. - **`src/commands/auth-token.test.ts`**: 22 unit tests covering validation and parsing of refresh tokens, JSON credentials, and setup tokens. ## Test plan - [x] All 22 new unit tests pass (`vitest run src/commands/auth-token.test.ts`) - [x] TypeScript compiles cleanly (zero new errors in `src/`) - [ ] Manual test: paste full `.credentials.json` during onboarding → verify `type: "oauth"` stored - [ ] Manual test: paste access token + refresh token → verify `type: "oauth"` stored - [ ] Manual test: paste access token only → verify `type: "token"` stored (backward compat) - [ ] Verify auto-refresh works after token expiry with `type: "oauth"` credentials ## Related - Fixes #9095 — Anthropic OAuth authentication fails with HTTP 401 invalid bearer token - Related to #9938 — Anthropic OAuth tokens stopped working - Related to #9141 — Configure wizard fails to save Anthropic setup token - Complementary to #5988 — Claude CLI credential sync (addresses the CLI sync side) 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> - Updates Anthropic `setup-token` flows (onboarding + `models auth`) to optionally store refreshable `type: "oauth"` credentials when a refresh token is available. - Adds parsing/validation helpers for refresh tokens and full `~/.claude/.credentials.json` blobs, plus unit tests. - Leaves the original access-token-only path in place by falling back to `type: "token"` storage when no refresh token is provided. <h3>Confidence Score: 3/5</h3> - This PR is close to mergeable, but there is a concrete credential-persistence bug in the new JSON/refresh handling paths. - Core idea and wiring to `type: "oauth"` looks consistent with existing auth-profile refresh logic, and tests cover the helpers. However, both the onboarding wizard and `models auth setup-token` can persist a full JSON blob as a static token if JSON parsing fails and the user skips the refresh-token prompt, which will break authentication for that profile until manually fixed. - src/commands/auth-choice.apply.anthropic.ts, src/commands/models/auth.ts, src/commands/auth-token.ts <!-- greptile_other_comments_section --> <sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub> **Context used:** - Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8)) - Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13)) <!-- /greptile_comment -->

Most Similar PRs