auth

package
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Jul 2, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AccessTokenFromContext

func AccessTokenFromContext(ctx context.Context) (string, bool)

AccessTokenFromContext retrieves the raw OAuth access token string stored by the auth middleware.

func ValidatePKCE

func ValidatePKCE(verifier, challenge, method string) bool

ValidatePKCE verifies that a code_verifier matches the stored code_challenge using the S256 method (SHA256 + base64url without padding) per RFC 7636.

func WithAccessToken

func WithAccessToken(ctx context.Context, token string) context.Context

WithAccessToken stores the raw OAuth access token in the given context.

func WithTokenInfo

func WithTokenInfo(ctx context.Context, info *IntrospectionResponse) context.Context

WithTokenInfo stores the IntrospectionResponse in the given context.

Types

type AuthorizationCode

type AuthorizationCode struct {
	Code            string
	ClientID        string
	RedirectURI     string
	CodeChallenge   string
	ChallengeMethod string
	ExpiresAt       time.Time
	ExternalToken   *ExternalToken
}

AuthorizationCode is created after successful authentication and holds the external token for exchange via the token endpoint.

type ExternalToken

type ExternalToken struct {
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token,omitempty"`
	TokenType    string `json:"token_type"`
	ExpiresIn    int    `json:"expires_in,omitempty"`
	Scope        string `json:"scope,omitempty"`
}

ExternalToken holds the token received from the upstream SSO provider.

type GenericProvider

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

GenericProvider implements the Provider interface for standard OAuth 2.0 / OIDC identity providers (Keycloak, Red Hat SSO, Okta, Azure AD, etc.). It uses the Authorization Code flow with token introspection (RFC 7662).

func NewGenericProvider

func NewGenericProvider(cfg *OAuthConfig) (*GenericProvider, error)

NewGenericProvider creates a provider from an OAuthConfig. Requires: ClientID, ClientSecret, AuthorizationURL, TokenURL, IntrospectionURL.

func (*GenericProvider) BuildAuthURL

func (p *GenericProvider) BuildAuthURL(callbackURL, state string) (string, error)

func (*GenericProvider) ExchangeCode

func (p *GenericProvider) ExchangeCode(ctx context.Context, code, callbackURL string) (*ExternalToken, error)

func (*GenericProvider) IntrospectToken

func (p *GenericProvider) IntrospectToken(ctx context.Context, token string) (*IntrospectionResponse, error)

func (*GenericProvider) RefreshToken

func (p *GenericProvider) RefreshToken(ctx context.Context, refreshToken string) (*ExternalToken, error)

type IntrospectionResponse

type IntrospectionResponse struct {
	Active    bool   `json:"active"`
	Sub       string `json:"sub,omitempty"`
	ClientID  string `json:"client_id,omitempty"`
	Username  string `json:"username,omitempty"`
	TokenType string `json:"token_type,omitempty"`
	Exp       int64  `json:"exp,omitempty"`
	Iat       int64  `json:"iat,omitempty"`
	Iss       string `json:"iss,omitempty"`
	Scope     string `json:"scope,omitempty"`
}

IntrospectionResponse represents the OAuth 2.0 Token Introspection response per RFC 7662.

func TokenInfoFromContext

func TokenInfoFromContext(ctx context.Context) (*IntrospectionResponse, bool)

TokenInfoFromContext retrieves the IntrospectionResponse stored by the auth middleware.

type Middleware

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

Middleware validates OAuth Bearer tokens using a Provider for introspection.

func NewMiddleware

func NewMiddleware(provider Provider, logger *slog.Logger) *Middleware

NewMiddleware creates a new OAuth middleware that validates tokens by delegating introspection to the given Provider.

func (*Middleware) Authenticate

func (m *Middleware) Authenticate(next http.Handler) http.Handler

Authenticate returns HTTP middleware that validates OAuth Bearer tokens. Validated token info is stored in the request context and accessible via TokenInfoFromContext.

func (*Middleware) Close

func (m *Middleware) Close()

Close stops the background cache cleanup goroutine.

func (*Middleware) MetadataHandler

func (*Middleware) MetadataHandler() http.HandlerFunc

MetadataHandler serves OAuth Authorization Server Metadata (RFC 8414). All endpoints point to our server, which proxies authentication to the external SSO.

func (*Middleware) ProtectedResourceMetadataHandler

func (*Middleware) ProtectedResourceMetadataHandler() http.HandlerFunc

ProtectedResourceMetadataHandler serves OAuth Protected Resource Metadata (RFC 9728) at /.well-known/oauth-protected-resource. MCP clients use this to discover which authorization server to use for obtaining tokens.

type OAuthClient

type OAuthClient struct {
	ClientID                string   `json:"client_id"`
	ClientSecret            string   `json:"client_secret"`
	RedirectURIs            []string `json:"redirect_uris"`
	GrantTypes              []string `json:"grant_types"`
	ResponseTypes           []string `json:"response_types"`
	TokenEndpointAuthMethod string   `json:"token_endpoint_auth_method"`
}

OAuthClient represents a dynamically registered OAuth client (RFC 7591).

type OAuthConfig

type OAuthConfig struct {
	ClientID         string
	ClientSecret     string
	AuthorizationURL string
	TokenURL         string
	IntrospectionURL string
	CallbackURL      string
}

OAuthConfig holds OAuth configuration loaded from environment variables.

func NewOAuthConfigFromEnv

func NewOAuthConfigFromEnv() (*OAuthConfig, error)

NewOAuthConfigFromEnv creates an OAuthConfig from SSO_* environment variables.

type OAuthServer

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

OAuthServer implements the OAuth 2.1 Authorization Server endpoints that proxy authentication to an external provider via the Provider interface. MCP clients interact with these endpoints; actual user authentication is delegated to the Provider.

func NewOAuthServer

func NewOAuthServer(provider Provider, callbackURL string, store *OAuthStore, logger *slog.Logger) *OAuthServer

NewOAuthServer creates a new OAuth authorization server. callbackURL is our server's /auth/callback/oidc endpoint URL that the external SSO will redirect to after user authentication.

func (*OAuthServer) HandleAuthorize

func (s *OAuthServer) HandleAuthorize(w http.ResponseWriter, r *http.Request)

HandleAuthorize implements the Authorization Endpoint (RFC 6749 Section 3.1). Validates the request, stores a pending authorization with a CSRF token, then redirects to the external provider for user authentication. The authorization code is only generated after successful authentication in HandleCallback. GET /auth/authorize

func (*OAuthServer) HandleCallback

func (s *OAuthServer) HandleCallback(w http.ResponseWriter, r *http.Request)

HandleCallback handles the redirect from the external provider after user authentication. It verifies the CSRF token, exchanges the provider's code for a token, generates an authorization code, and redirects back to the MCP client. GET /auth/callback/oidc

func (*OAuthServer) HandleComplete

func (s *OAuthServer) HandleComplete(w http.ResponseWriter, r *http.Request)

HandleComplete serves the post-authentication success page at a clean URL with no OAuth parameters exposed. It renders a meta-refresh redirect to the MCP client's redirect_uri. GET /auth/complete/{token}

func (*OAuthServer) HandleRegister

func (s *OAuthServer) HandleRegister(w http.ResponseWriter, r *http.Request)

HandleRegister implements Dynamic Client Registration (RFC 7591). POST /auth/register

func (*OAuthServer) HandleToken

func (s *OAuthServer) HandleToken(w http.ResponseWriter, r *http.Request)

HandleToken implements the Token Endpoint (RFC 6749 Section 3.2). Supports authorization_code (with PKCE) and refresh_token grant types. POST /auth/token

type OAuthStore

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

OAuthStore provides in-memory storage for OAuth clients, pending authorizations, authorization codes, and completion redirects.

func NewOAuthStore

func NewOAuthStore() *OAuthStore

NewOAuthStore creates a new in-memory OAuth store with a background cleanup goroutine that evicts expired pending authorizations and codes.

func (*OAuthStore) Close

func (s *OAuthStore) Close()

Close stops the background cleanup goroutine.

func (*OAuthStore) ConsumeCode

func (s *OAuthStore) ConsumeCode(code string) (*AuthorizationCode, bool)

ConsumeCode atomically retrieves and removes an authorization code (single-use). Returns nil if the code is invalid, expired, or already consumed.

func (*OAuthStore) ConsumeCompletion

func (s *OAuthStore) ConsumeCompletion(token string) (string, bool)

ConsumeCompletion atomically retrieves and removes a completion redirect URL.

func (*OAuthStore) ConsumePending

func (s *OAuthStore) ConsumePending(csrfToken string) (*PendingAuthorization, bool)

ConsumePending atomically retrieves and removes a pending authorization.

func (*OAuthStore) CreateClient

func (s *OAuthStore) CreateClient(redirectURIs, grantTypes, responseTypes []string, authMethod string) *OAuthClient

CreateClient registers a new OAuth client with generated credentials.

func (*OAuthStore) GetClient

func (s *OAuthStore) GetClient(clientID string) (*OAuthClient, bool)

GetClient retrieves a registered client by ID.

func (*OAuthStore) StoreCode

func (s *OAuthStore) StoreCode(code *AuthorizationCode)

StoreCode saves an authorization code for later exchange.

func (*OAuthStore) StoreCompletion

func (s *OAuthStore) StoreCompletion(redirectURL string) string

StoreCompletion saves a redirect URL keyed by a short-lived token. Used to redirect from the callback to a clean URL before showing the success page.

func (*OAuthStore) StorePending

func (s *OAuthStore) StorePending(pa *PendingAuthorization)

StorePending saves a pending authorization keyed by its CSRF token.

type PendingAuthorization

type PendingAuthorization struct {
	CSRFToken       string
	ClientID        string
	RedirectURI     string
	CodeChallenge   string
	ChallengeMethod string
	OrigState       string
	ExpiresAt       time.Time
}

PendingAuthorization holds context for an in-flight OAuth authorize request. Keyed by CSRF token in the store; consumed when the SSO callback arrives.

type Provider

type Provider interface {
	// BuildAuthURL constructs the external authorization URL to redirect the user to.
	// callbackURL is our server's /auth/callback/oidc endpoint.
	// state is an opaque value passed through the redirect round-trip.
	BuildAuthURL(callbackURL, state string) (string, error)

	// ExchangeCode trades an authorization code received from the external provider
	// for an access token (and optionally a refresh token).
	ExchangeCode(ctx context.Context, code, callbackURL string) (*ExternalToken, error)

	// RefreshToken obtains a new access token using a refresh token.
	RefreshToken(ctx context.Context, refreshToken string) (*ExternalToken, error)

	// IntrospectToken validates an access token and returns its metadata.
	// Implementations may call an introspection endpoint (RFC 7662) or use
	// provider-specific validation (e.g. Google's tokeninfo).
	IntrospectToken(ctx context.Context, token string) (*IntrospectionResponse, error)
}

Provider abstracts the upstream OAuth identity provider. Each implementation (generic OIDC, Google, etc.) handles the provider-specific details of building auth URLs, exchanging codes, refreshing tokens, and introspecting tokens.

The OAuthServer and Middleware are provider-agnostic — they delegate all provider-specific work through this interface.

Jump to

Keyboard shortcuts

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