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)

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§

AccessToken
An OAuth access token vended by the broker.
AccountFailure
One account’s part in a failed selection.
AccountInventory
Listing of one provider’s stored accounts plus any sibling keys that look like accounts of this provider but fail validation (never loaded).
AccountLabel
Validated account label. Grammar: ^[a-z0-9][a-z0-9._-]{0,31}$; the words default and auto are reserved and rejected.
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.
AccountPolicy
Per-provider account selection. Built once from config (+ env overlay); never mutates the process environment or the active profile.
AccountSummary
Non-secret listing row for one stored account. Never carries token material; account_id_prefix is at most 8 characters.
AnthropicProfile
Non-secret identity of the Claude account behind an OAuth credential. account_uuid is the seat identity used for duplicate detection.
AuthFile
AuthStateQuery
Which accounts to report on, and whether to clear their state first.
AuthStateReport
One broker’s in-memory account state.
AutoSelectionPolicy
AwsBedrockConfig
AzureOpenAiConfig
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.
BrokerMessage
BrokerToken
An access token as returned by the broker’s GET /token.
BrokerTool
CallbackResult
Result from the OAuth callback.
CallbackServerHandle
CredentialRef
A fully addressed OAuth credential: provider + account slot.
GoogleVertexConfig
InvokeOptions
InvokeRequest
LocalBroker
In-process credential broker. This module is the ONLY place runtime-serving code may read auth.json, provider.<key> config values, or credential environment variables.
LoginPersistOutcome
Outcome of save_credential_unless_duplicate.
MachineToken
The machine token a client presents to a broker, with its provenance.
OAuthCredentials
OAuthProviderDescriptor
OAuthProviderRegistry
ObservationFailure
A failed observation: its kind plus the HTTP status and Retry-After the provider sent, when there were any. Never token material or body bytes.
PinnedToken
The selected/pinned pair a runtime works with for one attempt: the credential the broker chose and the token vended for exactly that credential. Account-specific headers (e.g. the Codex account id) must be derived from token, never from a second lookup.
PlanRow
ProviderStatus
Non-secret capability/status row for one provider.
ProxyRequest
A typed, credential-free request the broker executes on the caller’s behalf against an OpenAI-compatible provider endpoint.
ProxyResponse
Buffered (non-streaming) proxy result: upstream status + body text.
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.
RemoteBroker
Client for a remote synaps auth-broker. Presents the machine’s own bearer token; receives access tokens (OAuth) and proxied responses (static-key providers). Never receives refresh tokens or raw keys.
ResolvedSeat
Identity of the seat an access token belongs to. account_id is the provider’s FULL account id (the value stored as accountId and hashed by super::seat_fingerprint); identity is a display-only label such as an email. Neither is a secret.
SeatIdentity
Identity of the credential material currently stored in one slot. Scopes per-slot caches and pairs a proven-capacity reading with the token vended for it: the provider seat (via seat_fingerprint) when the credential carries an account id — stable across token rotation — otherwise a digest of the refresh material, which changes on re-login and on rotation. An opaque digest: not reversible, never logged with token material.
SelectionFailure
A failed automatic selection: the top-level kind, every account’s part in it, and the earliest known reset among limited accounts.
SelectionPlan
StaticProviderSpec
Connection/credential metadata for one static-key provider.
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.
UsageSnapshot
Normalized, secret-free usage observation for one (provider, account).

Enums§

Account
A concrete account slot for a provider.
AccountFailureKind
Why one account could not serve a request, as a stable snake_case kind: a failed observation (usage read, token refresh, credential store) or the policy verdict on a good one. Secret-free; safe for logs and users.
AccountSelector
What a caller asks for when no explicit account is given.
AuthIdentity
Credential mechanism used behind the broker boundary.
BrokerCredentialStrategy
How a runtime may obtain a usable credential from the broker.
BrokerError
Broker failures. Messages never contain credential values. Non-exhaustive: new failure kinds are added as brokers gain operations.
BrokerOperation
BrokerTokenOrigin
How load_or_create_broker_token obtained the token.
CallbackOutcome
CloudProviderId
CredentialKind
What kind of credential a provider uses. Never carries key material.
CredentialSource
Where a client gets its provider credentials.
IdentityEvidence
What the duplicate-identity guard could establish for a new login.
MessageRole
OAuthProviderId
ProviderId
General auth identity. Existing OAuth identity remains strongly typed.
ProxyMethod
HTTP method subset the proxy protocol supports.
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”).
SeatResolution
Outcome of resolve_seat.
SelectionFailureKind
The one kind that explains a failed automatic selection.
StaticKeyStatus
Non-secret display status for one static key (settings UI).
UsageError
Usage failures. Display/Serialize never include a token, a URL query, or any upstream body bytes.

Constants§

ANTHROPIC_PROFILE_URL
Pinned Anthropic OAuth profile endpoint.
AUTH_STATE_SCHEMA_VERSION
Version of AuthStateReport’s JSON shape (synaps auth state --json).
AUTO_ACCOUNT_NAME
Reserved selector word for opt-in automatic selection (G5).
DEFAULT_ACCOUNT_NAME
Reserved word for the bare provider slot. Never a label.
DEFAULT_MARGIN_MS
Default refetch margin: 5 minutes (mirrors is_token_expired).
LOCAL_BROKER_TOKEN_FILE
File name of the auto-generated loopback broker token.
LOCAL_PROVIDER_KEY
The local OpenAI-compatible endpoint pseudo-provider (Ollama, LM Studio…). Its endpoint URL is non-secret user configuration; its optional key is still broker-owned.
MAX_PROXY_REQUEST_BYTES
Maximum serialized size of a proxy request body.
MAX_PROXY_RESPONSE_BYTES
Maximum buffered (non-streaming) response body size.
MAX_UPSTREAM_ERROR_BYTES
Historical cap for upstream error-body snippets. Upstream/broker error bodies are no longer read at all (spec §5.1: they may echo the request); the constant remains only because it is re-exported from auth::mod.
PROXY_REQUEST_TIMEOUT
Total time budget for a buffered (non-streaming) broker-executed request.

Traits§

CredentialBroker
The typed credential broker protocol. One implementation runs in-process (LocalBroker) so normal local use needs no daemon; the other talks to a remote synaps auth-broker over authenticated HTTP(S) (RemoteBroker).
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§

account_config_key
Config key carrying the selected account for a provider.
account_env_var
Environment variable that selects the account for a provider: SYNAPS_ACCOUNT_<PROVIDER> with - → _, upper-cased.
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).
broker_from_source
remote transport. There is no third option — and no direct-read fallback.
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.
fetch_anthropic_profile
GET the profile for access_token and parse it. endpoint_override is a loopback-only test seam. The caller’s client should follow no redirects (see super::identity::identity_http_client); a 3xx is an error here regardless. Errors never contain the token or upstream bytes.
fetch_usage
Read-only usage fetch for one (provider, account) using the caller’s already-resolved access token. See the module docs for the guarantees.
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.
global_broker
The process-wide broker. Defaults to the in-process LocalBroker so normal local use never requires a separately launched daemon.
global_broker_install_count
How many times set_global_broker has run in this process.
identity_http_client
HTTP client with the policy identity lookups (and the token refresh that may precede them) require: no redirects, bounded connect/total timeouts.
is_expired_with_margin
True if expires_ms is already past, or within margin_ms of now.
is_loopback_endpoint
True when endpoint is an http(s) URL whose host is loopback (localhost, 127.0.0.0/8, ::1).
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_or_create_broker_token
Broker side: read the token at path, or create it when absent.
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.
local_auth_state
synaps auth state for the local broker cache holds for the current credential store and config (the one requests use) or, when no request has built one yet, the account list with nothing recorded. live: the caller is the process that serves requests (the daemon). No network request, no refresh; query.clear never writes the store.
local_broker_token_path
<base_dir>/auth-broker.token.
login
Run the full OAuth login flow into the default Anthropic slot.
login_github_copilot
Production login entry (real network + system browser + auth.json).
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_kimi_code
Production login entry (real network + system browser + auth.json).
login_muse
Production login entry (real network + system browser + auth.json).
login_openai_codex
login_xai
open_browser
Open a URL in the default browser.
parse_anthropic_profile
Pure parser for the profile body. Fails closed when account.uuid is missing, empty, non-string or over-long; every other field is optional and unknown/null fields are ignored.
preflight_cloud_capability
Build the right broker for a credential source. Local sources get the in-process broker (no daemon needed); remote sources get the authenticated Pre-flight capability check for a cloud route (spec §5.5). Pure function: callers MUST run it before constructing a broker, looking up credentials, or opening any connection. The invoke-time guard inside the broker remains in place as defense in depth.
read_local_broker_token
Client side: the local broker token, if the file exists and is non-empty.
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.
resolve_seat
Resolve the seat behind access_token for provider. endpoint_override is a loopback-only test seam for the network-backed providers.
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.
seat_fingerprint
Stable, opaque seat fingerprint: hex SHA-256 over a domain tag, the provider id and the provider’s FULL account id (e.g. the Codex chatgpt_account_id claim). Deterministic across processes and hosts, so a consumer holding a vended token can derive the same value from that token’s claim and compare it with AccountSummary::seat_fingerprint before spending on the listed seat. Never derived from token material.
set_global_broker
Install the process-wide broker (called once from runtime configuration). Every call is counted (global_broker_install_count) and, when SYNAPS_MEM_TRACE=1, logged — the daemon-mode S7 gate asserts the count stays at 1 across subagent spawns.
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
static_provider
Look up a static provider spec by key.
supports_seat_identity
True when resolve_seat can, in principle, return SeatResolution::Resolved for provider. Used by listings to point at slots whose identity is still unverified.
unauthorized_hint
Actionable text for a broker 401 (client side).

Type Aliases§

ProxyByteStream
Streaming proxy result: raw upstream bytes (SSE), post-authorization.