Meerkat’s auth story has two layers. The fast path is env vars (Documentation Index
Fetch the complete documentation index at: https://docs.rkat.ai/llms.txt
Use this file to discover all available pages before exploring further.
ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, or
AZURE_OPENAI_API_KEY plus AZURE_OPENAI_ENDPOINT) — set them and
rkat run works. The powerful path is realm-scoped bindings:
declare a realm in your config, register credentials via rkat auth login or the REST/RPC surfaces, and pass --auth-binding <realm>:<binding> to scope a session or mob member to that specific
binding.
Today, CLI
rkat auth login is primarily a convenience bootstrap flow for the default dev:* credential namespace. If you need explicit realm/profile-targeted auth persistence such as prod:openai, use the REST/RPC auth surfaces or manage the realm config entries directly.What this guide is for
Use this guide when you need more than the env-var fast path:- explicit realm-scoped bindings
- OAuth or cloud-IAM-backed auth
- hot-swapping provider identity
- per-mob-member credential overrides
ProviderRuntimeRegistry. There’s no
hidden magic path: the env fallback is a synthesized realm with
CredentialSourceSpec::Env, resolved by the same code that handles
your configured realms.
The fast path: env vars
env_default) with a binding that reads the key via
CredentialSourceSpec::Env, then resolves normally. RKAT_*-prefixed
env vars (e.g., RKAT_ANTHROPIC_API_KEY) take precedence over the
provider-native names.
| Provider | Primary env var | Fallback |
|---|---|---|
| Anthropic | ANTHROPIC_API_KEY | — |
| OpenAI | OPENAI_API_KEY | — |
| OpenAI on Azure | AZURE_OPENAI_API_KEY plus AZURE_OPENAI_ENDPOINT | Optional AZURE_OPENAI_IMAGE_GENERATION_DEPLOYMENT, AZURE_OPENAI_IMAGE_GENERATION_API_VERSION |
| Gemini | GEMINI_API_KEY | GOOGLE_API_KEY |
RKAT_AZURE_OPENAI_API_KEY plus
RKAT_AZURE_OPENAI_ENDPOINT, or an explicit realm binding, to make Azure
OpenAI the env default in that case.
The powerful path: realms + bindings
A realm is a named collection of backend profiles, auth profiles, and provider bindings. It lets you:- Run multiple sessions against different accounts or tenants
- Mix OAuth (Claude.ai Pro/Max), api_key (keyed by CI), and cloud IAM (Bedrock/Vertex/Foundry) in one process
- Hot-swap a session’s active binding mid-conversation
- Give different mob members different credentials
Realm shape
openai) with an Azure-specific
backend/auth pair:
Log in
dev:* identities and is best thought of as the easiest way to get persisted credentials into Meerkat quickly.
Use the binding
Subcommands
Status and refresh
rkat auth refresh is a no-op for api_key / azure_api_key / static_bearer
auth methods (nothing to refresh). For OAuth-backed methods it
exchanges the persisted refresh token for a fresh access token and
writes the new bundle back to the TokenStore.Release auth smoke
make e2e-auth is the CI-safe auth smoke lane. It drives Meerkat’s
browser OAuth plumbing against a local OAuth fixture, verifies token-store
and AuthMachine lifecycle behavior across login, status, refresh, restart,
resolve, and logout, and skips optional live-provider canaries when their
seeded credentials are absent.
Real third-party browser login pages remain a manual pre-release check.
Do not automate provider-hosted OpenAI, Anthropic, or Google login pages in
CI; those pages are intentionally subject to MFA, CAPTCHA, account policy,
and provider UI changes.
Manual browser-login release checklist:
- Start login for the target provider.
- Confirm the system browser opens the provider-hosted login or consent page.
- Complete the callback and confirm Meerkat reports the login complete.
- Check auth status and confirm the target binding is
valid. - Run one tiny call through that binding.
- Logout and confirm auth status is cleared and the credential is gone.
Auth methods
Each provider’s runtime accepts a matrix of(backend_kind, auth_method) pairs. The table below summarizes what’s wired today.
| Provider | backend_kind | auth_method | Notes |
|---|---|---|---|
| Anthropic | anthropic_api | api_key, static_bearer | Direct to api.anthropic.com |
| Anthropic | anthropic_api | claude_ai_oauth | Claude Pro/Max OAuth (PKCE, S256) |
| Anthropic | anthropic_api | oauth_to_api_key | Console OAuth → provisions api_key |
| Anthropic | anthropic_api | external_authorizer | Host-resolved auth injection |
| Anthropic | bedrock | bedrock_bearer, bedrock_aws_sigv4 | AWS SigV4 / env-bearer |
| Anthropic | vertex | vertex_google_auth | GoogleAuth / Vertex AI |
| Anthropic | foundry | foundry_api_key, foundry_azure_ad | Azure AI Foundry |
| OpenAI | openai_api | api_key, static_bearer, external_authorizer | Direct to api.openai.com or host-resolved auth |
| OpenAI | azure_openai | azure_api_key | Azure OpenAI Responses API; base_url required; session model is the Azure deployment name |
| OpenAI | chatgpt_backend | managed_chatgpt_oauth | ChatGPT Plus/Pro OAuth |
| OpenAI | chatgpt_backend | external_chatgpt_tokens | Host-supplied tokens |
google_genai | api_key, bearer_api_key, external_authorizer | Direct to Google GenAI or host-resolved auth | |
vertex_ai | api_key_express | Vertex API Express key | |
vertex_ai | adc, compute_adc | ADC / compute metadata | |
google_code_assist | google_oauth | Gemini Code Assist OAuth |
CredentialSourceSpec::Command) and file
descriptors (CredentialSourceSpec::FileDescriptor) let host
applications inject tokens without going through OAuth.
Credential sources
Thesource field on an auth profile declares where credentials
come from.
| Kind | Description |
|---|---|
InlineSecret { secret } | Secret stored inline in the TOML (use only for dev/local) |
Env { env, fallback } | Read env var at resolve time via ResolverEnvironment::env_lookup |
ManagedStore { profile } | Resolve via the TokenStore; in current provider runtimes, persisted lookup is tied to the active auth-profile identity/binding path |
PlatformDefault | Use the host platform’s default credential chain where supported |
ExternalResolver { handle } | Host-registered JS callback (WASM) or Rust resolver (embedded) |
Command { program, args, ... } | Run an external binary; cache stdout for refresh_interval_ms |
FileDescriptor { fd, scope_override } | Read credentials from a host-supplied file descriptor |
FileDescriptor is a host-integration seam rather than a plain standalone resolver path. It requires a host-scoped reader/injection path, so treat it as an advanced embedding surface rather than a generic CLI config trick.Hot-swap mid-session
When a session is created with--auth-binding prod:default, its
persisted SessionMetadata.auth_binding carries that binding through
resume and hot-swap. Changing the model/provider mid-turn via the RPC
turn/start override keeps the binding by default; pass an explicit
auth_binding on the turn request to scope the swap to a different
realm or binding.
ProviderRuntimeRegistry::resolve with the new
binding — no env-default fallback, no cross-realm credential bleed.
Per-mob-member override
Mob members default to env-default / config-realm fallback credentials. Passauth_binding on the host-side mob spawn surface to scope a member to a
specific binding:
auth_binding object only; the colon-joined realm:binding[:profile]
form is a CLI input convenience and is converted before it crosses the
wire boundary.
Refresh coordination
Refresh semantics are owned by theAuthMachine DSL (one instance
per <realm>:<binding>). On resolve, the runtime:
- Checks
expires_at. If present and within 80% of TTL, marks the leaseExpiringvia the DSL. - Under
Expiring, the next resolve triggersBeginRefresh. In-process dedup ensures only one refresh HTTP call per binding even under concurrent resolves; cross-process dedup via filesystem lockfile whenrefresh-file-lockis enabled. - On successful refresh, fires
CompleteRefreshand updatesexpires_at. On failure,RefreshFailedTransient(retry) orRefreshFailedPermanent(routes toReauthRequired+ emits an[AUTH_REAUTH_REQUIRED]system notice on the session).
specs/machines/auth/.
Audit logging
Every accepted lifecycle transition emits a structured tracing event:target = "meerkat::auth::audit"- Fields:
binding_key,action,from_phase,to_phase
create_profile, delete_profile, login_oauth_complete,
login_device_complete, logout. Filter any tracing::Subscriber
on the meerkat::auth::audit target to build a persistent audit log.
Feature flags
Themeerkat-providers crate gates optional auth methods behind
features so you only pay for what you use:
| Feature | Enables |
|---|---|
oauth | OAuth flows (Claude.ai, ChatGPT, Code Assist) |
native-keyring | OS keychain storage for tokens |
refresh-file-lock | Cross-process refresh dedup |
aws-auth | Bedrock backend + SigV4 signing |
google-oauth | Vertex + Code Assist + ADC |
azure-auth | Foundry backend + Azure AD |
rkat CLI enables anthropic, openai, gemini, and oauth
by default; add cloud-specific features at compile time for
Bedrock/Vertex/Foundry.
See also
- Hooks — observe auth events or gate turns on credential state
- Mobs — per-member
auth_bindingoverrides - Machine Authority — rationale behind single-owner runtime state
