openclaw/docs/concepts/oauth.md

7.0 KiB
Raw Blame History

summary read_when title
OAuth in OpenClaw: token exchange, storage, and multi-account patterns
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
OAuth

OAuth

OpenClaw supports “subscription auth” via OAuth for providers that offer it (notably OpenAI Codex (ChatGPT OAuth)). For Anthropic, the practical split is now:

  • Anthropic API key: normal Anthropic API billing
  • Anthropic subscription auth inside OpenClaw: Anthropic notified OpenClaw users on April 4, 2026 at 12:00 PM PT / 8:00 PM BST that this now requires Extra Usage

OpenAI Codex OAuth is explicitly supported for use in external tools like OpenClaw. This page explains:

For Anthropic in production, API key auth is the safer recommended path.

  • how the OAuth token exchange works (PKCE)
  • where tokens are stored (and why)
  • how to handle multiple accounts (profiles + per-session overrides)

OpenClaw also supports provider plugins that ship their own OAuth or APIkey flows. Run them via:

openclaw models auth login --provider <id>

The token sink (why it exists)

OAuth providers commonly mint a new refresh token during login/refresh flows. Some providers (or OAuth clients) can invalidate older refresh tokens when a new one is issued for the same user/app.

Practical symptom:

  • you log in via OpenClaw and via Claude Code / Codex CLI → one of them randomly gets “logged out” later

To reduce that, OpenClaw treats auth-profiles.json as a token sink:

  • the runtime reads credentials from one place
  • we can keep multiple profiles and route them deterministically
  • when credentials are reused from an external CLI like Codex CLI, OpenClaw mirrors them with provenance and re-reads that external source instead of rotating the refresh token itself

Storage (where tokens live)

Secrets are stored per-agent:

  • Auth profiles (OAuth + API keys + optional value-level refs): ~/.openclaw/agents/<agentId>/agent/auth-profiles.json
  • Legacy compatibility file: ~/.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 auth-profiles.json on first use)

All of the above also respect $OPENCLAW_STATE_DIR (state dir override). Full reference: /gateway/configuration

For static secret refs and runtime snapshot activation behavior, see Secrets Management.

Anthropic legacy token compatibility

Anthropic's public Claude Code docs say direct Claude Code use stays within Claude subscription limits. Separately, Anthropic told OpenClaw users on **April 4, 2026 at 12:00 PM PT / 8:00 PM BST** that **OpenClaw counts as a third-party harness**. Existing Anthropic token profiles remain technically usable in OpenClaw, but Anthropic says the OpenClaw path now requires **Extra Usage** (pay-as-you-go billed separately from the subscription) for that traffic.

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.

OpenClaw now exposes Anthropic setup-token again as a legacy/manual path. Anthropic's OpenClaw-specific billing notice still applies to that path, so use it with the expectation that Anthropic requires Extra Usage for OpenClaw-driven Claude-login traffic.

Anthropic Claude CLI migration

Anthropic no longer has a supported local Claude CLI migration path in OpenClaw. Use Anthropic API keys for Anthropic traffic, or keep legacy token-based auth only where it is already configured and with the expectation that Anthropic treats that OpenClaw path as Extra Usage.

OAuth exchange (how login works)

OpenClaws interactive login flows are implemented in @mariozechner/pi-ai and wired into the wizards/commands.

Anthropic setup-token

Flow shape:

  1. start Anthropic setup-token or paste-token from OpenClaw
  2. OpenClaw stores the resulting Anthropic credential in an auth profile
  3. model selection stays on anthropic/...
  4. existing Anthropic auth profiles remain available for rollback/order control

OpenAI Codex (ChatGPT OAuth)

OpenAI Codex OAuth is explicitly supported for use outside the Codex CLI, including OpenClaw workflows.

Flow shape (PKCE):

  1. generate PKCE verifier/challenge + random state
  2. open https://auth.openai.com/oauth/authorize?...
  3. try to capture callback on http://127.0.0.1:1455/auth/callback
  4. if callback cant bind (or youre remote/headless), paste the redirect URL/code
  5. exchange at https://auth.openai.com/oauth/token
  6. extract accountId from the access token and store { access, refresh, expires, accountId }

Wizard path is openclaw onboard → auth choice openai-codex.

Refresh + expiry

Profiles store an expires timestamp.

At runtime:

  • if expires is in the future → use the stored access token
  • if expired → refresh (under a file lock) and overwrite the stored credentials
  • exception: reused external CLI credentials stay externally managed; OpenClaw re-reads the CLI auth store and never spends the copied refresh token itself

The refresh flow is automatic; you generally don't need to manage tokens manually.

Multiple accounts (profiles) + routing

Two patterns:

1) Preferred: separate agents

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.

2) Advanced: multiple profiles in one agent

auth-profiles.json supports multiple profile IDs for the same provider.

Pick which profile is used:

  • globally via config ordering (auth.order)
  • per-session via /model ...@<profileId>

Example (session override):

  • /model Opus@anthropic:work

How to see what profile IDs exist:

  • openclaw channels list --json (shows auth[])

Related docs: