Skip to main content

Module auth

Module auth 

Source
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:

  1. Generate PKCE verifier + challenge
  2. Start localhost callback server
  3. Open browser to claude.ai/oauth/authorize
  4. Capture redirect with auth code
  5. Exchange code for access + refresh tokens
  6. 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::unauthorized_hint;
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 LocalBroker in the process (a daemon can hold several brokers, one per runtime TokenCache).

Structs§

AccountInventory
Listing of one provider’s stored accounts plus any sibling keys that look like accounts of this provider but fail validation (never loaded).
AccountMetadata
Non-secret metadata stored beside a credential (label, identity, addedAt). Kept separate from OAuthCredentials so refresh writes, which only carry token fields, never clobber it.
AuthFile
BrokerClient
HTTP client for a credential broker. Presents the machine’s own bearer token (NOT the provider credential) and receives a short-lived access token.
BrokerToken
An access token as returned by the broker’s GET /token.
CallbackResult
Result from the OAuth callback.
CallbackServerHandle
LoginPersistOutcome
Outcome of save_credential_unless_duplicate.
OAuthCredentials
RefreshFailure
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.
TokenCache
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§

CallbackOutcome
CredentialSource
Where a client gets its provider credentials.
IdentityEvidence
What the duplicate-identity guard could establish for a new login.
RefreshFailureKind
Why a locked refresh produced no token, so callers can tell the user the right thing: only RefreshFailureKind::Credential means the login itself is unusable (“run synaps login”).

Constants§

DEFAULT_MARGIN_MS
Default refetch margin: 5 minutes (mirrors is_token_expired).

Traits§

TokenFetcher
“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_credential with CredentialRef::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 stores account_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_ms is already past, or within margin_ms of now.
is_token_expired
Check if the current token is expired.
list_accounts
Enumerate stored OAuth accounts for provider (non-secret rows; selected is left false for 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 (anthropic or anthropic@<label>); with None it 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 true if 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 or auth.json.
resolve_remote_token
Like resolve_remote but 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_auth resets 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 display identity. Used by the auth identify backfill 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