docs/concepts/oauth.md
OpenClaw supports OAuth ("subscription auth") for providers that offer it, notably OpenAI Codex (ChatGPT OAuth) and Anthropic Claude CLI reuse. For Anthropic, the practical split is:
claude -p usage as sanctioned for this integration unless Anthropic
publishes a new policy. For Anthropic in production, API key auth is still
the safer recommended path.OpenClaw stores both OpenAI API-key auth and ChatGPT/Codex OAuth under the
canonical provider id openai. Older openai-codex:* profile ids and
auth.order.openai-codex entries are legacy state repaired by
openclaw doctor --fix; use openai:* profile ids and auth.order.openai for
new config.
This page covers:
Provider plugins that ship their own OAuth or API-key flow run through the same entry point:
openclaw models auth login --provider <id>
OAuth providers commonly mint a new refresh token on every login/refresh. Some providers invalidate the previous refresh token when a new one is issued for the same user/app. Practical symptom: log in via OpenClaw and via Claude Code / Codex CLI, and one of them randomly gets logged out later.
To reduce that, OpenClaw treats the auth profile store as a token sink:
openai:default-style profile before OpenClaw owns OAuth for that
provider; after that, OpenClaw-owned refreshes stay canonicalSecrets live per agent, keyed by the logical name auth-profiles.json (the
underlying store is the agent's SQLite database; the JSON name is kept for
compatibility and tooling display):
~/.openclaw/agents/<agentId>/agent/auth-profiles.json~/.openclaw/agents/<agentId>/agent/auth.json
(static api_key entries are scrubbed when discovered)Legacy import-only file (still supported, but not the main store):
~/.openclaw/credentials/oauth.json (imported into the auth profile store on first use)All of the above also respect $OPENCLAW_STATE_DIR (state dir override). Full reference: /gateway/configuration-reference#auth-storage
For static secret refs and runtime snapshot activation behavior, see Secrets Management.
When a secondary agent has no local auth profile, OpenClaw uses read-through inheritance from the default/main agent store; it does not clone the main agent's store on read. OAuth refresh tokens are especially sensitive: normal copy flows skip them by default because some providers rotate or invalidate refresh tokens after use. Configure a separate OAuth login for an agent when it needs an independent account.
OpenClaw supports Anthropic Claude CLI reuse and claude -p as a sanctioned
auth path. If you already have a local Claude login on the host,
onboarding/configure can reuse it directly. Anthropic setup-token remains
available as a supported token-auth path, but OpenClaw prefers Claude CLI
reuse when it is available.
For Anthropic's current direct-Claude-Code plan docs, see Using Claude Code with your Pro or Max plan and Using Claude Code with your Team or Enterprise plan.
If you want other subscription-style options in OpenClaw, see OpenAI Codex, Qwen Cloud Coding Plan, MiniMax Coding Plan, and Z.AI / GLM Coding Plan. </Warning>
OpenClaw's interactive login flows are implemented in openclaw/plugin-sdk/llm.ts and wired into the wizards/commands.
Flow shape:
anthropic/...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. Do not use 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):
statehttps://auth.openai.com/oauth/authorize?... (scope
openid profile email offline_access)http://localhost:1455/auth/callback (the
callback host defaults to localhost and only accepts loopback hosts;
override with OPENCLAW_OAUTH_CALLBACK_HOST)https://auth.openai.com/oauth/tokenaccountId from the access token and store { access, refresh, expires, accountId }Wizard path is openclaw onboard → auth choice openai.
Profiles store an expires timestamp. At runtime:
expires is in the future, use the stored access tokenThe refresh flow is automatic; you generally do not need to manage tokens manually.
Two patterns:
If you want "personal" and "work" to never interact, use isolated agents (separate sessions + credentials + workspace):
openclaw agents add work
openclaw agents add personal
Then configure auth per-agent (wizard) and route chats to the right agent.
The auth profile store supports multiple profile IDs for the same provider. Pick which one is used:
auth.order)/model ...@<profileId>Example (session override):
/model Opus@anthropic:workList existing profile IDs with:
openclaw models auth list --provider <id>
Related docs: