Documentation
¶
Overview ¶
Package oauth provides an OAuth 2.1 / OIDC authorization server library intended to back an MCP server, aligned with the MCP 2025-11-25 OAuth profile. It implements the Protected-Resource role (token validation + metadata) and the Authorization-Server role (authorize / token / revoke / introspect / register / userinfo / discovery endpoints).
Architecture ¶
The package is split into:
- github.com/giantswarm/mcp-oauth/server — the protocol engine (server.Server, state machines for the authorization-code flow, PKCE, refresh-token rotation, JWKS, introspection).
- github.com/giantswarm/mcp-oauth/providers — pluggable upstream IdP adapters (built-in: providers/dex, providers/google, providers/github).
- github.com/giantswarm/mcp-oauth/storage — persistence interfaces; in-tree backends in storage/memory and storage/valkey.
- github.com/giantswarm/mcp-oauth/security — primitives: security.Encryptor (AES-256-GCM at rest with KeyRing seam), security.Auditor, security.RateLimiter, scopes / WWW-Authenticate helpers.
- github.com/giantswarm/mcp-oauth/oauthconfig — env-driven loaders ([oauthconfig.FromEnv], [oauthconfig.NewEncryptorFromEnv]) for standard `OAUTH_*` environment variables.
- github.com/giantswarm/mcp-oauth/handler — the HTTP adapter ([handler.Handler]) that translates `*server.Server` into routes via [handler.Handler.RegisterOAuthRoutes] / [handler.Handler.RegisterProtectedResourceMetadataRoutes].
- This root package — protocol-level types (Error, TokenResponse, ProtectedResourceMetadata, …) and thin re-exports / convenience constructors for server.Server (NewServer, …).
Security defaults ¶
Library defaults aim for spec-compliant secure-by-default behaviour:
- PKCE required; only S256 accepted (RFC 7636 + OAuth 2.1).
- Refresh-token rotation on; reuse detection revokes the family.
- `state` parameter required and length-bounded (configurable via server.Config.MinStateLength / server.Config.MaxStateLength).
- Per-IP and per-user rate limiters guard hot endpoints.
- Bearer-token comparisons are constant-time.
- Token-at-rest encryption available via security.NewEncryptor + [memory.WithEncryptor] / [valkey.WithEncryptor]; the ciphertext envelope is versioned with a 1-byte `kid` for future rotation.
- OIDC `nonce` is required end-to-end when scoped `openid` (CWE-294).
- SSRF protection on the client-metadata-document and discovery fetchers.
Insecure opt-outs (e.g. server.Config.AllowNoStateParameter, server.Config.AllowInsecureHTTP) emit a startup WARN.
Compliance ¶
Implemented:
- RFC 6749 (OAuth 2.0 / OAuth 2.1 draft)
- RFC 6750 (Bearer token usage + WWW-Authenticate)
- RFC 7009 (Token revocation)
- RFC 7517 / 7518 / 7519 (JWS / JWA / JWT) via go-jose/v4
- RFC 7591 (Dynamic Client Registration; response includes `client_id_issued_at`, `client_secret_expires_at`)
- RFC 7636 (PKCE — S256 only)
- RFC 7662 (Token introspection §2.2 shape + cross-client gate)
- RFC 8414 (Authorization Server Metadata + Cache-Control)
- RFC 8707 (Resource indicators + audience binding)
- RFC 9068 (JWT-profile access tokens)
- RFC 9207 (`iss` response parameter)
- RFC 9728 (Protected Resource Metadata)
- OIDC Core 1.0 §3 + §5.3 (`/userinfo`)
- OIDC Discovery 1.0 §3 (subject_types_supported, id_token_signing_alg_values_supported, claims_supported)
Example ¶
A minimal in-memory server using the Google provider, encryption-at-rest from environment, and the standard `OAUTH_*` env loader. See the `examples/` directory for full end-to-end programs.
package main
import (
"log"
"log/slog"
"net/http"
"os"
"github.com/giantswarm/mcp-oauth/handler"
"github.com/giantswarm/mcp-oauth/oauthconfig"
"github.com/giantswarm/mcp-oauth/providers/google"
"github.com/giantswarm/mcp-oauth/server"
"github.com/giantswarm/mcp-oauth/storage/memory"
)
func main() {
cfg, err := oauthconfig.FromEnv()
if err != nil {
log.Fatal(err)
}
enc, err := oauthconfig.NewEncryptorFromEnv()
if err != nil {
log.Fatal(err)
}
provider, err := google.NewProvider(&google.Config{
ClientID: os.Getenv("GOOGLE_CLIENT_ID"),
ClientSecret: os.Getenv("GOOGLE_CLIENT_SECRET"),
RedirectURL: cfg.Issuer + "/oauth/callback",
})
if err != nil {
log.Fatal(err)
}
store := memory.New(memory.WithEncryptor(enc))
srv, err := server.New(provider, store, store, store, cfg, slog.Default())
if err != nil {
log.Fatal(err)
}
h := handler.New(srv, slog.Default())
mux := http.NewServeMux()
h.RegisterOAuthRoutes(mux, handler.OAuthRoutesOptions{IncludeMetadata: true})
mux.Handle("/mcp", h.ValidateToken(mcpHandler))
log.Fatal(http.ListenAndServe(":8080", mux))
}
The library does not provide MCP itself — `mcpHandler` is whatever your MCP transport exposes. The OAuth layer protects it via [handler.Handler.ValidateToken], which extracts the bearer token, validates it against the configured provider (or self-issued JWT in JWT-AT mode), and stashes the resolved providers.UserInfo in the request context for [handler.UserInfoFromContext].
Index ¶
- Constants
- Variables
- func IsSilentAuthError(err error) bool
- func ParseOAuthError(errorCode, errorDescription string) error
- type AuthorizationServerMetadata
- type CallbackResult
- type ClientRegistrationRequest
- type ClientRegistrationResponse
- type Error
- type ErrorResponse
- type ForwardedIDTokenAcceptance
- type OAuthErrordeprecated
- type ProtectedResourceMetadata
- type Server
- type ServerConfig
- type ServerOption
- func WithAuditor(aud *security.Auditor) ServerOption
- func WithClientRegistrationRateLimiter(rl *security.ClientRegistrationRateLimiter) ServerOption
- func WithInstrumentation(inst *instrumentation.Instrumentation) ServerOption
- func WithMetadataFetchRateLimiter(rl *security.RateLimiter) ServerOption
- func WithRateLimiter(rl *security.RateLimiter) ServerOption
- func WithSecurityEventRateLimiter(rl *security.RateLimiter) ServerOption
- func WithSessionCreationHandler(h server.SessionCreationHandler) ServerOption
- func WithSessionRevocationHandler(h server.SessionRevocationHandler) ServerOption
- func WithTokenRefreshHandler(h server.TokenRefreshHandler) ServerOption
- func WithUserRateLimiter(rl *security.RateLimiter) ServerOption
- type SilentAuthError
- type TokenResponse
Constants ¶
const ( // DefaultRefreshTokenTTL is the default time-to-live for refresh tokens (90 days) DefaultRefreshTokenTTL = 90 * 24 * time.Hour // DefaultAuthorizationCodeTTL is how long authorization codes are valid (10 minutes) DefaultAuthorizationCodeTTL = 10 * time.Minute // DefaultAccessTokenTTL is the default access token expiry (1 hour) DefaultAccessTokenTTL = 1 * time.Hour // DefaultCleanupInterval is how often to cleanup expired tokens (1 minute) DefaultCleanupInterval = 1 * time.Minute // DefaultRateLimitCleanupInterval is how often to cleanup inactive rate limiters DefaultRateLimitCleanupInterval = 5 * time.Minute // InactiveLimiterCleanupWindow is the time after which inactive limiters are removed InactiveLimiterCleanupWindow = 10 * time.Minute // TokenRefreshThreshold is how soon before expiry to attempt token refresh TokenRefreshThreshold = 5 * time.Minute // TokenExpiringThreshold is the minimum time before a token is considered expiring TokenExpiringThreshold = 60 // seconds // ClockSkewGrace is the grace period (in seconds) for clock skew when // validating tokens this server issued — 5s handles typical NTP drift // without materially extending token lifetime. Upstream-issued tokens // (forwarded id_tokens, JWKS-verified IdP tokens) use a larger leeway // because cross-organisation NTP skew is harder to bound; see // [github.com/giantswarm/mcp-oauth/providers/oidc.DefaultClockSkewLeeway] // (30s). ClockSkewGrace = 5 // seconds )
OAuth token and code timeouts
const ( // DefaultMaxClientsPerIP is the default limit for client registrations per IP DefaultMaxClientsPerIP = 10 // DefaultRateLimitRate is the default requests per second per IP DefaultRateLimitRate = 10 // DefaultRateLimitBurst is the default burst size for rate limiting DefaultRateLimitBurst = 20 // DefaultTokenEndpointAuthMethod is the default client authentication method DefaultTokenEndpointAuthMethod = "client_secret_basic" )
OAuth client and security defaults
const ( // ClientIDTokenLength is the length of generated client IDs ClientIDTokenLength = 32 // ClientSecretTokenLength is the length of generated client secrets ClientSecretTokenLength = 48 // AccessTokenLength is the length of generated access tokens AccessTokenLength = 48 // RefreshTokenLength is the length of generated refresh tokens RefreshTokenLength = 48 // StateTokenLength is the length of generated state parameters StateTokenLength = 32 // MinStateLength is the minimum length for state parameters to prevent // timing attacks and ensure sufficient entropy for CSRF protection. // OAuth 2.1 recommends at least 128 bits (16 bytes) of entropy. // 24 characters provides 144 bits of entropy in base64, exceeding the 128-bit minimum. // This value is used as the default for server.Config.MinStateLength. MinStateLength = 24 // MaxStateLength caps the `state` parameter length to prevent audit-log // inflation / DoS via oversized state values; 512 characters accommodates // the common JWT-encoded-state pattern (~256-380 chars). // This value is used as the default for server.Config.MaxStateLength. MaxStateLength = 512 )
PKCE and token generation constants
const ( // ClientTypeConfidential represents a confidential OAuth client ClientTypeConfidential = "confidential" // ClientTypePublic represents a public OAuth client ClientTypePublic = "public" )
OAuth client types
const ( // TokenEndpointAuthMethodNone represents no authentication (public clients) TokenEndpointAuthMethodNone = "none" // TokenEndpointAuthMethodBasic represents HTTP Basic authentication TokenEndpointAuthMethodBasic = "client_secret_basic" // TokenEndpointAuthMethodPost represents POST form parameters TokenEndpointAuthMethodPost = "client_secret_post" )
Token endpoint authentication methods (RFC 7591)
const ( // SchemeHTTP is the HTTP URI scheme SchemeHTTP = "http" // SchemeHTTPS is the HTTPS URI scheme SchemeHTTPS = "https" )
URI schemes
const ( // MetadataPathProtectedResource is the RFC 9728 Protected Resource Metadata discovery path MetadataPathProtectedResource = "/.well-known/oauth-protected-resource" // MetadataPathAuthorizationServer is the RFC 8414 Authorization Server Metadata discovery path MetadataPathAuthorizationServer = "/.well-known/oauth-authorization-server" // MaxMetadataPathLength is the maximum allowed length for custom metadata paths // This prevents DoS attacks through excessively long path registration MaxMetadataPathLength = 256 )
OAuth discovery paths (RFC 8414, RFC 9728)
const ( // MaxLoginHintLength is the maximum length for the login_hint parameter. // This is typically an email address (RFC 5321 limits to 254 chars). // We use 256 to accommodate edge cases and remain consistent with other ID limits. MaxLoginHintLength = 256 // MaxIDTokenHintLength is the maximum length for the id_token_hint parameter. // JWTs can be large (especially with many claims), so we allow up to 64KB. // This matches maxSubjectTokenLength used in token exchange flows. MaxIDTokenHintLength = 64 * 1024 // 64KB // MaxACRValuesLength is the maximum length for the acr_values parameter. // ACR values are typically short URNs, but can be space-separated lists. MaxACRValuesLength = 1024 // MaxPromptLength is the maximum length for the prompt parameter. // Valid values are "none", "login", "consent", "select_account" or combinations. // Even with all combined ("login consent select_account"), this is well under 100 chars. MaxPromptLength = 128 // MaxMaxAgeLength is the maximum length for the max_age parameter (in seconds). // This caps parsing work for untrusted input. MaxMaxAgeLength = 10 // MaxMaxAgeSeconds caps max_age to a reasonable window (31 days). // Values above this are ignored to reduce DoS risk from huge integers. MaxMaxAgeSeconds = 31 * 24 * 60 * 60 // MaxNonceLength is the maximum length for the OIDC `nonce` parameter. MaxNonceLength = 256 )
OIDC parameter validation constants (OpenID Connect Core 1.0 Section 3.1.2.1) These limits provide defense-in-depth against DoS attacks via oversized parameters.
Variables ¶
var ( // DangerousSchemes lists URI schemes that must never be allowed for security DangerousSchemes = []string{"javascript", "data", "file", "vbscript", "about"} // LoopbackAddresses lists recognized loopback addresses for development LoopbackAddresses = []string{"localhost", "127.0.0.1", "::1", "[::1]"} )
Redirect URI validation constants
var ( // DefaultGrantTypes are the grant types supported by default DefaultGrantTypes = []string{"authorization_code", "refresh_token"} // DefaultResponseTypes are the response types supported by default DefaultResponseTypes = []string{"code"} // SupportedCodeChallengeMethods are the PKCE methods we support // Security: Only S256 is allowed. "plain" method is insecure and violates OAuth 2.1 SupportedCodeChallengeMethods = []string{"S256"} // SupportedTokenAuthMethods are the supported token endpoint auth methods SupportedTokenAuthMethods = []string{"client_secret_basic", "client_secret_post", "none"} )
OAuth grant types and response types
var ( // ErrInvalidRequest indicates the request is malformed or missing required parameters ErrInvalidRequest = func(desc string) *Error { return NewError(constants.ErrorCodeInvalidRequest, desc, http.StatusBadRequest) } // ErrInvalidGrant indicates the authorization code or refresh token is invalid or expired ErrInvalidGrant = func(desc string) *Error { return NewError(constants.ErrorCodeInvalidGrant, desc, http.StatusBadRequest) } // ErrInvalidClient indicates client authentication failed ErrInvalidClient = func(desc string) *Error { return NewError(constants.ErrorCodeInvalidClient, desc, http.StatusUnauthorized) } // ErrInvalidScope indicates the requested scope is invalid or unsupported ErrInvalidScope = func(desc string) *Error { return NewError(constants.ErrorCodeInvalidScope, desc, http.StatusBadRequest) } // ErrInvalidToken indicates the access token is invalid or expired ErrInvalidToken = func(desc string) *Error { return NewError(constants.ErrorCodeInvalidToken, desc, http.StatusUnauthorized) } // ErrInsufficientScope indicates the access token lacks required scopes ErrInsufficientScope = func(desc string) *Error { return NewError(constants.ErrorCodeInsufficientScope, desc, http.StatusForbidden) } ErrUnauthorizedClient = func(desc string) *Error { return NewError(constants.ErrorCodeUnauthorizedClient, desc, http.StatusBadRequest) } // ErrUnsupportedGrantType indicates the grant type is not supported ErrUnsupportedGrantType = func(desc string) *Error { return NewError(constants.ErrorCodeUnsupportedGrantType, desc, http.StatusBadRequest) } // ErrServerError indicates an internal server error occurred ErrServerError = func(desc string) *Error { return NewError(constants.ErrorCodeServerError, desc, http.StatusInternalServerError) } // ErrAccessDenied indicates the user or authorization server denied the request ErrAccessDenied = func(desc string) *Error { return NewError(constants.ErrorCodeAccessDenied, desc, http.StatusForbidden) } // ErrInvalidRedirectURI indicates the redirect URI is invalid or not registered ErrInvalidRedirectURI = func(desc string) *Error { return NewError(constants.ErrorCodeInvalidRedirectURI, desc, http.StatusBadRequest) } )
Common OAuth errors as reusable instances
var ErrSilentAuthFailed = errors.New("silent authentication failed: user interaction required")
ErrSilentAuthFailed is a sentinel error for when silent authentication is not possible. This occurs when the IdP requires user interaction (login or consent) but the authorization request used prompt=none for silent authentication.
Use IsSilentAuthError to check if an error indicates silent auth failure.
var ErrTrustedAudienceMismatch = server.ErrTrustedAudienceMismatch
ErrTrustedAudienceMismatch is returned by [Server.AcceptForwardedIDToken] when the bearer token's `aud` claim does not match any entry in Config.TrustedAudiences. Callers typically respond with 401.
var NewOAuthError = NewError
NewOAuthError is an alias for NewError, provided for backward compatibility.
Deprecated: Use NewError instead. This alias will be removed in a future major version.
Functions ¶
func IsSilentAuthError ¶ added in v0.2.46
IsSilentAuthError returns true if the error indicates silent authentication failed and interactive login is required. This checks for:
- *SilentAuthError type (including wrapped errors)
- Error strings containing known silent auth error codes
Example usage:
result := handleCallback(r)
if err := result.Err(); err != nil {
if oauth.IsSilentAuthError(err) {
// Fall back to interactive login
return startInteractiveLogin(w, r)
}
// Handle other errors
return handleError(w, err)
}
func ParseOAuthError ¶ added in v0.2.46
ParseOAuthError parses an OAuth error response and returns the appropriate error type. For silent auth failure codes (login_required, consent_required, interaction_required, account_selection_required), returns a *SilentAuthError. For other errors, returns a generic *Error with the code and description. Returns nil if errorCode is empty.
Example usage:
err := oauth.ParseOAuthError(r.URL.Query().Get("error"), r.URL.Query().Get("error_description"))
if err != nil {
if oauth.IsSilentAuthError(err) {
// Handle silent auth failure
}
}
Types ¶
type AuthorizationServerMetadata ¶
type AuthorizationServerMetadata struct {
// Issuer is the authorization server's issuer identifier URL
Issuer string `json:"issuer"`
// AuthorizationEndpoint is the URL of the authorization endpoint
AuthorizationEndpoint string `json:"authorization_endpoint"`
// TokenEndpoint is the URL of the token endpoint
TokenEndpoint string `json:"token_endpoint"`
// RegistrationEndpoint is the URL of the dynamic client registration endpoint (RFC 7591)
RegistrationEndpoint string `json:"registration_endpoint,omitempty"`
// ScopesSupported lists the OAuth scopes supported
ScopesSupported []string `json:"scopes_supported,omitempty"`
// ResponseTypesSupported lists the OAuth response types supported
ResponseTypesSupported []string `json:"response_types_supported"`
// GrantTypesSupported lists the OAuth grant types supported
GrantTypesSupported []string `json:"grant_types_supported,omitempty"`
// TokenEndpointAuthMethodsSupported lists the client authentication methods supported at the token endpoint
TokenEndpointAuthMethodsSupported []string `json:"token_endpoint_auth_methods_supported,omitempty"`
// CodeChallengeMethodsSupported lists the PKCE code challenge methods supported
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported,omitempty"`
// RevocationEndpoint is the URL of the OAuth 2.0 token revocation endpoint (RFC 7009)
RevocationEndpoint string `json:"revocation_endpoint,omitempty"`
// IntrospectionEndpoint is the URL of the OAuth 2.0 token introspection endpoint (RFC 7662)
IntrospectionEndpoint string `json:"introspection_endpoint,omitempty"`
// ClientIDMetadataDocumentSupported indicates support for Client ID Metadata Documents (MCP 2025-11-25)
ClientIDMetadataDocumentSupported bool `json:"client_id_metadata_document_supported,omitempty"`
// AuthorizationResponseIssParameterSupported indicates that this authorization
// server includes the `iss` parameter in authorization responses (RFC 9207),
// allowing clients talking to multiple authorization servers to detect mix-up
// attacks.
AuthorizationResponseIssParameterSupported bool `json:"authorization_response_iss_parameter_supported,omitempty"`
// ClaimsSupported lists the claim names this server may emit in id_tokens
// (OpenID Connect Discovery 1.0 §3).
ClaimsSupported []string `json:"claims_supported,omitempty"`
// SubjectTypesSupported lists the OIDC subject-identifier types this server
// supports (`public` only — pairwise sub is not implemented).
SubjectTypesSupported []string `json:"subject_types_supported,omitempty"`
// IDTokenSigningAlgValuesSupported lists JWS `alg` values the server may use
// to sign id_tokens. Required by OIDC Discovery 1.0 §3 even when the server
// does not issue id_tokens itself.
IDTokenSigningAlgValuesSupported []string `json:"id_token_signing_alg_values_supported,omitempty"`
}
AuthorizationServerMetadata represents OAuth 2.0 Authorization Server Metadata (RFC 8414)
type CallbackResult ¶ added in v0.2.46
type CallbackResult struct {
// Code is the authorization code from a successful authorization.
// Empty if the callback contains an error.
Code string
// State is the state parameter for CSRF validation.
// Should match the state sent in the authorization request.
State string
// Error is the OAuth error code if authorization failed.
// Common values: "access_denied", "login_required", "consent_required"
Error string
// ErrorDescription provides additional information about the error.
// Human-readable text describing the error.
ErrorDescription string
// ErrorURI points to a web page with error documentation.
ErrorURI string
}
CallbackResult represents the result of an OAuth authorization callback. It parses and holds the query parameters from the OAuth redirect.
The callback may contain either:
- Success: Code and State parameters
- Error: Error, ErrorDescription, and optionally ErrorURI parameters
Use Err() to get a typed error for error responses, including SilentAuthError for silent authentication failures.
func ParseCallbackQuery ¶ added in v0.2.46
func ParseCallbackQuery(code, state, errorCode, errorDescription, errorURI string) *CallbackResult
ParseCallbackQuery creates a CallbackResult from URL query parameters. This is a convenience function for parsing OAuth callback query strings.
Parameters:
- code: The authorization code (from "code" query param)
- state: The state parameter (from "state" query param)
- errorCode: The error code (from "error" query param)
- errorDescription: The error description (from "error_description" query param)
- errorURI: The error URI (from "error_uri" query param)
func (*CallbackResult) Err ¶ added in v0.2.46
func (r *CallbackResult) Err() error
Err returns an appropriate error for the callback result. For silent auth failures (login_required, consent_required, interaction_required, account_selection_required), returns a *SilentAuthError that can be detected with IsSilentAuthError(). Returns nil if no error occurred.
Example usage:
q := r.URL.Query()
result := ParseCallbackQuery(q.Get("code"), q.Get("state"), q.Get("error"), q.Get("error_description"), q.Get("error_uri"))
if err := result.Err(); err != nil {
if IsSilentAuthError(err) {
// Fall back to interactive login
return startInteractiveLogin(w, r)
}
return handleError(w, err)
}
// Process result.Code
func (*CallbackResult) IsError ¶ added in v0.2.46
func (r *CallbackResult) IsError() bool
IsError returns true if the callback contains an error. Use Err() to get the actual error with proper typing.
type ClientRegistrationRequest ¶
type ClientRegistrationRequest struct {
// RedirectURIs is the array of redirection URIs for use in redirect-based flows
RedirectURIs []string `json:"redirect_uris,omitempty"`
// TokenEndpointAuthMethod is the requested authentication method for the token endpoint
TokenEndpointAuthMethod string `json:"token_endpoint_auth_method,omitempty"`
// GrantTypes is the array of OAuth 2.0 grant types the client will use
GrantTypes []string `json:"grant_types,omitempty"`
// ResponseTypes is the array of OAuth 2.0 response types the client will use
ResponseTypes []string `json:"response_types,omitempty"`
// ClientName is the human-readable name of the client
ClientName string `json:"client_name,omitempty"`
// ClientURI is the URL of the client's home page
ClientURI string `json:"client_uri,omitempty"`
// Scope is the space-separated list of scope values
Scope string `json:"scope,omitempty"`
// ClientType indicates if this is a "public" or "confidential" client
// Public clients (mobile, SPA) can use "none" auth method
// Confidential clients (server-side) must use client_secret_basic or client_secret_post
ClientType string `json:"client_type,omitempty"`
}
ClientRegistrationRequest represents a dynamic client registration request
type ClientRegistrationResponse ¶
type ClientRegistrationResponse struct {
// ClientID is the unique client identifier
ClientID string `json:"client_id"`
// ClientSecret is the client secret (for confidential clients)
ClientSecret string `json:"client_secret,omitempty"`
// ClientIDIssuedAt is the time the client_id was issued
ClientIDIssuedAt int64 `json:"client_id_issued_at,omitempty"`
// ClientSecretExpiresAt is when the client_secret expires (0 = never)
ClientSecretExpiresAt int64 `json:"client_secret_expires_at,omitempty"`
// RedirectURIs is the array of redirection URIs
RedirectURIs []string `json:"redirect_uris,omitempty"`
// TokenEndpointAuthMethod is the authentication method for the token endpoint
TokenEndpointAuthMethod string `json:"token_endpoint_auth_method,omitempty"`
// GrantTypes is the array of OAuth 2.0 grant types
GrantTypes []string `json:"grant_types,omitempty"`
// ResponseTypes is the array of OAuth 2.0 response types
ResponseTypes []string `json:"response_types,omitempty"`
// ClientName is the human-readable name of the client
ClientName string `json:"client_name,omitempty"`
// Scope is the space-separated list of scope values
Scope string `json:"scope,omitempty"`
// ClientType indicates if this is a "public" or "confidential" client
ClientType string `json:"client_type,omitempty"`
}
ClientRegistrationResponse represents a dynamic client registration response
type Error ¶ added in v0.2.24
type Error struct {
Code string // OAuth error code (e.g., "invalid_request", "invalid_grant")
Description string // Human-readable error description
Status int // HTTP status code
}
Error represents an OAuth 2.0 error response. This type implements the standard error interface and provides structured information about OAuth protocol errors.
type ErrorResponse ¶
type ErrorResponse struct {
// Error is the error code
Error string `json:"error"`
// ErrorDescription provides additional information
ErrorDescription string `json:"error_description,omitempty"`
// ErrorURI points to error documentation
ErrorURI string `json:"error_uri,omitempty"`
}
ErrorResponse represents an OAuth error response
type ForwardedIDTokenAcceptance ¶ added in v0.2.102
type ForwardedIDTokenAcceptance = server.ForwardedIDTokenAcceptance
ForwardedIDTokenAcceptance is the verified result of accepting a JWT forwarded from a trusted upstream identity provider.
type OAuthError
deprecated
type OAuthError = Error
OAuthError is an alias for Error, provided for backward compatibility.
Deprecated: Use Error instead. This alias will be removed in a future major version.
type ProtectedResourceMetadata ¶
type ProtectedResourceMetadata struct {
// Resource is the identifier for the protected resource
Resource string `json:"resource"`
// AuthorizationServers lists the authorization servers that can issue tokens for this resource
AuthorizationServers []string `json:"authorization_servers"`
// BearerMethodsSupported lists the ways Bearer tokens can be sent (RFC 6750)
BearerMethodsSupported []string `json:"bearer_methods_supported,omitempty"`
// ResourceSigningAlgValuesSupported lists supported signing algorithms
ResourceSigningAlgValuesSupported []string `json:"resource_signing_alg_values_supported,omitempty"`
// ScopesSupported lists the scopes understood by this resource
ScopesSupported []string `json:"scopes_supported,omitempty"`
}
ProtectedResourceMetadata represents OAuth 2.0 Protected Resource Metadata (RFC 9728)
type Server ¶
Server is the OAuth 2.1 authorization server. See server.Server.
func NewServer ¶
func NewServer( provider providers.Provider, tokenStore storage.TokenStore, clientStore storage.ClientStore, flowStore storage.FlowStore, config *ServerConfig, logger *slog.Logger, opts ...ServerOption, ) (*Server, error)
NewServer creates a new OAuth server. See server.New.
func NewServerWithCombined ¶ added in v0.2.108
func NewServerWithCombined( provider providers.Provider, store storage.Combined, config *ServerConfig, logger *slog.Logger, opts ...ServerOption, ) (*Server, error)
NewServerWithCombined is a convenience wrapper for server.NewWithCombined — the additive constructor that takes a storage.Combined backend instead of three separate store arguments. Use it when your backend (memory, valkey, or anything else) implements all three storage interfaces.
type ServerConfig ¶
ServerConfig is the OAuth server configuration. See server.Config.
type ServerOption ¶ added in v0.2.121
ServerOption configures a Server during construction. See server.Option.
func WithAuditor ¶ added in v0.2.121
func WithAuditor(aud *security.Auditor) ServerOption
WithAuditor configures the security auditor. See server.WithAuditor.
func WithClientRegistrationRateLimiter ¶ added in v0.2.121
func WithClientRegistrationRateLimiter(rl *security.ClientRegistrationRateLimiter) ServerOption
WithClientRegistrationRateLimiter configures the registration rate limiter. See server.WithClientRegistrationRateLimiter.
func WithInstrumentation ¶ added in v0.2.121
func WithInstrumentation(inst *instrumentation.Instrumentation) ServerOption
WithInstrumentation installs an OpenTelemetry pipeline on the server. Build it with instrumentation.New and pass it here. See server.WithInstrumentation.
func WithMetadataFetchRateLimiter ¶ added in v0.2.121
func WithMetadataFetchRateLimiter(rl *security.RateLimiter) ServerOption
WithMetadataFetchRateLimiter configures the per-domain rate limiter for client-metadata-document fetches. See server.WithMetadataFetchRateLimiter.
func WithRateLimiter ¶ added in v0.2.121
func WithRateLimiter(rl *security.RateLimiter) ServerOption
WithRateLimiter configures the IP-based rate limiter. See server.WithRateLimiter.
func WithSecurityEventRateLimiter ¶ added in v0.2.121
func WithSecurityEventRateLimiter(rl *security.RateLimiter) ServerOption
WithSecurityEventRateLimiter configures the rate limiter that bounds security-event log emission. See server.WithSecurityEventRateLimiter.
func WithSessionCreationHandler ¶ added in v0.2.121
func WithSessionCreationHandler(h server.SessionCreationHandler) ServerOption
WithSessionCreationHandler registers a callback that fires when a new token family is created. See server.WithSessionCreationHandler.
func WithSessionRevocationHandler ¶ added in v0.2.121
func WithSessionRevocationHandler(h server.SessionRevocationHandler) ServerOption
WithSessionRevocationHandler registers a callback that fires when a token family is revoked. See server.WithSessionRevocationHandler.
func WithTokenRefreshHandler ¶ added in v0.2.121
func WithTokenRefreshHandler(h server.TokenRefreshHandler) ServerOption
WithTokenRefreshHandler registers a callback that fires after a provider token is refreshed. See server.WithTokenRefreshHandler.
func WithUserRateLimiter ¶ added in v0.2.121
func WithUserRateLimiter(rl *security.RateLimiter) ServerOption
WithUserRateLimiter configures the user-based rate limiter for authenticated requests. See server.WithUserRateLimiter.
type SilentAuthError ¶ added in v0.2.46
type SilentAuthError struct {
// Code is the OAuth/OIDC error code.
// Common values: "login_required", "consent_required", "interaction_required"
Code string
// Description is the optional error description from the IdP
Description string
}
SilentAuthError represents an error from a silent authentication attempt. These errors indicate the IdP requires user interaction and the client should fall back to interactive login.
Silent authentication fails when:
- No active session at the IdP (login_required)
- User hasn't granted required scopes (consent_required)
- IdP needs user interaction for other reasons (interaction_required)
- Multiple accounts and none selected (account_selection_required)
See: https://openid.net/specs/openid-connect-core-1_0.html#AuthError
func (*SilentAuthError) Error ¶ added in v0.2.46
func (e *SilentAuthError) Error() string
Error implements the error interface.
type TokenResponse ¶
type TokenResponse struct {
// AccessToken is the access token
AccessToken string `json:"access_token"`
// TokenType is the type of token (always "Bearer")
TokenType string `json:"token_type"`
// ExpiresIn is the lifetime in seconds of the access token
ExpiresIn int64 `json:"expires_in,omitempty"`
// RefreshToken is the refresh token (optional)
RefreshToken string `json:"refresh_token,omitempty"`
// Scope is the scope of the access token
Scope string `json:"scope,omitempty"`
// IDToken is the OIDC ID token from the upstream provider (optional).
// Per OpenID Connect Core 1.0 Section 3.1.3.3, this is REQUIRED for OIDC flows.
// This enables clients to use id_token_hint and login_hint for silent re-authentication.
IDToken string `json:"id_token,omitempty"`
}
TokenResponse represents an OAuth 2.0 token response
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
basic
command
Package main demonstrates basic OAuth 2.1 setup for MCP servers.
|
Package main demonstrates basic OAuth 2.1 setup for MCP servers. |
|
cimd
command
Package main demonstrates Client ID Metadata Document (CIMD) verification.
|
Package main demonstrates Client ID Metadata Document (CIMD) verification. |
|
custom-scopes
command
Package main demonstrates OAuth setup with multiple Google API scopes.
|
Package main demonstrates OAuth setup with multiple Google API scopes. |
|
dex
command
Package main demonstrates OAuth setup with the Dex OIDC provider.
|
Package main demonstrates OAuth setup with the Dex OIDC provider. |
|
github
command
Package main demonstrates OAuth setup with the GitHub OAuth provider.
|
Package main demonstrates OAuth setup with the GitHub OAuth provider. |
|
jwt
command
Package main demonstrates the AccessTokenFormatJWT mode of mcp-oauth.
|
Package main demonstrates the AccessTokenFormatJWT mode of mcp-oauth. |
|
mcp-2025-11-25
command
Package main demonstrates MCP 2025-11-25 OAuth specification features.
|
Package main demonstrates MCP 2025-11-25 OAuth specification features. |
|
production
command
Package main demonstrates production-ready OAuth 2.1 setup for MCP servers.
|
Package main demonstrates production-ready OAuth 2.1 setup for MCP servers. |
|
prometheus
command
Package main demonstrates OAuth setup with Prometheus metrics.
|
Package main demonstrates OAuth setup with Prometheus metrics. |
|
Package instrumentation provides OpenTelemetry (OTEL) instrumentation for the mcp-oauth library.
|
Package instrumentation provides OpenTelemetry (OTEL) instrumentation for the mcp-oauth library. |
|
internal
|
|
|
constants
Package constants defines values shared between the root package and server/ to break the circular import that would arise from server importing the root (which already imports server for its type aliases).
|
Package constants defines values shared between the root package and server/ to break the circular import that would arise from server importing the root (which already imports server for its type aliases). |
|
helpers
Package helpers provides common utility functions used across the mcp-oauth library.
|
Package helpers provides common utility functions used across the mcp-oauth library. |
|
testutil
Package testutil provides testing utilities, mock implementations, and test fixtures for the mcp-oauth library.
|
Package testutil provides testing utilities, mock implementations, and test fixtures for the mcp-oauth library. |
|
Package oauthconfig loads mcp-oauth configuration from environment variables.
|
Package oauthconfig loads mcp-oauth configuration from environment variables. |
|
internal/valkeytls
Package valkeytls builds a *tls.Config for Valkey connections from a small set of feature-flag-shaped options.
|
Package valkeytls builds a *tls.Config for Valkey connections from a small set of feature-flag-shaped options. |
|
Package providers defines the OAuth provider interface and types for user information.
|
Package providers defines the OAuth provider interface and types for user information. |
|
dex
Package dex implements the OAuth provider interface for Dex (https://dexidp.io/).
|
Package dex implements the OAuth provider interface for Dex (https://dexidp.io/). |
|
github
Package github implements the OAuth provider interface for GitHub OAuth Apps.
|
Package github implements the OAuth provider interface for GitHub OAuth Apps. |
|
google
Package google provides a Google OAuth 2.0 provider implementation.
|
Package google provides a Google OAuth 2.0 provider implementation. |
|
mock
Package mock provides mock implementations of the Provider interface for testing purposes.
|
Package mock provides mock implementations of the Provider interface for testing purposes. |
|
oidc
Package oidc provides shared OpenID Connect client utilities for OAuth providers.
|
Package oidc provides shared OpenID Connect client utilities for OAuth providers. |
|
tokencache
Package tokencache provides a generic LRU-bounded token cache for short-lived access tokens.
|
Package tokencache provides a generic LRU-bounded token cache for short-lived access tokens. |
|
Package security provides security features for OAuth including encryption, rate limiting, audit logging, and secure header management.
|
Package security provides security features for OAuth including encryption, rate limiting, audit logging, and secure header management. |
|
Package server provides OAuth 2.1 authorization server implementation with MCP support
|
Package server provides OAuth 2.1 authorization server implementation with MCP support |
|
Package storage provides interfaces and utilities for OAuth token, client, and flow persistence.
|
Package storage provides interfaces and utilities for OAuth token, client, and flow persistence. |
|
memory
Package memory provides an in-memory implementation of the OAuth storage interfaces.
|
Package memory provides an in-memory implementation of the OAuth storage interfaces. |
|
mock
Package mock provides mock implementations of storage interfaces for testing purposes.
|
Package mock provides mock implementations of storage interfaces for testing purposes. |
|
valkey
Package valkey provides a Valkey storage backend for the mcp-oauth library.
|
Package valkey provides a Valkey storage backend for the mcp-oauth library. |