Documentation
¶
Index ¶
- func GeneratePKCEChallenge() (verifier, challenge string, err error)
- func SetLogger(l schemas.Logger)
- func ValidatePKCEChallenge(verifier, challenge string) bool
- type DynamicClientRegistrationRequest
- type DynamicClientRegistrationResponse
- type OAuth2Provider
- func (p *OAuth2Provider) BuildUpstreamAuthorizeURL(ctx context.Context, flowID string) (string, error)
- func (p *OAuth2Provider) CompleteOAuthFlow(ctx context.Context, state, code string) error
- func (p *OAuth2Provider) CompleteUserOAuthFlow(ctx context.Context, state string, code string) (string, error)
- func (p *OAuth2Provider) GetAccessToken(ctx context.Context, oauthConfigID string) (string, error)
- func (p *OAuth2Provider) GetPendingMCPClient(oauthConfigID string) (*schemas.MCPClientConfig, error)
- func (p *OAuth2Provider) GetPendingMCPClientByState(state string) (*schemas.MCPClientConfig, string, error)
- func (p *OAuth2Provider) GetUserAccessTokenByMode(ctx context.Context, mode schemas.MCPAuthMode, identity, mcpClientID string) (string, error)
- func (p *OAuth2Provider) InitiateOAuthFlow(ctx context.Context, config *schemas.OAuth2Config) (*schemas.OAuth2FlowInitiation, error)
- func (p *OAuth2Provider) InitiateUserOAuthFlow(ctx context.Context, oauthConfigID string, mcpClientID string, ...) (*schemas.OAuth2FlowInitiation, string, error)
- func (p *OAuth2Provider) RefreshAccessToken(ctx context.Context, oauthConfigID string) error
- func (p *OAuth2Provider) RefreshUserAccessToken(ctx context.Context, tokenID string) error
- func (p *OAuth2Provider) RemovePendingMCPClient(oauthConfigID string) error
- func (p *OAuth2Provider) RevokeToken(ctx context.Context, oauthConfigID string) error
- func (p *OAuth2Provider) SetTempTokenService(svc *temptoken.Service)
- func (p *OAuth2Provider) StorePendingMCPClient(oauthConfigID string, mcpClientConfig schemas.MCPClientConfig) error
- func (p *OAuth2Provider) ValidateToken(ctx context.Context, oauthConfigID string) (bool, error)
- type OAuthMetadata
- type PerUserOAuthSweepWorker
- type PermanentOAuthError
- type ResourceMetadata
- type TokenRefreshWorker
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GeneratePKCEChallenge ¶
GeneratePKCEChallenge generates code_verifier and code_challenge for PKCE (RFC 7636) Returns:
- verifier: Random 128-character string (stored securely, never sent to server)
- challenge: SHA256 hash of verifier, base64url encoded (sent in authorization request)
func ValidatePKCEChallenge ¶
ValidatePKCEChallenge validates that a code_verifier matches the expected code_challenge Used during testing or debugging
Types ¶
type DynamicClientRegistrationRequest ¶
type DynamicClientRegistrationRequest struct {
ClientName string `json:"client_name"`
RedirectURIs []string `json:"redirect_uris"`
GrantTypes []string `json:"grant_types"`
ResponseTypes []string `json:"response_types"`
TokenEndpointAuthMethod string `json:"token_endpoint_auth_method"`
Scope string `json:"scope,omitempty"`
LogoURI string `json:"logo_uri,omitempty"`
ClientURI string `json:"client_uri,omitempty"`
Contacts []string `json:"contacts,omitempty"`
}
DynamicClientRegistrationRequest represents the client registration request (RFC 7591)
type DynamicClientRegistrationResponse ¶
type DynamicClientRegistrationResponse struct {
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret,omitempty"`
ClientIDIssuedAt int64 `json:"client_id_issued_at,omitempty"`
ClientSecretExpiresAt int64 `json:"client_secret_expires_at,omitempty"`
RegistrationAccessToken string `json:"registration_access_token,omitempty"`
RegistrationClientURI string `json:"registration_client_uri,omitempty"`
}
DynamicClientRegistrationResponse represents the server's response (RFC 7591)
func RegisterDynamicClient ¶
func RegisterDynamicClient(ctx context.Context, registrationURL string, req *DynamicClientRegistrationRequest) (*DynamicClientRegistrationResponse, error)
RegisterDynamicClient performs dynamic client registration with the OAuth provider (RFC 7591) This allows Bifrost to automatically register as an OAuth client without manual setup.
Parameters:
- ctx: Context for the registration request
- registrationURL: The registration endpoint (discovered or user-provided)
- req: Client registration details
Returns client_id and optional client_secret that can be used for OAuth flows.
type OAuth2Provider ¶
type OAuth2Provider struct {
// contains filtered or unexported fields
}
OAuth2Provider implements the schemas.OAuth2Provider interface It provides OAuth 2.0 authentication functionality with database persistence
func NewOAuth2Provider ¶
func NewOAuth2Provider(configStore configstore.ConfigStore, logger schemas.Logger) *OAuth2Provider
NewOAuth2Provider creates a new OAuth provider instance
func (*OAuth2Provider) BuildUpstreamAuthorizeURL ¶ added in v1.3.11
func (p *OAuth2Provider) BuildUpstreamAuthorizeURL(ctx context.Context, flowID string) (string, error)
BuildUpstreamAuthorizeURL reconstructs the upstream provider authorization URL for a pending per-user OAuth flow. Called by the frontend sessions tab when the user clicks "Authenticate" — at which point the flow row already exists (from a prior InitiateUserOAuthFlow), the CSRF state + PKCE verifier are stored on it, and we just need to hand the user the upstream redirect.
The code_challenge is recomputed deterministically from the stored verifier so we don't have to persist it separately.
func (*OAuth2Provider) CompleteOAuthFlow ¶
func (p *OAuth2Provider) CompleteOAuthFlow(ctx context.Context, state, code string) error
CompleteOAuthFlow handles the OAuth callback and exchanges code for tokens Supports PKCE verification
func (*OAuth2Provider) CompleteUserOAuthFlow ¶ added in v1.3.1
func (p *OAuth2Provider) CompleteUserOAuthFlow(ctx context.Context, state string, code string) (string, error)
CompleteUserOAuthFlow handles the OAuth callback for a per-user flow. It looks up the session by state, exchanges code for tokens, and returns a session token.
func (*OAuth2Provider) GetAccessToken ¶
GetAccessToken retrieves the access token for a given oauth_config_id
func (*OAuth2Provider) GetPendingMCPClient ¶
func (p *OAuth2Provider) GetPendingMCPClient(oauthConfigID string) (*schemas.MCPClientConfig, error)
GetPendingMCPClient retrieves an MCP client config by oauth_config_id Returns nil if no pending config is found or if the oauth config has expired
func (*OAuth2Provider) GetPendingMCPClientByState ¶
func (p *OAuth2Provider) GetPendingMCPClientByState(state string) (*schemas.MCPClientConfig, string, error)
GetPendingMCPClientByState retrieves an MCP client config by OAuth state token This is useful when the callback only has the state parameter
func (*OAuth2Provider) GetUserAccessTokenByMode ¶ added in v1.3.11
func (p *OAuth2Provider) GetUserAccessTokenByMode(ctx context.Context, mode schemas.MCPAuthMode, identity, mcpClientID string) (string, error)
GetUserAccessTokenByMode retrieves the upstream access token using exactly one identity column determined by mode. No fallback chain. Filters status='active' so orphaned rows never satisfy a lookup.
func (*OAuth2Provider) InitiateOAuthFlow ¶
func (p *OAuth2Provider) InitiateOAuthFlow(ctx context.Context, config *schemas.OAuth2Config) (*schemas.OAuth2FlowInitiation, error)
InitiateOAuthFlow creates an OAuth config and returns the authorization URL Supports OAuth discovery and PKCE
func (*OAuth2Provider) InitiateUserOAuthFlow ¶ added in v1.3.1
func (p *OAuth2Provider) InitiateUserOAuthFlow(ctx context.Context, oauthConfigID string, mcpClientID string, redirectURI string, flowMode schemas.MCPAuthMode) (*schemas.OAuth2FlowInitiation, string, error)
InitiateUserOAuthFlow creates or refreshes the per-user OAuth flow row for a given (mode, identity, mcp_client) binding and returns the auth landing URL.
Determinism: there is exactly one flow row per binding. If one already exists (from a prior auth attempt), it's updated in place — fresh CSRF state, fresh PKCE verifier, status reset to 'pending'. Otherwise a new row is inserted. Reauth never duplicates rows; revoke deletes them.
The function errors out cleanly on any misconfig (missing identity, unknown mode, missing template config) — no fallbacks, no generated identities.
func (*OAuth2Provider) RefreshAccessToken ¶
func (p *OAuth2Provider) RefreshAccessToken(ctx context.Context, oauthConfigID string) error
RefreshAccessToken refreshes the access token for a given oauth_config_id
func (*OAuth2Provider) RefreshUserAccessToken ¶ added in v1.3.1
func (p *OAuth2Provider) RefreshUserAccessToken(ctx context.Context, tokenID string) error
RefreshUserAccessToken refreshes a per-user OAuth access token, looked up by the token row's primary-key ID.
func (*OAuth2Provider) RemovePendingMCPClient ¶
func (p *OAuth2Provider) RemovePendingMCPClient(oauthConfigID string) error
RemovePendingMCPClient clears the pending MCP client config from the oauth config This is called after OAuth completion to clean up
func (*OAuth2Provider) RevokeToken ¶
func (p *OAuth2Provider) RevokeToken(ctx context.Context, oauthConfigID string) error
RevokeToken revokes the OAuth token
func (*OAuth2Provider) SetTempTokenService ¶ added in v1.3.11
func (p *OAuth2Provider) SetTempTokenService(svc *temptoken.Service)
SetTempTokenService installs the temp-token service used by InitiateUserOAuthFlow to mint the mcp_auth token embedded in the auth-page URL fragment. Called by server startup once both services have been constructed (the provider is built first by lib/config.go, the service later by the HTTP transport).
func (*OAuth2Provider) StorePendingMCPClient ¶
func (p *OAuth2Provider) StorePendingMCPClient(oauthConfigID string, mcpClientConfig schemas.MCPClientConfig) error
StorePendingMCPClient stores an MCP client config that's waiting for OAuth completion The config is persisted in the database (oauth_configs.mcp_client_config_json) to support multi-instance deployments where OAuth callback may hit a different server instance.
func (*OAuth2Provider) ValidateToken ¶
ValidateToken checks if the token is still valid
type OAuthMetadata ¶
type OAuthMetadata struct {
AuthorizationURL string `json:"authorization_endpoint"`
TokenURL string `json:"token_endpoint"`
RegistrationURL *string `json:"registration_endpoint,omitempty"`
ScopesSupported []string `json:"scopes_supported,omitempty"`
Issuer string `json:"issuer,omitempty"`
ResponseTypes []string `json:"response_types_supported,omitempty"`
GrantTypes []string `json:"grant_types_supported,omitempty"`
TokenAuthMethods []string `json:"token_endpoint_auth_methods_supported,omitempty"`
PKCEMethods []string `json:"code_challenge_methods_supported,omitempty"`
}
OAuthMetadata contains discovered OAuth configuration from authorization server
func DiscoverOAuthMetadata ¶
func DiscoverOAuthMetadata(ctx context.Context, serverURL string) (*OAuthMetadata, error)
DiscoverOAuthMetadata performs OAuth 2.0 discovery for the given MCP server URL Following RFC 8414 (Authorization Server Discovery) and RFC 9728 (Protected Resource Metadata)
Parameters:
- ctx: Context for the discovery requests
- serverURL: The MCP server URL to discover OAuth configuration from
- logger: Logger for discovery progress (can be nil for silent operation)
The discovery process: 1. Attempt to connect to MCP server, expect 401 with WWW-Authenticate header 2. Parse WWW-Authenticate header for resource_metadata URL and scopes 3. Fetch resource metadata to get authorization server URLs 4. Try .well-known discovery if resource metadata is not available 5. Fetch authorization server metadata from discovered URLs 6. Return complete OAuth configuration
type PerUserOAuthSweepWorker ¶ added in v1.3.11
type PerUserOAuthSweepWorker struct {
// contains filtered or unexported fields
}
PerUserOAuthSweepWorker periodically purges stale per-user OAuth state:
- expired pending flow rows (oauth_user_sessions where ExpiresAt < now and status='pending')
- orphaned token rows older than OrphanRetention (oauth_user_tokens where status='orphaned')
Pending-flow expiry is short (driven by the row's own ExpiresAt, default 15min) so the flow tick is fast. Orphan retention is operator-tunable (default 30 days) and the orphan tick is slow.
func NewPerUserOAuthSweepWorker ¶ added in v1.3.11
func NewPerUserOAuthSweepWorker(provider *OAuth2Provider, orphanRetention time.Duration, logger schemas.Logger) *PerUserOAuthSweepWorker
NewPerUserOAuthSweepWorker creates a sweep worker with sensible defaults. orphanRetention <= 0 disables the orphan-token sweep.
func (*PerUserOAuthSweepWorker) SetFlowSweepInterval ¶ added in v1.3.11
func (w *PerUserOAuthSweepWorker) SetFlowSweepInterval(d time.Duration)
SetFlowSweepInterval updates the pending-flow sweep cadence (for testing). Non-positive durations are ignored — run() feeds the field straight into time.NewTicker, which panics on d <= 0.
func (*PerUserOAuthSweepWorker) SetOrphanSweepInterval ¶ added in v1.3.11
func (w *PerUserOAuthSweepWorker) SetOrphanSweepInterval(d time.Duration)
SetOrphanSweepInterval updates the orphan-token sweep cadence (for testing). Same non-positive guard as SetFlowSweepInterval.
func (*PerUserOAuthSweepWorker) Start ¶ added in v1.3.11
func (w *PerUserOAuthSweepWorker) Start(ctx context.Context)
Start begins the sweep worker in a background goroutine.
func (*PerUserOAuthSweepWorker) Stop ¶ added in v1.3.11
func (w *PerUserOAuthSweepWorker) Stop()
Stop gracefully stops the sweep worker. sync.Once guards against double-close panics when called from multiple shutdown paths.
type PermanentOAuthError ¶ added in v1.2.37
PermanentOAuthError indicates the OAuth provider rejected the request in a way that requires user re-authorization (e.g. revoked refresh token, invalid_grant). Distinct from transient network failures which should be retried.
func (*PermanentOAuthError) Error ¶ added in v1.2.37
func (e *PermanentOAuthError) Error() string
type ResourceMetadata ¶
type ResourceMetadata struct {
AuthorizationServers []string `json:"authorization_servers"`
ScopesSupported []string `json:"scopes_supported,omitempty"`
Scopes []string `json:"scopes,omitempty"` // Alternative field name
}
ResourceMetadata contains metadata from protected resource
type TokenRefreshWorker ¶
type TokenRefreshWorker struct {
// contains filtered or unexported fields
}
TokenRefreshWorker manages automatic token refresh for expiring OAuth tokens
func NewTokenRefreshWorker ¶
func NewTokenRefreshWorker(provider *OAuth2Provider, logger schemas.Logger) *TokenRefreshWorker
NewTokenRefreshWorker creates a new token refresh worker
func (*TokenRefreshWorker) SetLookAheadWindow ¶
func (w *TokenRefreshWorker) SetLookAheadWindow(window time.Duration)
SetLookAheadWindow updates the look-ahead window for token expiry (for testing)
func (*TokenRefreshWorker) SetRefreshInterval ¶
func (w *TokenRefreshWorker) SetRefreshInterval(interval time.Duration)
SetRefreshInterval updates the refresh check interval (for testing)
func (*TokenRefreshWorker) Start ¶
func (w *TokenRefreshWorker) Start(ctx context.Context)
Start begins the token refresh worker in a background goroutine
func (*TokenRefreshWorker) Stop ¶
func (w *TokenRefreshWorker) Stop()
Stop gracefully stops the token refresh worker. Safe to call multiple times — guarded by sync.Once so a redundant call from a secondary shutdown path can't panic by re-closing the channel.