oauth

package
v0.2.12 Latest Latest
Warning

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

Go to latest
Published: Jun 20, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

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

View Source
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

func OpenBrowser(rawURL string) error

OpenBrowser opens the given URL in the user's default browser. Only http and https schemes are allowed.

Types

type AuthChallenge

type AuthChallenge struct {
	Realm            string
	ResourceMetadata string
}

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

type CallbackResult struct {
	Code  string
	State string
	Error string
}

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.

func (*Client) Login

func (c *Client) Login(ctx context.Context, serverURL string) error

Login performs browser-based OAuth login for the given MCP server URL. It probes the server, discovers OAuth metadata, starts a local callback server, opens the browser for user authentication, exchanges the authorization code, and stores the resulting token.

func (*Client) Logout

func (c *Client) Logout(serverURL string) error

Logout removes the stored token 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

func DiscoverMetadata(ctx context.Context, issuerURL string) (*Metadata, error)

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

type PKCEChallenge struct {
	Verifier        string
	Challenge       string
	ChallengeMethod string
}

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.

Jump to

Keyboard shortcuts

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