Authentication
BMO supports 15+ AI providers. Most use environment variables or config
interpolation. GitHub Copilot, Hyper, and OpenRouter also support a human-run
bmo auth bootstrap.
Credential ownership by surface
Section titled “Credential ownership by surface”Use the surface’s own auth contract. BMO does not use one universal “authentication” mechanism across provider, CLI, editor, MCP, and service boundaries.
| Surface | Examples | Who owns credentials | How to bootstrap | Where to verify |
|---|---|---|---|---|
| Standard provider API | OpenAI, Anthropic, Groq, Xiaomi, OpenAI-compatible providers | Operator + BMO config/env | Environment variables or [providers.<id>] config | bmo config show-provider-status, /provider-status, bmo auth summary |
| Provider OAuth bootstrap | Copilot, Hyper, OpenRouter | Operator starts the flow; BMO stores the resulting token or API key | bmo auth copilot, bmo auth hyper, bmo auth openrouter, or Manage Providers | get_provider_auth_wizard, bmo config show-provider-status, /provider-status |
| Cloud identity | Bedrock, Vertex AI, Azure OpenAI | Cloud account, profile, or ambient runtime identity | Environment variables, profiles, or provider options such as auth_source | bmo auth bedrock, bmo auth bedrock doctor, /config-status |
| CLI-owned auth | Codex CLI, Antigravity CLI, Gemini CLI, Qwen Code, Claude Code, Cursor Agent | The vendor CLI or local tool | Use the vendor login flow or its env vars; BMO launches the local binary and inherits that auth state | bmo config show-provider-status for BMO readiness; vendor CLI status commands for login state |
| ACP child provider | codex-acp, opencode-acp, copilot-acp | The child agent process / vendor tool | Configure the child binary and its auth contract; BMO only owns selector, readiness, and launch posture | bmo config show-provider-status, bmo config show-model-selection, ACP providers/list |
| MCP client OAuth | [mcp.<id>].auth = "oauth" | BMO’s MCP client auth handler + the remote MCP server | Configure the MCP client block and complete the browser callback flow when prompted | MCP runtime reconnect/status plus the OAuth topic |
| BMO service auth | bmo service start http, bmo service start mcp | BMO service boundary | --auth, --token, [services.http], [services.mcp] | Service config/status and the HTTP server topic |
Environment variables
Section titled “Environment variables”| Variable | Provider |
|---|---|
ANTHROPIC_API_KEY | Anthropic (Claude) |
OPENAI_API_KEY | OpenAI |
VERCEL_API_KEY | Vercel AI Gateway |
GEMINI_API_KEY | Google Gemini |
SYNTHETIC_API_KEY | Synthetic |
ZAI_API_KEY | Z.ai |
MINIMAX_API_KEY | MiniMax |
HF_TOKEN | Hugging Face Inference |
CEREBRAS_API_KEY | Cerebras |
XIAOMI_API_KEY | Xiaomi MiMo |
OPENROUTER_API_KEY | OpenRouter |
IONET_API_KEY | io.net |
GROQ_API_KEY | Groq |
NANOGPT_API_KEY | NanoGPT custom OpenAI-compatible provider |
NVIDIA_API_KEY | NVIDIA-hosted NIM custom OpenAI-compatible provider |
Google Cloud Vertex AI
Section titled “Google Cloud Vertex AI”export VERTEXAI_PROJECT=my-project-idexport VERTEXAI_LOCATION=us-central1Amazon Bedrock
Section titled “Amazon Bedrock”export AWS_ACCESS_KEY_ID=...export AWS_SECRET_ACCESS_KEY=...export AWS_REGION=us-east-1# Optional session token (for temporary credentials / STS):export AWS_SESSION_TOKEN=...# Or use a named profile:export AWS_PROFILE=my-bedrock-profile# Or bearer token:export AWS_BEARER_TOKEN_BEDROCK=...BMO also reads AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE as fallbacks.
For unattended bmo run or agent-orchestrated work, prefer pinning the
credential source so a stale SSO profile cannot win the AWS SDK default chain:
[providers.bedrock.provider_options]auth_source = "env" # auto, env, profile, bearer, or containerregion = "us-east-1"BMO also honors BMO_AWS_ACCESS_KEY_ID, BMO_AWS_SECRET_ACCESS_KEY,
BMO_AWS_REGION, and the matching BMO_AWS_* variants as process-local
overrides for Bedrock.
For Bedrock API-key style access, BMO can also store the bearer token as the provider key and keep the raw token in the durable credential store:
printf '%s' "$AWS_BEARER_TOKEN_BEDROCK" | bmo auth bedrock token bedrockconverse --token-stdinThat command writes a keychain:<provider> sentinel when durable storage is
available. Use auth_source = "bearer" to force bearer-token auth, or leave
auth_source unset to let automatic auth pick the provider token before
ambient Bedrock bearer-token environment variables. AWS profile, env-key, and
container modes remain the right choice for IAM role or SSO-backed deployments.
Container credentials (ECS / Fargate)
Section titled “Container credentials (ECS / Fargate)”When running in an AWS container environment, set auth_source = "container".
BMO reads AWS_CONTAINER_CREDENTIALS_RELATIVE_URI or
AWS_CONTAINER_CREDENTIALS_FULL_URI from the environment (set automatically
by ECS task roles). A region is still required:
[providers.bedrock.provider_options]auth_source = "container"region = "us-east-1"Bedrock auth diagnostics
Section titled “Bedrock auth diagnostics”Run /config-status in the TUI, or use the agent config_status tool, to see
the resolved Bedrock auth state, including credential source, region, profile,
and readiness status. Outside a session, run bmo auth bedrock for the same
redacted credential-mode check against the configured large model. Run
bmo auth bedrock doctor to inspect all configured Bedrock-family providers.
Azure OpenAI
Section titled “Azure OpenAI”export AZURE_OPENAI_API_ENDPOINT=https://my-resource.openai.azure.comexport AZURE_OPENAI_API_KEY=... # not needed when using Entra IDexport AZURE_OPENAI_API_VERSION=2024-02-01Browser and device-code auth
Section titled “Browser and device-code auth”bmo auth <platform> is a human-only bootstrap command group. It opens a browser
or asks you to complete a device-code flow, so agents should use
get_provider_auth_wizard and ask the operator to run the listed CLI command
rather than trying to finish OAuth themselves.
bmo auth copilotbmo auth hyperbmo auth openrouter- GitHub Copilot: reuses an existing refresh token from disk when present, otherwise starts the GitHub device flow.
- Hyper: starts device auth, shows a verification code, and exchanges the resulting refresh/access token.
- OpenRouter: starts a browser PKCE flow and stores the resulting API key.
CLI-owned auth and ACP children
Section titled “CLI-owned auth and ACP children”Local CLI and ACP-child providers do not use BMO’s provider OAuth bootstrap.
For Codex and other local CLI backends, BMO launches the local binary and
inherits that tool’s login state or env vars. bmo auth codex is guidance and
setup checking only; it does not store Codex credentials in BMO.
Use the vendor CLI’s normal auth flow first, then use BMO to select models, inspect readiness, and route turns. See the Multi-provider topic for strict CLI/ACP model selection and the ACP topic for ACP-child behavior.
Storing keys in config
Section titled “Storing keys in config”You can also set API keys directly in your BMO config file. Prefer environment variables for secrets.
# bmo.toml — only use for non-sensitive values or personal machines[providers.my-anthropic]base_url = "https://api.anthropic.com"api_key = "${ANTHROPIC_API_KEY}" # interpolate from envWhen a durable credential store is available, BMO can also keep provider
credentials behind keychain:<provider> sentinels instead of storing the raw
secret in config.
Using multiple providers
Section titled “Using multiple providers”BMO merges provider configs. Set keys for multiple providers and switch models mid-session with /model:
export ANTHROPIC_API_KEY=sk-ant-...export OPENAI_API_KEY=sk-...export GROQ_API_KEY=gsk-...export XIAOMI_API_KEY=...bmo# Then: /model gpt-4o or /model llama-3-70bFor TPM / rate-limit recovery, options.tpm_recovery.provider_model_fallback can list several model selectors on the same provider (for example multiple OpenRouter slugs). Implementation notes: tpm-fallback-openrouter-chains.md.
After wiring credentials, use bmo config show-model-selection for the
detached config projection, or /model-selection inside the TUI, to verify
which selector the next turn will actually use. Keep provider-status for
provider readiness and bmo models / GET /v1/models for raw catalog
inventory.
Which surface proves what
Section titled “Which surface proves what”Keep the read surfaces separate so you do not mistake catalog inventory for credential readiness or next-turn routing:
| Surface | Answers | Not for |
|---|---|---|
bmo config show-provider-status, /provider-status, GET /v1/provider-status | Which providers are configured, ready, ambiguous, or recently refreshed/applied | Raw catalog inventory |
bmo config show-model-selection, /model-selection, GET /v1/model-selection | Which selector or saved model the next turn will use | Proving credentials are usable |
bmo auth summary, bmo auth bedrock, bmo auth bedrock doctor | Redacted credential mode for the configured large model or Bedrock family | Choosing the next-turn model |
ACP providers/list | What an ACP client can present in its model picker, including unavailable rows | Owning or storing provider credentials |
bmo models, GET /v1/models, bmo update-providers | Raw catalog metadata and discovered model rows | Proving local auth, tool-calling, or task quality |
Model and provider claim status
Section titled “Model and provider claim status”BMO separates provider metadata from local verification:
| Status | Meaning | What to do |
|---|---|---|
| Provider claim | A provider catalog, provider docs, local CLI output, or model card says a model exists or supports a capability. | Treat it as source context until your configured BMO runtime can resolve and use it. |
| Local verification | BMO can resolve the configured provider/model, show availability diagnostics, and run through the relevant command, tool, or eval path. | Use bmo update-providers, /model, /config-status, provider parity reports, or targeted evals depending on the claim. |
| Local proof needed | The claim may be true, but this checkout has not proven credentials, availability, tool-calling, context size, or quality for your setup. | Keep the claim caveated and run the smallest local check before relying on it. |
Model names, context windows, provider routing suffixes, and supported
parameters can change outside BMO. bmo update-providers refreshes provider
catalog metadata; it does not prove credentials, model quality, tool support,
or that a provider-side model card matches your local configuration. Use
benchmarks and evals as task-specific evidence, not as a universal “best model”
ranking.
Custom and local providers
Section titled “Custom and local providers”See Custom Providers in the configuration reference for local Ollama, OpenAI-compatible endpoints, LM Studio setups, and self-hosted models.
For Ollama, define providers.ollama with type = "anthropic" and
base_url = "http://localhost:11434"; local Ollama does not require a BMO-managed API key.
For NanoGPT, define a custom openai-compat provider with
api_key = "${NANOGPT_API_KEY}". For NVIDIA-hosted NIM, use
api_key = "${NVIDIA_API_KEY}"; self-hosted NIM deployments may use a local
loopback URL and no real provider key, depending on the deployment’s auth
policy.
Using the embedded provider catalog
Section titled “Using the embedded provider catalog”BMO resolves providers from embedded metadata plus any cached Catwalk metadata
written by an explicit bmo update-providers run. In restricted networks, force
the embedded catalog and ignore refreshed cache metadata:
[options]disable_provider_auto_update = trueCredential source map
Section titled “Credential source map”bmo auth copilot, bmo auth hyper, or bmo auth openrouter. This step is intentionally human-run.keychain:<provider> sentinels when credentials should not live in shell history or project files.