OAuth in OpenClaw: Token Exchange, Storage, and Multi-Account Patterns
Learn how OpenClaw handles OAuth for OpenAI Codex and Anthropic Claude CLI, including PKCE token exchange, secure storage, and managing multiple accounts. Essential for developers integrating subscription auth.
Read this when
- You want to understand OpenClaw OAuth end-to-end
- You hit token invalidation / logout issues
- You want Claude CLI or OAuth auth flows
- You want multiple accounts or profile routing
OpenClaw offers OAuth, also referred to as "subscription auth," for providers that support it, especially OpenAI Codex (ChatGPT OAuth) and Anthropic Claude CLI reuse. For Anthropic, the practical distinction is:
- Anthropic API key: standard Anthropic API billing.
- Anthropic Claude CLI / subscription auth inside OpenClaw: Anthropic staff have confirmed this usage is permitted again, so OpenClaw considers Claude CLI reuse and
claude -pusage sanctioned for this integration unless Anthropic changes its policy. For production Anthropic workloads, API key auth remains the more conservative recommendation.
Both OpenAI API-key auth and ChatGPT/Codex OAuth are kept by OpenClaw under the canonical provider id openai. Legacy openai-codex:* profile ids and auth.order.openai-codex entries represent outdated state that openclaw doctor --fix fixes; new configurations should use openai:* profile ids and auth.order.openai.
This page addresses:
- the mechanics of the OAuth token exchange (PKCE)
- the storage location for tokens (and the reasoning)
- managing multiple accounts (via profiles and per-session overrides)
Provider plugins with their own OAuth or API-key flows all enter through the same point:
openclaw models auth login --provider <id>
The token sink (why it exists)
OAuth providers typically issue a fresh refresh token with each login or refresh. Some providers revoke the prior refresh token when a new one is issued for the same user and app. The observable effect: signing in through OpenClaw and through Claude Code or Codex CLI means one of them may unexpectedly lose its session later.
To mitigate this, OpenClaw designates the auth profile store as a token sink:
- the runtime pulls credentials from a single location per agent
- multiple profiles can exist side by side and route predictably
- external CLI reuse depends on the provider: once OpenClaw holds a local OAuth profile for a provider, that local refresh token becomes authoritative. If the local refresh token gets rejected, OpenClaw flags the profile for re-authentication rather than resorting to external CLI token data. Codex CLI bootstrap is even more limited: it can only populate an empty
openai:default-style profile before OpenClaw takes over OAuth for that provider; afterward, OpenClaw-managed refreshes stay authoritative - status and startup paths restrict external CLI discovery to the already-configured provider set, so a single-provider setup never probes an unrelated CLI login store
Storage (where tokens live)
Secrets and auth-routing state reside in each agent's canonical SQLite database:
~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite- Credential rows:
auth_profile_store - Order, last-good, cooldown, and usage rows:
auth_profile_state
Older installations may still carry auth-profiles.json, auth-state.json, per-agent auth.json, or shared credentials/oauth.json. Execute openclaw doctor --fix once after upgrading. Doctor imports validated values, logs a migration receipt, and renames the original file to a timestamped archive.
The runtime never reads these retired files. Whether one still present causes issues depends on whether the SQLite store already serves credentials for that agent:
- The store has profiles: the retired file is just leftover data. The runtime logs a one-time warning naming the file and continues; Doctor archives it on the next
--fix. Doctor never replaces a usable stored credential with imported values, so the file cannot bring back a stale token. - The store is empty: the credentials exist only in that file, so the runtime fails closed for that agent with
AUTH_PROFILE_MIGRATION_REQUIREDinstead of falling back to environment auth. Gateway startup downgrades this owner to configured-unavailable rather than blocking startup.
The database and migration sources honor $OPENCLAW_STATE_DIR. Full reference: /gateway/configuration-reference#auth-storage
For static secret refs and runtime snapshot activation behavior, consult Secrets Management.
When a secondary agent lacks a local auth profile, OpenClaw applies read-through inheritance from the default or main agent store; it does not duplicate the main agent's store during reads. OAuth refresh tokens demand extra care: standard copy flows exclude them by default because some providers rotate or invalidate refresh tokens after use. Set up a separate OAuth login for an agent when it requires an independent account.
Anthropic Claude CLI reuse
OpenClaw treats Anthropic Claude CLI reuse and claude -p as a sanctioned auth path. If a local Claude login already exists on the host, onboarding or configure can use it directly. The Anthropic setup-token remains a supported token-auth option, but OpenClaw prefers Claude CLI reuse when available.
Warning
Anthropic's public Claude Code documentation states that direct Claude Code use remains within Claude subscription limits, and Anthropic staff confirmed that OpenClaw-style Claude CLI usage is allowed again. Consequently, OpenClaw considers Claude CLI reuse and
claude -pusage sanctioned for this integration unless Anthropic releases a new policy.For Anthropic's current direct-Claude-Code plan documentation, see Using Claude Code with your Pro or Max plan and Using Claude Code with your Team or Enterprise plan.
For other subscription-style options in OpenClaw, see OpenAI Codex, Qwen Cloud Coding Plan, MiniMax Coding Plan, and Z.AI / GLM Coding Plan.
OAuth exchange (how login works)
OpenClaw's interactive login flows live in openclaw/plugin-sdk/llm.ts and are connected to the wizards and commands.
Anthropic setup-token
Flow shape:
- generate the token by running
claude setup-tokenon any machine with Claude Code, then start Anthropic setup-token or paste-token from OpenClaw - OpenClaw saves the resulting Anthropic credential into an auth profile
- model selection remains on
anthropic/... - existing Anthropic auth profiles stay available for rollback or order control
OpenAI Codex (ChatGPT OAuth)
OpenAI Codex OAuth is explicitly supported for use outside the Codex CLI, including OpenClaw workflows.
The login command uses the canonical OpenAI provider id:
openclaw models auth login --provider openai
Use --profile-id openai:<name> for multiple ChatGPT/Codex OAuth accounts in one agent. Avoid openai-codex:<name> for new profiles. Doctor migrates that older prefix to a collision-free openai:* profile id; run openclaw models auth list --provider openai after repair before copying profile ids into auth.order or /model ...@<profileId>.
Flow shape (PKCE):
- generate a PKCE verifier and challenge plus a random
state - open
https://auth.openai.com/oauth/authorize?...(scopeopenid profile email offline_access) - attempt to capture the callback on
http://localhost:1455/auth/callback(the callback host defaults tolocalhostand accepts only loopback hosts; override withOPENCLAW_OAUTH_CALLBACK_HOST) - if a code can be pasted before the callback arrives (or you are remote or headless and the callback cannot bind), paste the redirect URL or code instead: manual paste races the browser callback, and whichever completes first wins
- exchange the code at
https://auth.openai.com/oauth/token - extract
accountIdfrom the access token and store{ access, refresh, expires, accountId }
Wizard path is openclaw onboard → auth choice openai.
Refresh + expiry
Profiles store an expires timestamp. At runtime:
- When
expireslies ahead, rely on the saved access token - Once it has expired, refresh under a file lock and replace the stored credentials
- Should a secondary agent access an inherited main-agent OAuth profile, the refresh updates the main agent store rather than duplicating the refresh token into the secondary agent store
- Externally managed CLI credentials (Claude CLI, narrow Codex CLI bootstrap; see The token sink) get re-read instead of consuming a copied refresh token. If a managed refresh fails, OpenClaw flags the affected profile for re-authentication rather than exposing external CLI token data.
The refresh process runs automatically, so manual token management is rarely necessary.
Multiple accounts (profiles) + routing
Two approaches exist:
1) Preferred: separate agents
To keep "personal" and "work" completely separate, choose isolated agents (distinct sessions, credentials, and workspaces):
openclaw agents add work
openclaw agents add personal
After that, set up auth per agent via the wizard and direct chats to the appropriate agent.
2) Advanced: multiple profiles in one agent
The auth profile store can hold multiple profile IDs for one provider. Select which one applies:
- globally through config ordering (
auth.order) - per-session using
/model ...@<profileId> -s
Example (session override):
/model Opus@anthropic:work -s
Show all profile IDs with:
openclaw models auth list --provider <id>
Additional resources:
- Model failover (rotation and cooldown rules)
- Slash commands (command surface)
Related
- Authentication - model provider auth overview
- Secrets - credential storage and SecretRef
- Configuration Reference - auth config keys