Genesis 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 Claude CLI / subscription auth inside Genesis: Anthropic staff told us this usage is allowed again
OpenAI Codex OAuth is explicitly supported for use in external tools like Genesis. 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)
Genesis also supports provider plugins that ship their own OAuth or API‑key flows. Run them via:
genesis 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 Genesis and via Claude Code / Codex CLI → one of them randomly gets “logged out” later
To reduce that, Genesis treats auth-profiles.json as a token sink:
- the runtime reads credentials from one place
- we can keep multiple profiles and route them deterministically
- external CLI reuse is provider-specific: Codex CLI can bootstrap an empty
openai-codex:defaultprofile, but once Genesis has a local OAuth profile, the local refresh token is canonical; other integrations can remain externally managed and re-read their CLI auth store
Storage (where tokens live)
Secrets are stored per-agent:
- Auth profiles (OAuth + API keys + optional value-level refs):
~/.genesis/agents/<agentId>/agent/auth-profiles.json - Legacy compatibility file:
~/.genesis/agents/<agentId>/agent/auth.json(staticapi_keyentries are scrubbed when discovered)
Legacy import-only file (still supported, but not the main store):
~/.genesis/credentials/oauth.json(imported intoauth-profiles.jsonon first use)
All of the above also respect $GENESIS_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
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 Genesis, see OpenAI Codex, Qwen Cloud Coding Plan, MiniMax Coding Plan, and Z.AI / GLM Coding Plan.
Genesis also exposes Anthropic setup-token as a supported token-auth path, but it now prefers Claude CLI reuse and claude -p when available.
Anthropic Claude CLI migration
Genesis supports Anthropic Claude CLI reuse again. If you already have a local Claude login on the host, onboarding/configure can reuse it directly.
OAuth exchange (how login works)
Genesis’s interactive login flows are implemented in @earendil-works/pi-ai and wired into the wizards/commands.
Anthropic setup-token
Flow shape:
- start Anthropic setup-token or paste-token from Genesis
- Genesis stores the resulting Anthropic credential in an auth profile
- model selection stays on
anthropic/... - 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 Genesis workflows.
Flow shape (PKCE):
- generate PKCE verifier/challenge + random
state - open
https://auth.openai.com/oauth/authorize?... - try to capture callback on
http://127.0.0.1:1455/auth/callback - if callback can’t bind (or you’re remote/headless), paste the redirect URL/code
- exchange at
https://auth.openai.com/oauth/token - extract
accountIdfrom the access token and store{ access, refresh, expires, accountId }
Wizard path is genesis onboard → auth choice openai-codex.
Refresh + expiry
Profiles store an expires timestamp.
At runtime:
- if
expiresis in the future → use the stored access token - if expired → refresh (under a file lock) and overwrite the stored credentials
- exception: some external CLI credentials stay externally managed; Genesis
re-reads those CLI auth stores instead of spending copied refresh tokens.
Codex CLI bootstrap is intentionally narrower: it seeds an empty
openai-codex:defaultprofile, then Genesis-owned refreshes keep the local profile canonical.
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):
genesis agents add work
genesis 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> - via
priority(see Rotation order)
Each profile can carry a human-readable displayName and a numeric priority
that controls the rotation order. Both fields can be set on either the
secret-side credential or the config-side auth.profiles.<id> entry; secret
side wins when both are set.
Example (per-profile name and priority via the secret side):
// auth-profiles.json
{
profiles: {
"anthropic:work": {
type: "oauth",
provider: "anthropic",
access: "...",
refresh: "...",
expires: 0,
displayName: "Work",
priority: 100,
},
"anthropic:personal": {
type: "oauth",
provider: "anthropic",
access: "...",
refresh: "...",
expires: 0,
displayName: "Personal",
},
},
}
Example (config side only — useful for shaping rotation from genesis.json without rewriting secrets):
// genesis.json
{
auth: {
profiles: {
"anthropic:work": {
provider: "anthropic",
mode: "oauth",
displayName: "Work",
priority: 100,
},
"anthropic:personal": { provider: "anthropic", mode: "oauth", displayName: "Personal" },
},
},
}
Add or edit via CLI:
# New profile with name + priority (paste-token / setup-token / login all accept these)
genesis models auth paste-token --provider anthropic --profile-id anthropic:work --name "Work" --priority 100 --expires-in 365d
# Rename / set priority / remove after the fact
genesis models auth rename --profile-id anthropic:work --name "Work"
genesis models auth set-priority --profile-id anthropic:work --priority 100
genesis models auth remove --profile-id anthropic:work
Example (session override):
/model Opus@anthropic:work
How to see what profile IDs exist:
genesis channels list --json(showsauth[])
Related docs:
- Model failover (rotation + cooldown rules)
- Slash commands (command surface)
Related
- Authentication — model provider auth overview
- Secrets — credential storage and SecretRef
- Configuration Reference — auth config keys