Documentation
¶
Overview ¶
Package providers defines the OAuth provider interface and types for user information.
This package contains the Provider interface that must be implemented by all OAuth identity providers, as well as the UserInfo type that represents authenticated user data.
Interfaces ¶
Provider is the core interface that all OAuth identity providers must implement. It handles the complete OAuth flow including authorization, token exchange, validation, refresh, and revocation.
JWKSProvider is an optional interface for providers that support JWKS-based JWT validation. This enables SSO token forwarding where ID tokens from upstream servers can be validated via JWKS signature verification instead of calling the userinfo endpoint. Providers that implement this interface can participate in federated authentication scenarios.
Implementations ¶
Implementations are provided in subpackages:
- providers/google: Google OAuth 2.0 provider (implements JWKSProvider)
- providers/github: GitHub OAuth provider
- providers/dex: Dex OIDC provider (implements JWKSProvider, supports multiple connectors)
- providers/mock: Mock provider for testing (implements JWKSProvider)
- providers/oidc: Generic OIDC discovery and validation utilities
Provider Capabilities ¶
All Provider implementations handle:
- OAuth authorization URL generation with PKCE support
- Authorization code exchange
- Token validation and user info retrieval
- Token refresh
- Token revocation
- Health checks
JWKSProvider implementations additionally support:
- JWKS URI discovery for JWT signature verification
- Issuer URL for JWT issuer validation
Example Usage ¶
Basic provider usage:
provider, err := google.NewProvider(&google.Config{
ClientID: "your-client-id",
ClientSecret: "your-client-secret",
RedirectURL: "http://localhost:8080/oauth/callback",
})
if err != nil {
log.Fatal(err)
}
// Use provider with OAuth server
server, _ := oauth.NewServer(provider, tokenStore, clientStore, flowStore, config, logger)
SSO Token Forwarding ¶
When using TrustedAudiences with a JWKSProvider, the server can validate forwarded ID tokens from upstream MCP servers:
config := &server.Config{
TrustedAudiences: []string{"upstream-client-id"},
// ... other config
}
The server will:
- Check if the Bearer token is a JWT with a matching audience
- Validate the JWT signature using the provider's JWKS
- Extract user info from the validated ID token claims
Package providers defines the interface for OAuth identity providers and implements provider-specific logic for Google, GitHub, Microsoft, and other OAuth/OIDC providers.
Index ¶
- Constants
- func ApplyAuthorizationURLOptions(opts *AuthorizationURLOptions) []oauth2.AuthCodeOption
- func CopyScopes(requestedScopes, defaultScopes []string) []string
- func ExchangeCodeWithPKCE(ctx context.Context, config OAuth2ConfigExchanger, httpClient *http.Client, ...) (*oauth2.Token, error)
- type AuthorizationURLOptions
- type JWKSProvider
- type OAuth2ConfigExchanger
- type Provider
- type TokenSource
- type UserInfo
Constants ¶
const CrossClientAudienceScopePrefix = "audience:server:client_id:"
CrossClientAudienceScopePrefix is the Dex-specific prefix for cross-client audience scopes. Scopes with this prefix are mandatory and must be merged into client-requested scopes to enable SSO token forwarding scenarios.
ADMINISTRATOR NOTE: Any scope with this prefix configured in the provider's default scopes will be AUTOMATICALLY MERGED into ALL authorization requests, regardless of what scopes the client explicitly requests. This is intentional behavior to ensure SSO token forwarding works correctly, but administrators should be aware that:
- Tokens will always include the configured audience claims
- Clients cannot opt out of these audiences
- This affects token size and validation requirements on downstream services
Example: If defaults include "audience:server:client_id:k8s-auth", every token will be valid for the "k8s-auth" client, even if the requesting client didn't ask for it.
Variables ¶
This section is empty.
Functions ¶
func ApplyAuthorizationURLOptions ¶ added in v0.2.46
func ApplyAuthorizationURLOptions(opts *AuthorizationURLOptions) []oauth2.AuthCodeOption
ApplyAuthorizationURLOptions converts AuthorizationURLOptions to oauth2.AuthCodeOption slice. This shared helper reduces code duplication across providers and helps keep cyclomatic complexity low. Returns nil if opts is nil.
Standard OIDC parameters supported:
- prompt: Controls authentication UX (none, login, consent, select_account)
- login_hint: Pre-fills username/email field
- max_age: Maximum authentication age in seconds
- acr_values: Authentication context class references
- id_token_hint: Previously issued ID token as session hint
- Extra: Additional custom parameters
func CopyScopes ¶ added in v0.2.46
CopyScopes creates a deep copy of scopes to prevent race conditions. If requestedScopes is empty, copies defaultScopes. If requestedScopes is non-empty, copies those and merges in any mandatory scopes from defaultScopes. Mandatory scopes are cross-client audience scopes (prefixed with "audience:server:client_id:") which are required for SSO token forwarding scenarios.
Mandatory Scope Merging:
Cross-client audience scopes (prefixed with CrossClientAudienceScopePrefix) from defaultScopes are ALWAYS merged into the result, even when the client provides custom scopes. This ensures SSO token forwarding scenarios work correctly.
Example:
defaultScopes: ["openid", "profile", "audience:server:client_id:k8s-auth"] requestedScopes: ["openid", "email"] result: ["openid", "email", "audience:server:client_id:k8s-auth"]
Note that "profile" is NOT merged (it's not an audience scope), but the audience scope IS merged because it's mandatory for SSO token forwarding.
func ExchangeCodeWithPKCE ¶ added in v0.2.24
func ExchangeCodeWithPKCE(ctx context.Context, config OAuth2ConfigExchanger, httpClient *http.Client, code, verifier string) (*oauth2.Token, error)
ExchangeCodeWithPKCE is a shared helper for exchanging authorization codes with optional PKCE. It handles the common pattern of: 1. Adding PKCE verifier if provided 2. Setting up the HTTP client context 3. Performing the exchange 4. Wrapping any errors consistently
Parameters:
- ctx: context for the request (should have timeout set by caller)
- config: OAuth2 config that implements Exchange method
- httpClient: custom HTTP client to use for the exchange
- code: the authorization code to exchange
- verifier: PKCE code verifier (empty string if not using PKCE)
Types ¶
type AuthorizationURLOptions ¶ added in v0.2.46
type AuthorizationURLOptions struct {
// Prompt controls the authentication UX behavior.
// Common values:
// - "none": Silent authentication - no UI displayed. Returns error if login/consent required.
// - "login": Force re-authentication even if session exists.
// - "consent": Force consent even if previously granted.
// - "select_account": Force account selection even if only one account.
// Multiple values can be space-separated: "login consent"
Prompt string
// LoginHint pre-fills the email/username field at the IdP.
// Useful for re-authentication when the user's identity is already known.
// Example: "user@example.com"
LoginHint string
// MaxAge specifies the maximum authentication age in seconds.
// If the user's session is older than this, re-authentication is required.
// A value of 0 is equivalent to prompt=login.
MaxAge *int
// ACRValues requests specific authentication context class references.
// Space-separated string of acr_values.
// Example: "urn:mace:incommon:iap:silver"
ACRValues string
// IDTokenHint is a previously issued ID token passed as a hint about the user's session.
// Used with prompt=none to identify the user for silent re-authentication.
IDTokenHint string
// Extra allows setting additional custom parameters not covered above.
// These are added as query parameters to the authorization URL.
Extra map[string]string
}
AuthorizationURLOptions contains optional OIDC parameters for the authorization request. These parameters enable advanced authentication flows like silent re-authentication and user hints per OpenID Connect Core 1.0 Section 3.1.2.1.
See: https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
type JWKSProvider ¶ added in v0.2.39
type JWKSProvider interface {
Provider
// JWKSURI returns the JWKS (JSON Web Key Set) URI for this provider.
// This is used to fetch public keys for JWT signature verification.
// Returns empty string if JWKS is not available.
JWKSURI(ctx context.Context) (string, error)
// IssuerURL returns the issuer URL for this provider.
// This is used for JWT issuer validation.
IssuerURL() string
}
JWKSProvider is an optional interface for providers that support JWKS-based JWT validation. This enables SSO token forwarding where ID tokens from upstream servers are validated via JWKS signature verification.
Providers that don't support JWKS validation can omit this interface. The server will fall back to userinfo endpoint validation in that case.
type OAuth2ConfigExchanger ¶ added in v0.2.24
type OAuth2ConfigExchanger interface {
Exchange(ctx context.Context, code string, opts ...oauth2.AuthCodeOption) (*oauth2.Token, error)
}
OAuth2ConfigExchanger is an interface for the Exchange method of oauth2.Config. This allows us to create shared helper functions that work with any provider's config.
type Provider ¶
type Provider interface {
// Name returns the provider name (e.g., "google", "github", "microsoft")
Name() string
// DefaultScopes returns the provider's default scopes used when the client doesn't
// request specific scopes. These are the scopes configured when the provider was created.
DefaultScopes() []string
// AuthorizationURL generates the URL to redirect users for authentication
// codeChallenge and codeChallengeMethod are for PKCE (pass empty strings to disable)
// scopes is the list of scopes to request (if empty, provider's default scopes are used)
// opts contains optional OIDC parameters like prompt, login_hint, max_age (nil for defaults)
//
// OAuth 2.1 Security: PKCE is recommended for ALL client types (public and confidential)
// to protect against Authorization Code Injection attacks. Providers should support PKCE
// even when using client_secret authentication for defense-in-depth.
AuthorizationURL(state string, codeChallenge string, codeChallengeMethod string, scopes []string, opts *AuthorizationURLOptions) string
// ExchangeCode exchanges an authorization code for tokens
// codeVerifier is for PKCE verification (pass empty string if not using PKCE)
// Returns standard oauth2.Token
//
// OAuth 2.1 Security: PKCE verification provides cryptographic binding between the
// authorization request and token exchange, preventing code injection even for
// confidential clients with client_secret.
ExchangeCode(ctx context.Context, code string, codeVerifier string) (*oauth2.Token, error)
// ValidateToken validates an access token and returns user information
ValidateToken(ctx context.Context, accessToken string) (*UserInfo, error)
// RefreshToken refreshes an expired token using a refresh token
// Returns standard oauth2.Token
RefreshToken(ctx context.Context, refreshToken string) (*oauth2.Token, error)
// RevokeToken revokes a token at the provider
RevokeToken(ctx context.Context, token string) error
// HealthCheck verifies that the provider is reachable and functioning correctly.
// This is useful for readiness/liveness probes and startup validation.
// Returns nil if the provider is healthy, or an error describing the issue.
//
// SECURITY WARNING: Do not expose error messages from this method to untrusted clients.
// Error details may contain information about provider state (HTTP status codes, network errors)
// that could be used for reconnaissance. Use this for internal monitoring only.
HealthCheck(ctx context.Context) error
}
Provider defines the interface for OAuth identity providers. This abstraction allows supporting Google, GitHub, Microsoft, and generic OIDC providers. Now uses golang.org/x/oauth2.Token directly instead of custom types.
type TokenSource ¶ added in v0.2.43
type TokenSource string
TokenSource indicates how the user was authenticated.
const ( // TokenSourceOAuth indicates the user was authenticated via normal OAuth flow. // The server issued the token and the provider's ID token is stored in the token store. TokenSourceOAuth TokenSource = "oauth" // TokenSourceSSO indicates the user was authenticated via SSO token forwarding. // The Bearer token IS the ID token forwarded from a trusted upstream service. // There is no entry in the token store because the server didn't issue the token. TokenSourceSSO TokenSource = "sso" )
type UserInfo ¶
type UserInfo struct {
// ID is the unique user identifier from the provider
ID string
// Email is the user's email address
Email string
// EmailVerified indicates if the email is verified
EmailVerified bool
// Name is the user's full name
Name string
// GivenName is the user's first name
GivenName string
// FamilyName is the user's last name
FamilyName string
// Picture is the URL of the user's profile picture
Picture string
// Locale is the user's preferred locale
Locale string
// Groups contains group memberships from the identity provider.
// This is populated from the 'groups' claim in OIDC userinfo responses.
// Providers that don't support groups will leave this empty.
Groups []string
// TokenSource indicates how this user was authenticated.
// This is set to TokenSourceOAuth for normal OAuth flow tokens
// (where the ID token is stored in the token store) or TokenSourceSSO
// for SSO-forwarded tokens (where the Bearer token IS the ID token).
//
// Downstream servers can use this to determine whether to look up
// a stored ID token or use the Bearer token directly for downstream
// authentication (e.g., Kubernetes API authentication).
//
// SECURITY: This field is set server-side during token validation and
// should NOT be trusted if received from external sources (e.g., if
// UserInfo is deserialized from untrusted input). Always use the server's
// ValidateToken() method to obtain a trusted UserInfo with correct TokenSource.
TokenSource TokenSource
}
UserInfo represents user information from a provider
func (*UserInfo) IsOAuth ¶ added in v0.2.43
IsOAuth returns true if this user was authenticated via normal OAuth flow. When true, the server issued the token and the provider's ID token is stored in the token store.
Returns true for nil receivers (safe default) and empty TokenSource (backward compatibility with existing code). Returns false for SSO tokens and unknown/invalid TokenSource values.
Downstream servers should look up the stored ID token from the token store when this returns true.
func (*UserInfo) IsSSO ¶ added in v0.2.43
IsSSO returns true if this user was authenticated via SSO token forwarding. When true, the Bearer token IS the ID token and there is no entry in the token store (the server didn't issue the token).
Returns false for nil receivers, OAuth tokens, empty TokenSource, and unknown/invalid TokenSource values.
Downstream servers should use the Bearer token directly for downstream authentication when this returns true, rather than looking up a stored token.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package dex implements the OAuth provider interface for Dex (https://dexidp.io/).
|
Package dex implements the OAuth provider interface for Dex (https://dexidp.io/). |
|
Package github implements the OAuth provider interface for GitHub OAuth Apps.
|
Package github implements the OAuth provider interface for GitHub OAuth Apps. |
|
Package google provides a Google OAuth 2.0 provider implementation.
|
Package google provides a Google OAuth 2.0 provider implementation. |
|
Package mock provides mock implementations of the Provider interface for testing purposes.
|
Package mock provides mock implementations of the Provider interface for testing purposes. |
|
Package oidc provides shared OpenID Connect client utilities for OAuth providers.
|
Package oidc provides shared OpenID Connect client utilities for OAuth providers. |