Expand description
OAuth 2.0 Authorization Code + PKCE flow for Anthropic (Claude Pro/Max).
Implements the same flow as Claude Code and Pi coding agent:
- Generate PKCE verifier + challenge
- Start localhost callback server
- Open browser to claude.ai/oauth/authorize
- Capture redirect with auth code
- Exchange code for access + refresh tokens
- Save to ~/.pi/agent/auth.json (shared with Pi)
Re-exports§
pub use auto_selection::AutoSelectionPolicy;pub use auto_selection::PlanRow;pub use auto_selection::SelectionPlan;pub use auth_state::AuthStateQuery;pub use auth_state::AuthStateReport;pub use auth_state::AUTH_STATE_SCHEMA_VERSION;pub use quota_policy::AccountFailure;pub use quota_policy::AccountFailureKind;pub use quota_policy::ObservationFailure;pub use quota_policy::SelectionFailure;pub use quota_policy::SelectionFailureKind;pub use account::account_config_key;pub use account::account_env_var;pub use account::seat_fingerprint;pub use account::Account;pub use account::AccountLabel;pub use account::AccountPolicy;pub use account::AccountSelector;pub use account::AccountSummary;pub use account::CredentialRef;pub use account::SeatIdentity;pub use account::AUTO_ACCOUNT_NAME;pub use account::DEFAULT_ACCOUNT_NAME;pub use anthropic_profile::fetch_anthropic_profile;pub use anthropic_profile::parse_anthropic_profile;pub use anthropic_profile::AnthropicProfile;pub use anthropic_profile::ANTHROPIC_PROFILE_URL;pub use broker::broker_from_source;pub use broker::global_broker;pub use broker::global_broker_install_count;pub use broker::local_auth_state;pub use broker::preflight_cloud_capability;pub use broker::set_global_broker;pub use broker::AccessToken;pub use broker::BrokerError;pub use broker::CredentialBroker;pub use broker::CredentialKind;pub use broker::LocalBroker;pub use broker::PinnedToken;pub use broker::ProviderStatus;pub use broker::ProxyByteStream;pub use broker::ProxyMethod;pub use broker::ProxyRequest;pub use broker::ProxyResponse;pub use broker::RemoteBroker;pub use broker::StaticKeyStatus;pub use broker::MAX_PROXY_REQUEST_BYTES;pub use broker::MAX_PROXY_RESPONSE_BYTES;pub use broker::MAX_UPSTREAM_ERROR_BYTES;pub use broker::PROXY_REQUEST_TIMEOUT;pub use broker_token::is_loopback_endpoint;pub use broker_token::load_or_create_broker_token;pub use broker_token::local_broker_token_path;pub use broker_token::read_local_broker_token;pub use broker_token::BrokerTokenOrigin;pub use broker_token::MachineToken;pub use broker_token::LOCAL_BROKER_TOKEN_FILE;pub use cloud::AuthIdentity;pub use cloud::AwsBedrockConfig;pub use cloud::AzureOpenAiConfig;pub use cloud::BrokerMessage;pub use cloud::BrokerOperation;pub use cloud::BrokerTool;pub use cloud::CloudProviderId;pub use cloud::GoogleVertexConfig;pub use cloud::InvokeOptions;pub use cloud::InvokeRequest;pub use cloud::MessageRole;pub use cloud::ProviderId;pub use github_copilot::login as login_github_copilot;pub use identity::identity_http_client;pub use identity::resolve_seat;pub use identity::supports_seat_identity;pub use identity::ResolvedSeat;pub use identity::SeatResolution;pub use kimi_code::login as login_kimi_code;pub use muse::login as login_muse;pub use provider::BrokerCredentialStrategy;pub use provider::OAuthProviderDescriptor;pub use provider::OAuthProviderId;pub use provider::OAuthProviderRegistry;pub use static_providers::static_provider;pub use static_providers::StaticProviderSpec;pub use static_providers::LOCAL_PROVIDER_KEY;pub use usage::fetch_usage;pub use usage::UsageError;pub use usage::UsageSnapshot;
Modules§
- account
- Account references for multi-account OAuth credentials.
- anthropic_
profile - Anthropic OAuth profile lookup: the seat identity behind a Claude credential.
- auth_
state synaps auth state: what one broker remembers about its accounts (each account’s cooldown, its last usage read and last token refresh exchange, and the last automatic selection), read from memory only.- auto_
selection - Automatic subscription choice and its secret-free explanation.
Eligibility remains in
quota_policy; config and the preview use that same policy so the CLI cannot promise a different account than the broker. - aws_
bedrock - Provider-local IAM Identity Center and Bedrock broker boundary. The transport trait is intentionally typed: it cannot sign arbitrary URLs or vend credentials.
- azure_
openai - Provider-local Azure OpenAI OAuth, catalog, and broker request contracts. No function in this module performs network I/O or returns credentials.
- broker
- The credential broker — the mandatory boundary between runtimes and
provider secrets (Checkpoint 1 decision,
docs/decisions/credential-broker-checkpoint-1.md). - broker_
token - Zero-config machine token for a loopback
synaps auth-broker(#147 C1). - cloud
- Shared, credential-free cloud provider contracts.
- cloud_
login - Provider-specific interactive cloud login protocols. Credentials remain persisted only through the broker-owned auth store.
- github_
copilot - GitHub Copilot OAuth (device authorization + broker-owned session mint).
- google_
gemini - Google Gemini (Code Assist) OAuth: authorization-code + PKCE.
- google_
vertex - Provider-local Google Vertex AI installed-app OAuth primitives.
- identity
- Provider-generic seat identity resolution.
- kimi_
code - Kimi Code OAuth (RFC 8628 device authorization; direct bearer, no mint).
- muse
- Meta Muse Code OAuth (RFC 8628 device authorization + Model API key mint).
- provider
- Typed OAuth provider identity, descriptors, registry validation, and dispatch.
- providers
- quota_
keeper - G6 — quota keeper: pure scheduler state machine, private persisted state and singleton/attempt locking.
- quota_
policy - G5 — pure capacity-selection policy for multi-account OAuth providers.
- static_
providers - Static-key provider connection metadata, owned by the credential broker.
- usage
- Read-only, normalized quota/usage snapshots for the four OAuth providers the multi-account broker manages: Claude (Anthropic), ChatGPT/Codex, Kimi Code and Grok (xAI).
- usage_
reads - Process-wide table of Anthropic/OAuth usage reads, one entry per account
slot, shared by every
LocalBrokerin the process (a daemon can hold several brokers, one per runtimeTokenCache).
Structs§
- Account
Inventory - Listing of one provider’s stored accounts plus any sibling keys that look like accounts of this provider but fail validation (never loaded).
- Account
Metadata - Non-secret metadata stored beside a credential (
label,identity,addedAt). Kept separate fromOAuthCredentialsso refresh writes, which only carry token fields, never clobber it. - Auth
File - Broker
Client - HTTP client for a credential broker. Presents the machine’s own bearer token (NOT the provider credential) and receives a short-lived access token.
- Broker
Token - An access token as returned by the broker’s
GET /token. - Callback
Result - Result from the OAuth callback.
- Callback
Server Handle - Login
Persist Outcome - Outcome of
save_credential_unless_duplicate. - OAuth
Credentials - Refresh
Failure - A refresh failure: its kind plus a log-safe message (our own texts, or provider errors that went through the provider’s sanitizer) and, when the token endpoint answered with a failure, its HTTP status. Never carries token material.
- Token
Cache - Thread-safe cache of broker access tokens. Cloneable handle over shared state. Holds ONLY short-lived access tokens, never a refresh token, never persisted to disk.
Enums§
- Callback
Outcome - Credential
Source - Where a client gets its provider credentials.
- Identity
Evidence - What the duplicate-identity guard could establish for a new login.
- Refresh
Failure Kind - Why a locked refresh produced no token, so callers can tell the user
the right thing: only
RefreshFailureKind::Credentialmeans the login itself is unusable (“runsynaps login”).
Constants§
- DEFAULT_
MARGIN_ MS - Default refetch margin: 5 minutes (mirrors
is_token_expired).
Traits§
- Token
Fetcher - “Get a fresh access token from somewhere.” Abstracted so the cache/resolve
logic is unit-testable without real HTTP. The real impl is
BrokerClient.
Functions§
- any_
oauth_ credential_ present - True if auth.json holds at least one OAuth credential of ANY provider or account. Used for broker startup/health so non-Anthropic-only installations work.
- auth_
file_ path - Get the path to auth.json (~/.synaps-cli/auth.json).
- build_
auth_ url - Build the full authorize URL for the browser.
- ensure_
fresh_ credential - Ensure one addressed credential (provider + account) has a fresh token.
- ensure_
fresh_ provider_ token - Ensure an OAuth provider (including Anthropic) has a fresh token in its
default account slot. Equivalent to
ensure_fresh_credentialwithCredentialRef::default_for. - ensure_
fresh_ token - Acquire the Anthropic refresh gate, check token freshness, refresh if needed, and persist the result atomically. Returns the current (possibly refreshed) credentials.
- exchange_
code_ for_ tokens - Exchange an authorization code for access + refresh tokens.
- extract_
codex_ account_ id - extract_
codex_ email - Display-only identity (email claim) carried by a Codex access token, if present. Never a secret; used to label accounts in listings.
- find_
duplicate_ identity - Duplicate-identity guard for login: returns the account (of the same
provider, other than
except) that already storesaccount_id. - generate_
code_ challenge - Compute S256 code challenge from verifier.
- generate_
code_ verifier - Generate a cryptographically random code verifier (43-128 chars, base64url).
- generate_
state - Generate a random state parameter.
- is_
expired_ with_ margin - True if
expires_msis already past, or withinmargin_msof now. - is_
token_ expired - Check if the current token is expired.
- list_
accounts - Enumerate stored OAuth accounts for
provider(non-secret rows;selectedis leftfalsefor the caller to annotate). - list_
accounts_ detailed - Enumerate with malformed-key diagnostics (for
auth list). - list_
all_ accounts - Enumerate stored OAuth accounts for every provider.
- load_
auth - Load credentials from auth.json.
- load_
cloud_ state - Load an opaque broker-owned cloud provider state object.
- load_
credential - Load the credential stored in one account slot.
- load_
provider_ auth - Load one provider’s OAuth credential from auth.json.
- load_
static_ key - Load one provider’s broker-owned static API key from auth.json.
- login
- Run the full OAuth login flow into the default Anthropic slot.
- login_
into - Run the full OAuth login flow. With
Some(key)the credential is persisted ONLY into that slot (anthropicoranthropic@<label>); withNoneit is returned unsaved so the caller can run pre-persistence checks. - login_
openai_ codex - login_
xai - open_
browser - Open a URL in the default browser.
- refresh_
token - Refresh an expired OAuth token. Failures are typed at the source: no
response or an unusable success body is transient, a status is
classified by [
status_kind]. - remove_
credential - Remove one account slot. Returns
trueif a key was removed. Never leaves a partial file and never touches any other key. A corrupt file is an error (nothing is reset on a removal path). - resolve_
access_ token - Provider-aware token resolution honoring the credential source — kept as a
compatibility adapter for CLI callers (
synaps status). Delegates to the typed credential broker: the local in-process broker or the authenticated remote transport. Vends the access token only. - resolve_
remote - Resolve a provider token via cache-or-fetch, returning the full
BrokerToken(access + expiry). The runtime needs the expiry to drive its in-memory refresh trigger. NEVER touches a refresh token orauth.json. - resolve_
remote_ token - Like
resolve_remotebut returns only the access token string. - save_
account_ metadata - Merge non-secret metadata into an account slot (which must already exist).
- save_
auth - Save credentials to auth.json.
- save_
cloud_ state - Atomically persist opaque cloud state while preserving every unrelated field.
- save_
credential - Persist a credential into exactly one account slot. Other slots (including
the provider’s default slot) and any non-secret metadata already stored in
this slot are preserved. A corrupt store is an error — the account path
never resets the file (that would wipe every other slot); the legacy
single-credential
save_provider_authresets only an empty file. - save_
credential_ unless_ duplicate - Login persistence: duplicate scan and write happen inside ONE locked
read-modify-write of auth.json, so two concurrent logins (or a login
racing a remove/re-login) can never create two slots owning the same
seat. A duplicate is another slot of the same provider with the same
non-empty
accountId, or with an identical refresh token. - save_
provider_ auth - Save one provider credential while preserving other auth.json entries.
- save_
static_ key - Persist a broker-owned static API key while preserving every other auth.json entry and any provider metadata.
- set_
slot_ identity - Record the provider seat identity on an EXISTING OAuth slot: sets
accountId(the full provider account id) and, when given, the displayidentity. Used by theauth identifybackfill for slots whose login predates identity acquisition (Anthropic tokens are opaque; the seat comes from the profile endpoint after the fact). - start_
callback_ server - start_
callback_ server_ at