Documentation
¶
Overview ¶
Package oauth provides OAuth 2.0 authentication for remote MCP servers. It implements browser-based authorization code flow with PKCE, token storage, server probing, and OAuth metadata discovery.
Index ¶
- Constants
- func ClearMetadataCache()
- func OpenBrowser(rawURL string) error
- type AuthChallenge
- type CallbackResult
- type CallbackServer
- type Client
- type Metadata
- type PKCEChallenge
- type ProtectedResourceMetadata
- type StoredToken
- type Token
- type TokenStatus
- type TokenStore
- func (s *TokenStore) DeleteToken(serverURL string) error
- func (s *TokenStore) GetToken(serverURL string) *StoredToken
- func (s *TokenStore) GetValidToken(serverURL string) *StoredToken
- func (s *TokenStore) HasValidToken(serverURL string) bool
- func (s *TokenStore) ListTokens() ([]TokenStatus, error)
- func (s *TokenStore) StoreToken(serverURL, issuerURL string, token Token) error
Constants ¶
const ( // DefaultClientIDMetadataURL is the CIMD URL hosted on GitHub Pages. // Authorization servers that support Client ID Metadata Documents (CIMD) // will fetch this URL to validate client metadata (redirect URIs, etc.). DefaultClientIDMetadataURL = "https://giantswarm.github.io/klausctl/client.json" )
Variables ¶
This section is empty.
Functions ¶
func ClearMetadataCache ¶
func ClearMetadataCache()
ClearMetadataCache removes all cached metadata entries. Exported for testing.
func OpenBrowser ¶
OpenBrowser opens the given URL in the user's default browser. Only http and https schemes are allowed.
Types ¶
type AuthChallenge ¶
AuthChallenge represents parsed fields from a WWW-Authenticate: Bearer response header.
func ParseWWWAuthenticate ¶
func ParseWWWAuthenticate(header string) *AuthChallenge
ParseWWWAuthenticate extracts realm and resource_metadata from a WWW-Authenticate: Bearer response header value. It handles both quoted and unquoted parameter values, and is tolerant of extra whitespace.
Examples of supported formats:
Bearer realm="https://dex.example.com" Bearer realm="https://dex.example.com", resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource" Bearer realm="https://dex.example.com",resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource"
func ProbeServer ¶
func ProbeServer(ctx context.Context, serverURL string) (*AuthChallenge, error)
ProbeServer sends a HEAD request to the given MCP server URL and checks for a 401 Unauthorized response with a WWW-Authenticate: Bearer header. Returns nil if the server does not require authentication. Falls back to checking .well-known/oauth-protected-resource (RFC 9728) when the HEAD response lacks a WWW-Authenticate header.
type CallbackResult ¶
CallbackResult holds the authorization code or error received from the OAuth callback.
type CallbackServer ¶
type CallbackServer struct {
// contains filtered or unexported fields
}
CallbackServer listens on 127.0.0.1:3001 for a single OAuth callback, then shuts down automatically.
func NewCallbackServer ¶
func NewCallbackServer(expectedState string) *CallbackServer
NewCallbackServer creates a callback server that validates the state parameter against expectedState.
func (*CallbackServer) Start ¶
func (cs *CallbackServer) Start() (string, error)
Start begins listening for the OAuth callback. Returns the full callback URL that should be registered as the redirect_uri.
func (*CallbackServer) WaitForCallback ¶
func (cs *CallbackServer) WaitForCallback(ctx context.Context) (CallbackResult, error)
WaitForCallback blocks until the OAuth callback is received or the context is cancelled. Shuts down the server before returning.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client orchestrates the full OAuth authorization code flow with PKCE.
func NewClient ¶
func NewClient(store *TokenStore) *Client
NewClient creates a Client backed by the given TokenStore.
func (*Client) AuthStatus ¶
func (c *Client) AuthStatus(serverURL string) TokenStatus
AuthStatus returns the token status for the given server URL.
type Metadata ¶
type Metadata struct {
Issuer string `json:"issuer"`
AuthorizationEndpoint string `json:"authorization_endpoint"`
TokenEndpoint string `json:"token_endpoint"`
ScopesSupported []string `json:"scopes_supported,omitempty"`
CodeChallengeSupported []string `json:"code_challenge_methods_supported,omitempty"`
}
Metadata holds OAuth authorization server metadata from RFC 8414 (.well-known/oauth-authorization-server) or OpenID Connect discovery (.well-known/openid-configuration).
func DiscoverMetadata ¶
DiscoverMetadata fetches OAuth authorization server metadata from the issuer URL. It tries RFC 8414 (.well-known/oauth-authorization-server) first, then falls back to OpenID Connect discovery (.well-known/openid-configuration). Results are cached with a 10-minute TTL.
type PKCEChallenge ¶
PKCEChallenge holds a PKCE verifier/challenge pair for the S256 method.
func GeneratePKCE ¶
func GeneratePKCE() PKCEChallenge
GeneratePKCE creates a new PKCE verifier/challenge pair using the S256 method. Uses golang.org/x/oauth2's cryptographically secure implementation.
type ProtectedResourceMetadata ¶
type ProtectedResourceMetadata struct {
Resource string `json:"resource"`
AuthorizationServers []string `json:"authorization_servers"`
BearerMethods []string `json:"bearer_methods_supported,omitempty"`
}
ProtectedResourceMetadata holds RFC 9728 OAuth Protected Resource Metadata fetched from .well-known/oauth-protected-resource.
func FetchResourceMetadata ¶
func FetchResourceMetadata(ctx context.Context, metadataURL string) (*ProtectedResourceMetadata, error)
FetchResourceMetadata fetches RFC 9728 OAuth Protected Resource Metadata from the given URL. This is used when a server's WWW-Authenticate header contains resource_metadata instead of realm.
type StoredToken ¶
type StoredToken struct {
Token Token `json:"token"`
Issuer string `json:"issuer"`
ServerURL string `json:"server_url"`
CreatedAt time.Time `json:"created_at"`
}
StoredToken wraps a Token with metadata needed for storage and refresh.
func (*StoredToken) IsExpired ¶
func (st *StoredToken) IsExpired() bool
IsExpired reports whether the access token has expired based on the stored creation time and expires_in value. Returns false when no expiry information is available (treat as non-expiring).
type Token ¶
type Token struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
RefreshToken string `json:"refresh_token,omitempty"`
ExpiresIn int `json:"expires_in,omitempty"`
}
Token holds the raw OAuth token fields returned by the authorization server.
type TokenStatus ¶
type TokenStatus struct {
ServerURL string
Issuer string
Status string // "valid", "expired", "none"
ExpiresAt string // RFC3339 or empty
}
TokenStatus describes the authentication state for a server.
type TokenStore ¶
type TokenStore struct {
// contains filtered or unexported fields
}
TokenStore manages OAuth tokens persisted as JSON files keyed by server URL. Each server gets a file at <dir>/<url-safe-hash>.json with 0600 permissions.
func NewTokenStore ¶
func NewTokenStore(dir string) *TokenStore
NewTokenStore creates a TokenStore backed by the given directory. The directory is created on first write if it does not exist.
func (*TokenStore) DeleteToken ¶
func (s *TokenStore) DeleteToken(serverURL string) error
DeleteToken removes the stored token for the given server URL.
func (*TokenStore) GetToken ¶
func (s *TokenStore) GetToken(serverURL string) *StoredToken
GetToken retrieves the stored token for the given server URL. Returns nil if no token is stored.
func (*TokenStore) GetValidToken ¶
func (s *TokenStore) GetValidToken(serverURL string) *StoredToken
GetValidToken retrieves a non-expired token for the server URL. Returns nil if no token is stored or the token has expired.
func (*TokenStore) HasValidToken ¶
func (s *TokenStore) HasValidToken(serverURL string) bool
HasValidToken reports whether a non-expired token exists for the server.
func (*TokenStore) ListTokens ¶
func (s *TokenStore) ListTokens() ([]TokenStatus, error)
ListTokens returns the status of all stored tokens sorted by server URL.
func (*TokenStore) StoreToken ¶
func (s *TokenStore) StoreToken(serverURL, issuerURL string, token Token) error
StoreToken persists a token for the given server and issuer URLs.