litellmauth

package module
v0.0.0-...-d97fbab Latest Latest
Warning

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

Go to latest
Published: Jul 26, 2026 License: MIT Imports: 25 Imported by: 0

README

litellm-auth-go

litellm-auth-go authenticates Go applications and a small CLI with a LiteLLM proxy's browser-based CLI SSO flow. It returns the LiteLLM API key issued for the signed-in user and selected team.

Prerequisites

Use a LiteLLM proxy with SSO configured and support for the CLI SSO endpoints. At the pinned upstream version, these endpoints are beta/experimental and are excluded from its OpenAPI schema; see UPSTREAM_COMPATIBILITY.md for the exact upstream commit and contract.

For a proxy with multiple replicas, the login session must live in a shared auth cache (for example Redis). If LiteLLM reports an invalid CLI login session and asks for a shared cache, configure that shared cache before retrying; a browser callback and a poll request may otherwise reach different replicas.

Library

Create a client for the proxy URL and use OnSession to open the verification URL in the browser. The complete example is examples/browser-login.

client, err := litellmauth.New("https://proxy.example.com")
if err != nil {
	return err
}
credential, err := client.Authenticate(ctx, litellmauth.AuthenticateOptions{
	OnSession: func(_ context.Context, session litellmauth.Session) error {
		return browser.OpenURL(session.VerificationURL.String())
	},
})

For headless environments, do not open a browser. Print the verification URL and user code, then let the user open it elsewhere. Set TeamID when the application already knows the team; otherwise SelectTeam can choose from the proxy-provided teams. See examples/manual-login.

credential, err := client.Authenticate(ctx, litellmauth.AuthenticateOptions{
	TeamID: "team-engineering",
	OnSession: func(_ context.Context, session litellmauth.Session) error {
		fmt.Printf("Open %s\nCode: %s\n", session.VerificationURL, session.UserCode)
		return nil
	},
})
Use the returned key

credential.Key is the API key. Pass it as the bearer token to a standard http.Client; examples/use-token loads the stored, origin-bound credential and adds its Authorization: Bearer ... header in a RoundTripper.

For an existing OpenAI-compatible Go client, use the same key and proxy base URL. For example, an application already using github.com/openai/openai-go would configure it as:

client := openai.NewClient(
	option.WithAPIKey(credential.Key),
	option.WithBaseURL(credential.BaseURL+"/v1"),
)

Use the OpenAI-compatible route configured by the proxy; /v1 is common. This module does not require an OpenAI SDK.

CLI

Install from this module's checkout:

go install ./cmd/litellm-auth

Log in with a browser, or print the URL for manual/headless completion:

litellm-auth --base-url https://proxy.example.com login
litellm-auth --base-url https://proxy.example.com login --no-browser
litellm-auth --base-url https://proxy.example.com login --team team-engineering

Other commands are:

litellm-auth whoami
litellm-auth print-token
litellm-auth logout
litellm-auth import-token
Additional credential sources

login remains the LiteLLM CLI SSO flow. Use import-token to store a token from an environment variable, rotating file, stdin, or an external helper:

litellm-auth --base-url https://proxy.example.com import-token \
  --from-env LITELLM_API_KEY --non-expiring
litellm-auth --base-url https://proxy.example.com import-token \
  --from-file /var/run/secrets/token --non-expiring
printf '%s\n' "$LITELLM_API_KEY" | \
  litellm-auth --base-url https://proxy.example.com import-token \
  --from-stdin --non-expiring
litellm-auth --base-url https://proxy.example.com import-token \
  --from-exec /usr/local/bin/corp-token-helper --exec-arg issue \
  --exec-env PATH --exec-env HTTPS_PROXY

See authentication sources and binders for lifetime rules, external-helper schema, and library usage.

print-token only reads a fresh local token; it never logs in, refreshes a token, or makes a network request. Use --base-url when reading a token for a specific proxy. It rejects a token issued by another normalized proxy URL.

Setting Meaning
--base-url LiteLLM proxy URL. It takes precedence over LITELLM_PROXY_URL.
LITELLM_PROXY_URL Default proxy URL. login otherwise uses http://localhost:4000.
--token-file Credential file; default is ~/.litellm/token.json.
--timeout Total login timeout; default is 10 minutes.
--allow-insecure-http Permits non-loopback HTTP for development only.
--verbose Shows safe polling progress.
login --no-browser Does not launch a browser; prints the URL and code.
login --team Selects a LiteLLM team ID without prompting.

Credential storage and lifetime

The default token file is ~/.litellm/token.json. On Unix, the store creates the directory with private permissions and writes the file as 0600; it also rejects insecure existing file or directory modes. Treat the file and printed token as secrets. Credentials are bound to their normalized issuer URL, so a token cannot be loaded for a different proxy origin.

This protocol has no refresh or revocation operation. logout removes only the local token file; revoke or rotate a server-side key through the LiteLLM proxy when that is required. After a credential expires, SSO users rerun login and imported-token users rerun import-token from their configured source.

Verification

The examples compile without an OpenAI SDK:

go test ./examples/...

License

MIT. See LICENSE.

Documentation

Overview

Package litellmauth authenticates Go applications with a LiteLLM proxy's browser-based CLI SSO flow.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnsupportedProxy reports a proxy without the LiteLLM CLI SSO endpoints.
	ErrUnsupportedProxy = errors.New("proxy does not support LiteLLM CLI SSO")
	// ErrProtocol reports an invalid LiteLLM CLI SSO response.
	ErrProtocol = errors.New("invalid LiteLLM CLI SSO response")
	// ErrLoginExpired reports an expired LiteLLM CLI SSO session.
	ErrLoginExpired = errors.New("LiteLLM CLI login session expired")
	// ErrTeamRequired reports that a team must be selected to finish login.
	ErrTeamRequired = errors.New("team selection required")
	// ErrNoCredential reports that no stored credential exists.
	ErrNoCredential = errors.New("no stored LiteLLM credential")
	// ErrCredentialStale reports that a stored credential is expired.
	ErrCredentialStale = errors.New("stored LiteLLM credential is expired")
	// ErrOriginMismatch reports a credential issued by a different proxy URL.
	ErrOriginMismatch = errors.New("stored credential belongs to a different LiteLLM proxy")
	// ErrInvalidCredential reports a malformed or contradictory credential.
	ErrInvalidCredential = errors.New("invalid authentication credential")
	// ErrCredentialExpiryUnknown reports a credential without a known or explicitly unlimited lifetime.
	ErrCredentialExpiryUnknown = errors.New("authentication credential expiry is unknown")
	// ErrSourceUnavailable reports a configured source that did not produce a credential.
	ErrSourceUnavailable = errors.New("authentication source did not produce a credential")
	// ErrSourceOutput reports invalid external source output.
	ErrSourceOutput = errors.New("invalid authentication source output")
)

Functions

This section is empty.

Types

type AuthMethod

type AuthMethod string

AuthMethod identifies how a credential was acquired.

const (
	AuthMethodLiteLLMSSO  AuthMethod = "litellm-cli-sso"
	AuthMethodStatic      AuthMethod = "static"
	AuthMethodEnvironment AuthMethod = "env"
	AuthMethodFile        AuthMethod = "file"
	AuthMethodExec        AuthMethod = "exec"
	AuthMethodStdin       AuthMethod = "stdin"
)

type AuthenticateOptions

type AuthenticateOptions struct {
	// OnSession receives the session before polling, typically to open its URL.
	OnSession func(context.Context, Session) error
	// TeamID selects an offered team without calling SelectTeam.
	TeamID string
	// SelectTeam chooses an offered team when TeamID is empty.
	SelectTeam TeamSelector
	// OnEvent receives safe login progress events.
	OnEvent func(Event)
}

AuthenticateOptions configures Client.Authenticate.

type Authenticator

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

Authenticator applies one or more independent credentials.

func NewAuthenticator

func NewAuthenticator(bindings ...Binding) (*Authenticator, error)

NewAuthenticator validates and copies bindings.

func (*Authenticator) Apply

func (a *Authenticator) Apply(ctx context.Context, request *http.Request) error

Apply acquires every credential before atomically replacing request headers.

func (*Authenticator) GoString

func (a *Authenticator) GoString() string

GoString returns a secret-free description.

func (*Authenticator) String

func (*Authenticator) String() string

String returns a secret-free description.

func (*Authenticator) Transport

func (a *Authenticator) Transport(base http.RoundTripper) http.RoundTripper

Transport returns a RoundTripper that clones and authenticates each request.

type AwaitOptions

type AwaitOptions struct {
	// TeamID selects an offered team without calling SelectTeam.
	TeamID string
	// SelectTeam chooses an offered team when TeamID is empty.
	SelectTeam TeamSelector
	// OnEvent receives safe login progress events.
	OnEvent func(Event)
}

AwaitOptions configures Client.Await.

type Binder

type Binder interface {
	Bind(*http.Request, Credential) error
}

Binder attaches one credential to an HTTP request.

func NewA2ABearerHeader

func NewA2ABearerHeader(agentName string) (Binder, error)

NewA2ABearerHeader creates LiteLLM's per-A2A-agent bearer header.

func NewBearerHeader

func NewBearerHeader(header string) (Binder, error)

NewBearerHeader creates a Bearer header binder.

func NewMCPBearerHeader

func NewMCPBearerHeader(serverAlias string) (Binder, error)

NewMCPBearerHeader creates LiteLLM's per-MCP-server bearer header.

func NewPrefixedHeader

func NewPrefixedHeader(header, prefix string) (Binder, error)

NewPrefixedHeader creates a fixed-prefix header binder.

func NewRawHeader

func NewRawHeader(header string) (Binder, error)

NewRawHeader creates a raw token header binder.

type BinderFunc

type BinderFunc func(*http.Request, Credential) error

BinderFunc adapts a function to Binder.

func (BinderFunc) Bind

func (f BinderFunc) Bind(request *http.Request, credential Credential) error

Bind calls f.

type Binding

type Binding struct {
	Source Source
	Binder Binder
}

Binding pairs one credential source with one request binder.

func (Binding) GoString

func (b Binding) GoString() string

GoString returns a secret-free description.

func (Binding) String

func (Binding) String() string

String returns a secret-free description.

type Client

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

Client authenticates with one normalized LiteLLM proxy base URL.

func New

func New(baseURL string, opts ...Option) (*Client, error)

New creates a Client for baseURL. HTTPS is required except for loopback development URLs configured with WithAllowInsecureHTTP.

func (*Client) Authenticate

func (c *Client) Authenticate(ctx context.Context, options AuthenticateOptions) (Credential, error)

Authenticate starts a session, invokes OnSession, then waits for a credential.

func (*Client) Await

func (c *Client) Await(ctx context.Context, session Session, options AwaitOptions) (Credential, error)

Await polls session until it returns a credential or expires.

func (*Client) PollOnce

func (c *Client) PollOnce(ctx context.Context, session Session, teamID string) (PollResult, error)

PollOnce obtains one polling result for session and an optional team ID.

func (*Client) Start

func (c *Client) Start(ctx context.Context) (Session, error)

Start creates a browser login session without opening a browser or polling.

type Credential

type Credential struct {
	// BaseURL is the normalized proxy URL that issued Key.
	BaseURL string `json:"base_url"`
	// Key is the bearer token returned by LiteLLM.
	Key string `json:"key"`
	// AuthMethod identifies how Key was acquired.
	AuthMethod AuthMethod `json:"auth_method,omitempty"`
	// TokenType is the authorization scheme; empty means Bearer for compatibility.
	TokenType string `json:"token_type,omitempty"`
	// Issuer is optional non-secret identity-provider metadata.
	Issuer string `json:"issuer,omitempty"`
	// Subject is optional non-secret subject metadata.
	Subject string `json:"subject,omitempty"`
	// Scopes contains optional non-secret OAuth scopes.
	Scopes []string `json:"scopes,omitempty"`
	// NonExpiring explicitly marks a credential without a known expiry.
	NonExpiring bool `json:"non_expiring,omitempty"`
	// UserID is the authenticated user's proxy identifier.
	UserID string `json:"user_id"`
	// TeamID is the selected team identifier, when one applies.
	TeamID string `json:"team_id"`
	// TeamAlias is the selected team's optional display name.
	TeamAlias string `json:"team_alias"`
	// Teams is the set of teams available during login.
	Teams []Team `json:"teams"`
	// AttributionMetadata contains scalar metadata supplied by LiteLLM.
	AttributionMetadata map[string]any `json:"attribution_metadata"`
	// IssuedAt is when the credential was received.
	IssuedAt time.Time `json:"issued_at"`
	// ExpiresAt is the credential expiry derived from the key or issue time.
	ExpiresAt time.Time `json:"expires_at"`
}

Credential is a LiteLLM API key and its non-secret metadata.

func (Credential) AuthorizationHeader

func (c Credential) AuthorizationHeader() string

AuthorizationHeader returns c as a valid authorization header.

func (Credential) Clone

func (c Credential) Clone() Credential

Clone returns an independent credential copy.

func (Credential) Expiry

func (c Credential) Expiry() time.Time

Expiry returns the explicit, JWT, or compatibility expiry for c.

func (Credential) Fresh

func (c Credential) Fresh(now time.Time) bool

Fresh reports whether c is valid at now, with a small expiry safety margin.

func (Credential) GoString

func (c Credential) GoString() string

GoString returns a secret-free credential description.

func (Credential) String

func (Credential) String() string

String returns a secret-free credential description.

func (*Credential) UnmarshalJSON

func (c *Credential) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes a credential while rejecting invalid metadata.

func (Credential) Validate

func (c Credential) Validate() error

Validate checks token formatting and lifetime semantics without contacting a server.

type EnvSource

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

EnvSource reads a token from one environment variable on every call.

func NewEnvSource

func NewEnvSource(name string, config SourceConfig) (*EnvSource, error)

NewEnvSource creates an environment credential source.

func (*EnvSource) Credential

func (s *EnvSource) Credential(ctx context.Context) (Credential, error)

Credential reads and validates the current environment value.

func (*EnvSource) GoString

func (s *EnvSource) GoString() string

GoString returns a secret-free description.

func (*EnvSource) String

func (s *EnvSource) String() string

String returns a secret-free description.

type Event

type Event struct {
	// Kind identifies the event.
	Kind EventKind
	// Attempt is the one-based polling attempt number.
	Attempt int
	// StatusCode is set for HTTP retry events.
	StatusCode int
	// Teams is set when a team selection is required.
	Teams []Team
	// Err is set for retry events.
	Err error
}

Event reports login progress without exposing session secrets.

type EventKind

type EventKind string

EventKind identifies a login progress event.

const (
	// EventPending reports a pending poll response.
	EventPending EventKind = "pending"
	// EventRetrying reports a retryable polling failure.
	EventRetrying EventKind = "retrying"
	// EventTeamsRequired reports that the proxy requires a team selection.
	EventTeamsRequired EventKind = "teams_required"
)

type ExecSource

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

ExecSource executes one helper without a shell.

func NewExecSource

func NewExecSource(path string, args []string, config ExecSourceConfig) (*ExecSource, error)

NewExecSource creates an external-command source.

func (*ExecSource) Credential

func (s *ExecSource) Credential(ctx context.Context) (Credential, error)

Credential executes and parses the helper.

func (*ExecSource) GoString

func (s *ExecSource) GoString() string

GoString returns a secret-free description.

func (*ExecSource) String

func (*ExecSource) String() string

String returns a secret-free description.

type ExecSourceConfig

type ExecSourceConfig struct {
	BaseURL        string
	Timeout        time.Duration
	MaxOutputBytes int
	AllowedEnv     []string
}

ExecSourceConfig configures an external credential helper.

type HTTPError

type HTTPError struct {
	// Op is the SSO operation that returned the response.
	Op string
	// StatusCode is the HTTP status code.
	StatusCode int
	// Detail is safe response detail when supplied by the proxy.
	Detail string
	// Retryable reports whether the request can be retried.
	Retryable bool
	// contains filtered or unexported fields
}

HTTPError describes a non-successful LiteLLM CLI SSO response.

func (HTTPError) Error

func (e HTTPError) Error() string

Error returns a safe summary of the HTTP error.

func (HTTPError) GoString

func (e HTTPError) GoString() string

GoString returns a safe summary of the HTTP error.

func (HTTPError) Is

func (e HTTPError) Is(target error) bool

Is matches HTTP errors by operation, status code, and retryability.

func (HTTPError) SafeDetail

func (e HTTPError) SafeDetail() string

SafeDetail returns explicitly recognized, safe proxy guidance.

func (HTTPError) Unwrap

func (e HTTPError) Unwrap() error

Unwrap returns ErrLoginExpired for expired login sessions.

type LoginTimeoutError

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

LoginTimeoutError reports a session timeout.

func (LoginTimeoutError) Error

func (LoginTimeoutError) Error() string

Error returns the timeout message.

func (LoginTimeoutError) Unwrap

func (e LoginTimeoutError) Unwrap() []error

Unwrap returns the applicable timeout and expiry errors.

type Option

type Option func(*Client) error

Option configures a Client created by New.

func WithAllowInsecureHTTP

func WithAllowInsecureHTTP() Option

WithAllowInsecureHTTP permits non-loopback HTTP for development only.

func WithHTTPClient

func WithHTTPClient(client *http.Client) Option

WithHTTPClient uses client for LiteLLM requests.

func WithMaxWait

func WithMaxWait(wait time.Duration) Option

WithMaxWait limits the total duration of one login session.

func WithPollInterval

func WithPollInterval(interval time.Duration) Option

WithPollInterval sets the delay between pending polling requests.

func WithRequestTimeout

func WithRequestTimeout(timeout time.Duration) Option

WithRequestTimeout limits one HTTP request.

type PollResult

type PollResult struct {
	// Status is the polling status.
	Status PollStatus
	// Credential is set when Status is PollReady.
	Credential *Credential
	// Teams is the proxy-provided set of teams.
	Teams []Team
	// RequiresTeamSelection reports whether the proxy requires a team choice.
	RequiresTeamSelection bool
}

PollResult is the parsed result of one polling request.

type PollStatus

type PollStatus string

PollStatus describes a single LiteLLM CLI SSO polling result.

const (
	// PollPending means browser verification is not complete.
	PollPending PollStatus = "pending"
	// PollReady means a credential is ready.
	PollReady PollStatus = "ready"
	// PollTeamSelection means the caller must choose a team.
	PollTeamSelection PollStatus = "team_selection"
)

type SSOSource

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

SSOSource adapts the existing LiteLLM CLI SSO client to Source.

func NewSSOSource

func NewSSOSource(client *Client, options AuthenticateOptions) (*SSOSource, error)

NewSSOSource creates an SSO source.

func (*SSOSource) Credential

func (s *SSOSource) Credential(ctx context.Context) (Credential, error)

Credential authenticates through LiteLLM CLI SSO.

func (*SSOSource) GoString

func (s *SSOSource) GoString() string

GoString returns a secret-free description.

func (*SSOSource) Invalidate

func (s *SSOSource) Invalidate()

Invalidate clears the cached SSO credential.

func (*SSOSource) String

func (*SSOSource) String() string

String returns a secret-free description.

type Session

type Session struct {
	// LoginID identifies the session to the proxy.
	LoginID string
	// UserCode is shown to the user while completing browser verification.
	UserCode string
	// VerificationURL is the browser URL for the login session.
	VerificationURL *url.URL
	// ExpiresIn is the maximum duration for completing the login session.
	ExpiresIn time.Duration
	// contains filtered or unexported fields
}

Session is a short-lived browser login session. Its polling secret is never exported or serialized.

func (Session) GoString

func (s Session) GoString() string

GoString returns a secret-free session description.

func (Session) String

func (s Session) String() string

String returns a secret-free session description.

type Source

type Source interface {
	Credential(context.Context) (Credential, error)
}

Source acquires one authentication credential.

type SourceConfig

type SourceConfig struct {
	BaseURL     string
	AuthMethod  AuthMethod
	TokenType   string
	ExpiresAt   time.Time
	NonExpiring bool
	Issuer      string
	Subject     string
	Scopes      []string
}

SourceConfig supplies non-secret metadata and lifetime policy.

type SourceFunc

type SourceFunc func(context.Context) (Credential, error)

SourceFunc adapts a function to Source.

func (SourceFunc) Credential

func (f SourceFunc) Credential(ctx context.Context) (Credential, error)

Credential calls f.

type StaticSource

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

StaticSource returns one immutable configured credential.

func NewStaticSource

func NewStaticSource(key string, config SourceConfig) (*StaticSource, error)

NewStaticSource creates a static source.

func (*StaticSource) Credential

func (s *StaticSource) Credential(ctx context.Context) (Credential, error)

Credential returns an independent credential copy.

func (*StaticSource) GoString

func (s *StaticSource) GoString() string

GoString returns a secret-free description.

func (*StaticSource) String

func (*StaticSource) String() string

String returns a secret-free description.

type Team

type Team struct {
	// ID is the proxy's team identifier.
	ID string
	// Alias is the optional human-readable team name.
	Alias string
}

Team identifies a LiteLLM team available to a user.

type TeamRequiredError

type TeamRequiredError struct {
	// Teams is the proxy-provided set of selectable teams.
	Teams []Team
}

TeamRequiredError contains the teams offered by a login session.

func (TeamRequiredError) Error

func (e TeamRequiredError) Error() string

Error returns ErrTeamRequired's message.

func (TeamRequiredError) Unwrap

func (e TeamRequiredError) Unwrap() error

Unwrap returns ErrTeamRequired.

type TeamSelector

type TeamSelector func(context.Context, []Team) (string, error)

TeamSelector chooses one ID from the teams supplied by the proxy.

type TokenFileSource

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

TokenFileSource reads a rotating token file on every call.

func NewTokenFileSource

func NewTokenFileSource(path string, config SourceConfig) (*TokenFileSource, error)

NewTokenFileSource creates a rotating file source.

func (*TokenFileSource) Credential

func (s *TokenFileSource) Credential(ctx context.Context) (Credential, error)

Credential re-reads and validates the token file.

func (*TokenFileSource) GoString

func (s *TokenFileSource) GoString() string

GoString returns a secret-free description.

func (*TokenFileSource) String

func (*TokenFileSource) String() string

String returns a secret-free description.

Directories

Path Synopsis
cmd
litellm-auth command
examples
browser-login command
Command browser-login opens a LiteLLM browser login session.
Command browser-login opens a LiteLLM browser login session.
dual-auth command
Command dual-auth demonstrates a LiteLLM gateway key plus a delegated user token.
Command dual-auth demonstrates a LiteLLM gateway key plus a delegated user token.
manual-login command
Command manual-login prints a LiteLLM login URL for headless use.
Command manual-login prints a LiteLLM login URL for headless use.
use-token command
Command use-token loads a stored LiteLLM key into an HTTP transport.
Command use-token loads a stored LiteLLM key into an HTTP transport.
internal
cli
Package tokenstore securely persists LiteLLM credentials on disk.
Package tokenstore securely persists LiteLLM credentials on disk.

Jump to

Keyboard shortcuts

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