Authentication and models
Rho supports several providers with different auth modes. This page covers the concepts shared across all of them. For provider-specific login, logout, environment overrides, and model selection, see the provider index or the individual provider pages.
Provider, model, and auth mode are stored in configuration. Secrets are never stored in config.
Providers
Rho's implemented providers are:
| Provider | Auth mode | Details |
|---|---|---|
openai | api-key | OpenAI |
openai-codex | codex | OpenAI (Codex OAuth) |
anthropic | anthropic-api-key | Anthropic |
google | google-api-key | Google Gemini |
github-copilot | github-copilot | GitHub Copilot |
xai | xai-api-key, xai-oauth | xAI |
poolside | poolside-api-key | Poolside |
openrouter | openrouter-api-key, openrouter-oauth | OpenRouter |
ollama | none, optional ollama-api-key | Ollama |
ollama-cloud | ollama-cloud-api-key, ollama-cloud-device | Ollama Cloud |
moonshot | moonshot-api-key | Moonshot and Kimi Code |
kimi-code | kimi-oauth | Moonshot and Kimi Code |
qwen-token-plan | qwen-token-plan-api-key | Qwen Token Plan |
meta | meta-api-key | Meta Model API |
minimax | minimax-api-key | MiniMax |
opencode-go | opencode-go-api-key | OpenCode Go |
User-defined OpenAI-compatible hosts use [providers.custom.<name>] with auth = "none" or {name}-api-key. They speak Chat Completions by default, or Responses when api = "responses". Create one from /login by choosing Custom · Chat Completions or Custom · Responses, or add the table in config. See Custom OpenAI-compatible hosts.
Most providers expose a refreshable API model list after authentication. /login ollama stores the local API base and an optional key. Custom hosts can run without a key. OpenAI Codex OAuth and xAI OAuth use static allowlists maintained by Rho, so Refresh model lists does not fetch them.
First run
The first launch on a fresh machine opens a full-screen setup instead of a session. There is no history to read and no model you chose yet, so the composer, hints, and statusline stay out of the way until you have both:
rho v1.26.0
Welcome. Two steps and you are ready to work.
▸ Sign in to a provider
Choose a model
>
→ Anthropic
GitHub Copilot
...
Esc to skip setupEach step drives the same picker the matching command opens, so sign-in behaves exactly as /login does, including method pickers, the credential-store question, and OAuth. Choosing a model ends setup and hands off to a normal session.
Setup opens at whichever step can do something. A launch whose available credentials, stored or from the environment, already list models starts at the model step rather than asking for a login that is done; a launch with no models to offer starts at sign-in. Esc leaves setup at any point.
Signed-out sessions
Outside setup, the session shows whether the active provider resolved to usable credentials.
- No usable credentials. The header hints lead with
/login, in accent rather than dim. The statusline replaces the provider and model withnot signed in · /login, so the state stays on screen no matter how far the transcript scrolls. - A prompt sent while signed out opens the login picker instead of failing a turn. Your text stays in the composer; press enter once a provider is live to send it.
Login and provider switching
/login opens a readable provider picker. Providers with multiple authentication methods open a second picker with prompts such as API Key and OAuth; providers with one method continue directly to that login flow. OAuth profiles that have both a local browser callback and device-code, currently Codex and xAI, then ask whether to use a browser callback or device-code, even when a browser is available. The default option is browser on a graphical session and device-code when headless. Custom · Chat Completions and Custom · Responses each collect a name, a base URL, and an optional API key. Direct args (/login openai, /login anthropic, and so on) target a single method. See each provider page for the exact flow.
Interactive logins always show the authorize URL, including when a local browser opened. Headless or remote sessions (SSH, no display, nested harness) skip launching a browser and prefer a device-code flow when the provider has one. In the TUI the URL and any device code stay in the composer, including on first-run setup, so they are visible without the transcript. Press c to copy the URL (OSC-52 over SSH), or click COPY next to the link. Esc cancels, or goes back when a parent picker is open. rho login prints the same URL and code; it selects device-code automatically when no browser can appear, so you do not need --device-auth after the fact. --device-auth still forces device-code on a graphical session.
Claude Code login is the exception: /login claude-code hands the terminal to claude auth login and never sees an authorize URL. /login cursor does the same for cursor-agent login.
Successful login normally stores credentials only. It does not switch the active provider/model, because provider switching is model-driven through /model. If Rho started without usable auth and is running on an unauthenticated placeholder, a successful login selects that provider's default model so the session becomes usable.
/logout opens a provider picker containing only providers with stored credentials that can be deleted. If an environment override is still present, the provider remains available after deleting the stored credential. When Claude Code is signed in, /logout also offers claude-code as a separate runtime target.
Claude Code runtime sign-in
Claude Code is a runtime, not a Rho provider. It is separate from the Anthropic API-key provider. Anthropic does not allow third-party clients to use Claude.ai subscription credentials on their own API stacks, so Rho cannot put a Pro/Max plan on the normal Anthropic provider path. runtime: claude-cli is the indirect workaround: delegate a child to the official claude binary, which owns sign-in and plan usage (see subscription workaround and how to use it). Install the claude binary first (installation).
/login claude-code(or Anthropic → Claude Code (delegation only) in the picker) asks you to confirm, then hands the terminal toclaude auth login --claudeai. Rho suspends its TUI for that process and resumes when it exits. Cancel the confirmation to stay in Rho. After the handoff, the Claude prompt has no cancel key; stop theclaudeprocess from another terminal or close that prompt if you need to get out.- Claude Code runs the sign-in UI, stores the subscription credential, and remains the owner of that state. Rho never sees or stores the token and never writes a Rho credential-store entry for it.
- Rho reads signed-in state with bounded
claude auth statusprobes for/infoand/doctor. Ownership wording stays explicit (managed by the claude binary). - Sign out with
/logout claude-code(after an explicit confirmation that this signs out of Claude Code everywhere) or withclaude auth logoutyourself. That is a global Claude Code logout, not a Rho token delete. Rho cannot remove a Claude token from the Rho credential store because it never stored one. - Bare
/loginlists Claude Code under the Anthropic group next to the Anthropic API key method. Choosing it skips the Rho credential-store chooser entirely.
Cursor Agent runtime sign-in
Cursor Agent is a runtime, not a Rho provider. Agent definitions with runtime: cursor delegate to cursor-agent. Install that binary first (installation).
/login cursor(alias/login cursor-agent) suspends the TUI and hands the terminal tocursor-agent login. SetNO_OPEN_BROWSER=1on the child environment if you need the URL printed instead of a browser open. After the handoff there is no cancel key inside the Cursor prompt.- Cursor Agent runs the sign-in UI and stores credentials in
~/.cursor. Rho never sees or stores the token and never writes a Rho credential-store entry for it. - Rho reads signed-in state with bounded
cursor-agent status --format jsonprobes for/infoand/doctor. /logout cursoris not available from Rho. Sign out withcursor-agent logoutyourself.- Bare
/loginlists Cursor as a top-level row. Choosing it skips the Rho credential-store chooser.
Selecting models
Use /model provider/model to switch explicitly, including to another provider:
/model openai/gpt-5.6-sol
/model openai-codex/gpt-5.6-sol
/model anthropic/claude-sonnet-4-5
/model google/gemini-3.1-flash-lite
/model github-copilot/gpt-4.1
/model openrouter/anthropic/claude-sonnet-4
/model ollama/<installed-model>
/model ollama-cloud/<hosted-model>
/model xai/grok-4.7A bare model id works when it uniquely matches the catalog for the active selection rules. Uncataloged bare model ids stay on the current provider as an escape hatch for newly released models.
Refresh a provider list with /refresh-models or /config → Providers → Refresh model lists before selecting a newly released model. Codex OAuth and xAI OAuth stay on static allowlists.
Where credentials live
Rho recommends the native OS credential store. When the credential backend is still unset, the first interactive login for a normal Rho provider probes available backends and opens a picker before any secret is saved. Bare /login opens the provider group picker first; the store chooser appears only after you pick a normal provider (or run /login <provider>). CLI rho login asks the same store question on a TTY. If the OS probe fails, you can choose local file storage instead.
Interactive startup, including rho --resume, prints a notice before its first OS-keyring access. If startup pauses there, check your desktop for a keyring unlock prompt. The notice does not mean the keyring is locked; it identifies a step that can wait for desktop approval. File-backed credentials and non-interactive runs do not show it.
Local file storage keeps secrets in ~/.rho/credentials/secrets.json (or under RHO_HOME). Rho applies owner-only directory and file permissions on Unix and a protected user-only ACL on Windows. It is not encrypted at rest. Rho never selects it without an explicit login picker answer, CLI command, config value, or environment setting.
rho credential-store status
rho credential-store probe os
rho credential-store probe file
rho credential-store set os
rho credential-store set fileBackends are os and file only. When no choice has been saved, Rho uses the OS store and does not fall back to a file. rho credential-store status prints the saved config policy only: unset, os, or file. RHO_CREDENTIAL_STORE=os|file overrides the saved policy for the current process. The policy contains no secrets and is saved in ~/.rho/config.toml as behavior.credential_store.
On macOS, see Apple's Keychain access prompt documentation when the OS asks whether to allow a credential-store operation.
For normal interactive setup, prefer /login. Environment variables are CI/development escape hatches and override stored credentials; each provider page lists the variables it reads. Command-line flags override values loaded from configuration for the current invocation. Pass --save with --provider, --model, --auth, or --reasoning to make those choices the saved default.
Model metadata
Rho uses cached model metadata to choose context windows for status display and auto compaction. The same metadata supplies each model's available reasoning effort levels, so the TUI can skip unsupported choices without model-name allowlists. Override a window or reasoning list in ~/.rho/models.toml. A custom OpenAI-compatible host that is not itself in models.dev can set catalog to another provider slug and borrow that catalog. See local model metadata and Custom OpenAI-compatible hosts.
For subscription auth modes such as Codex OAuth and xAI OAuth, the statusline still estimates an equivalent API cost from models.dev pricing (including long-context rate tiers when available) and labels it (sub). When a model is seen for the first time, Rho refreshes models.dev so newly added providers are not stuck on a stale local snapshot.
For persistent defaults, see configuration. For one-shot prompts, see automation and CLI.