auth

package
v0.27.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 6, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package auth handles credential storage and OAuth flows for AI providers.

Credentials are stored in ~/.config/moa/auth.json with mode 0600. Supports both API keys and OAuth tokens (Claude Max).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultStorePath

func DefaultStorePath() string

DefaultStorePath returns the default path for the auth store, or "" when no config directory can be resolved.

func IsOAuthToken

func IsOAuthToken(key string) bool

IsOAuthToken returns true if the given key looks like an OAuth token rather than a standard API key. Detects Anthropic OAuth (sk-ant-oat) and JWT tokens (three dot-separated segments, as used by OpenAI OAuth).

func OpenBrowser

func OpenBrowser(url string)

OpenBrowser opens a URL in the default browser.

Types

type Credential

type Credential struct {
	Type      string `json:"type"`                 // "api_key" or "oauth"
	Key       string `json:"key,omitempty"`        // API key (type=api_key)
	Access    string `json:"access,omitempty"`     // OAuth access token (type=oauth)
	Refresh   string `json:"refresh,omitempty"`    // OAuth refresh token (type=oauth)
	Expires   int64  `json:"expires,omitempty"`    // OAuth token expiry (unix ms) (type=oauth)
	AccountID string `json:"account_id,omitempty"` // Provider-specific account ID (e.g., OpenAI chatgpt_account_id)
}

Credential represents a stored credential for a provider.

type OAuthCredentials

type OAuthCredentials struct {
	Access    string `json:"access"`
	Refresh   string `json:"refresh"`
	Expires   int64  `json:"expires"`              // Unix milliseconds
	AccountID string `json:"account_id,omitempty"` // OpenAI chatgpt_account_id
}

OAuthCredentials holds the result of an OAuth login/refresh.

func CompleteXAIDeviceFlow added in v0.26.0

func CompleteXAIDeviceFlow(ctx context.Context, client *http.Client, _ XAIEndpoints, device *XAIDeviceCode) (*OAuthCredentials, error)

CompleteXAIDeviceFlow uses the endpoint and expiry captured at authorization; it never rediscovers metadata or restarts the device-code lifetime.

func LoginAnthropic

func LoginAnthropic(openURL func(string), promptCode func() (string, error)) (*OAuthCredentials, error)

LoginAnthropic runs the Anthropic OAuth PKCE flow (device code style): 1. Generate PKCE verifier + challenge 2. Open browser to Anthropic authorize URL 3. User approves and sees a code on Anthropic's callback page 4. User pastes the code back into the CLI 5. Exchange code for tokens

promptCode is called to get the authorization code from the user. It receives the auth URL (for display) and should return the pasted code string.

func LoginOpenAI

func LoginOpenAI(openURL func(string), promptCode func() (string, error)) (*OAuthCredentials, error)

LoginOpenAI runs the OpenAI PKCE OAuth flow with a local callback server. Returns credentials including the accountId extracted from the JWT.

openURL is called to open the browser. promptCode is the fallback if the local server doesn't receive the callback.

func LoginXAI added in v0.26.0

func LoginXAI(ctx context.Context, openURL func(string), display func(*XAIDeviceCode)) (*OAuthCredentials, error)

func RefreshAnthropicToken

func RefreshAnthropicToken(refreshToken string) (*OAuthCredentials, error)

RefreshAnthropicToken refreshes an expired OAuth token.

func RefreshOpenAIToken

func RefreshOpenAIToken(refreshToken string) (*OAuthCredentials, error)

RefreshOpenAIToken refreshes an expired OpenAI OAuth token.

func RefreshXAIToken added in v0.26.0

func RefreshXAIToken(refreshToken string) (*OAuthCredentials, error)

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store manages credentials on disk.

func NewStore

func NewStore(path string) *Store

NewStore creates or loads a credential store.

func (*Store) CredentialKind added in v0.26.0

func (s *Store) CredentialKind(provider string) string

CredentialKind reports the credential origin without inspecting token contents. Environment values are always API keys, including JWT-shaped xAI values, so transport selection cannot be confused by token syntax.

func (*Store) Get

func (s *Store) Get(provider string) (Credential, bool)

Get retrieves a credential for a provider.

func (*Store) GetAPIKey

func (s *Store) GetAPIKey(provider string) (key string, isOAuth bool, err error)

GetAPIKey resolves the API key for a provider. Priority:

  1. Environment variable (ANTHROPIC_API_KEY, etc.)
  2. OAuth token from store (auto-refreshed if expired)
  3. API key from store

Returns the key and whether it's an OAuth token.

func (*Store) GetAccountID

func (s *Store) GetAccountID(provider string) string

GetAccountID returns the stored account ID for a provider (e.g., OpenAI chatgpt_account_id).

func (*Store) PeekOAuthToken

func (s *Store) PeekOAuthToken(provider string) (token string, isOAuth, valid bool)

PeekOAuthToken returns the current OAuth access token for a provider WITHOUT triggering a refresh. It is for read-only, best-effort callers (e.g. the plan usage widget) that must never rotate the shared refresh token.

  • isOAuth is true when an OAuth credential is in use for the provider.
  • valid is true only when a non-expired access token is available.

When isOAuth is true but valid is false, the token has expired: the caller should treat usage as temporarily unavailable rather than refresh, and let a real API call renew the token on demand.

func (*Store) RefreshOAuthIfCurrent added in v0.26.0

func (s *Store) RefreshOAuthIfCurrent(provider, rejected string) (string, error)

RefreshOAuthIfCurrent reactively rotates an OAuth token that a consumer API rejected. If another request already rotated it, that newer token is reused. It deliberately never considers environment variables: those are API keys.

func (*Store) Remove

func (s *Store) Remove(provider string) error

Remove deletes a credential for a provider.

func (*Store) Set

func (s *Store) Set(provider string, cred Credential) error

Set stores a credential for a provider.

type XAIDeviceCode added in v0.26.0

type XAIDeviceCode struct {
	DeviceCode              string
	UserCode                string
	VerificationURI         string
	VerificationURIComplete string
	ExpiresIn               time.Duration
	Interval                time.Duration
	// contains filtered or unexported fields
}

XAIDeviceCode is the user-facing part of an RFC 8628 authorization request.

func StartXAIDeviceFlow added in v0.26.0

func StartXAIDeviceFlow(ctx context.Context, client *http.Client, endpoints XAIEndpoints) (*XAIDeviceCode, error)

type XAIEndpoints added in v0.26.0

type XAIEndpoints struct {
	DiscoveryURL   string
	AllowedHosts   []string
	AllowedIssuers []string
	AllowHTTP      bool
	Wait           func(context.Context, time.Duration) error
	Now            func() time.Time
}

XAIEndpoints is test configuration for the xAI OIDC client. Production must leave it empty: that pins discovery, issuer, and endpoints to auth.x.ai. A non-default endpoint requires an explicit host allowlist. AllowHTTP and Wait are intended only for local tests.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL