oidc

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Mar 2, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package oidc provides OpenID Connect building blocks for authentication.

It defines a Provider interface that projects implement per-provider, an OIDC token Verifier backed by auto-discovery and JWKS key rotation, and utilities for OAuth2 state management and PKCE.

This package provides a standardized, reusable layer without enforcing specific providers, callback patterns, or account linking logic. It uses only the standard library and golang.org/x/crypto for JWKS key parsing and signature verification.

Usage:

// Create a verifier for any OIDC-compliant issuer
v, err := oidc.NewVerifier(ctx, "https://accounts.google.com", oidc.VerifierConfig{
    ClientID: "my-client-id",
})
idToken, err := v.Verify(ctx, rawIDToken)

// Generate secure state + PKCE for OAuth2 flows
state, err := oidc.GenerateState()
pkce, err := oidc.NewPKCE()

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenerateNonce

func GenerateNonce() (string, error)

GenerateNonce creates a cryptographically secure random nonce for OIDC replay protection. Returns a 16-byte hex-encoded string (32 characters).

func GenerateState

func GenerateState() (string, error)

GenerateState creates a cryptographically secure random state string for CSRF protection in OAuth2 flows. Returns a 32-byte hex-encoded string (64 characters).

Types

type AuthURLOption

type AuthURLOption func(*AuthURLOptions)

AuthURLOption configures authorization URL generation.

func WithExtraParam

func WithExtraParam(key, value string) AuthURLOption

WithExtraParam adds a custom query parameter to the authorization URL.

func WithNonce

func WithNonce(nonce string) AuthURLOption

WithNonce adds an OIDC nonce parameter for replay protection.

func WithPKCE

func WithPKCE(pkce *PKCE) AuthURLOption

WithPKCE adds PKCE (Proof Key for Code Exchange) parameters.

func WithRedirectURI

func WithRedirectURI(uri string) AuthURLOption

WithRedirectURI overrides the configured redirect URI for this request.

func WithScopes

func WithScopes(scopes ...string) AuthURLOption

WithScopes overrides the default scopes for this request.

type AuthURLOptions

type AuthURLOptions struct {
	RedirectURI string
	Scopes      []string
	Nonce       string
	PKCE        *PKCE
	ExtraParams map[string]string
}

AuthURLOptions holds the configuration for authorization URL generation.

func ApplyAuthURLOptions

func ApplyAuthURLOptions(opts []AuthURLOption) AuthURLOptions

ApplyAuthURLOptions applies options and returns the resolved configuration. This is a helper for Provider implementations to process AuthURLOption parameters.

type Config

type Config struct {
	// Enabled controls whether OIDC verification is active.
	Enabled bool `mapstructure:"enabled"`

	// Issuer is the OIDC provider's issuer URL (e.g., "https://accounts.google.com").
	// Used for auto-discovery of JWKS endpoint, authorization endpoint, etc.
	Issuer string `mapstructure:"issuer"`

	// ClientID is the OAuth2 client ID (also used as expected "aud" claim).
	ClientID string `mapstructure:"client_id"`

	// ClientSecret is the OAuth2 client secret (for confidential clients).
	ClientSecret string `mapstructure:"client_secret"`

	// RedirectURL is the OAuth2 callback URL.
	RedirectURL string `mapstructure:"redirect_url"`

	// Scopes are the OAuth2 scopes to request (default: ["openid", "email", "profile"]).
	Scopes []string `mapstructure:"scopes"`

	// SupportedSigningAlgs restricts allowed ID token signing algorithms (default: ["RS256"]).
	SupportedSigningAlgs []string `mapstructure:"supported_signing_algs"`

	// JWKSCacheDuration controls how long JWKS keys are cached (default: "1h").
	JWKSCacheDuration time.Duration `mapstructure:"jwks_cache_duration"`

	// HTTPTimeout is the timeout for discovery and JWKS HTTP requests (default: "10s").
	HTTPTimeout time.Duration `mapstructure:"http_timeout"`

	// SkipIssuerCheck skips issuer validation (for testing only).
	SkipIssuerCheck bool `mapstructure:"skip_issuer_check"`
}

Config configures OIDC provider verification. Loadable from YAML/env via mapstructure tags.

func (*Config) ApplyDefaults

func (c *Config) ApplyDefaults()

ApplyDefaults sets sensible defaults for zero-valued fields.

func (*Config) ToVerifierConfig

func (c *Config) ToVerifierConfig() VerifierConfig

ToVerifierConfig converts to a VerifierConfig for creating a Verifier.

func (*Config) Validate

func (c *Config) Validate() error

Validate checks required fields.

type DiscoveryEndpoints

type DiscoveryEndpoints struct {
	Authorization string
	Token         string
	UserInfo      string
	JWKS          string
}

DiscoveryEndpoints holds the discovered OIDC endpoints.

type ExchangeOption

type ExchangeOption func(*ExchangeOptions)

ExchangeOption configures the token exchange.

func WithCodeVerifier

func WithCodeVerifier(verifier string) ExchangeOption

WithCodeVerifier adds the PKCE code verifier for the exchange.

func WithExchangeRedirectURI

func WithExchangeRedirectURI(uri string) ExchangeOption

WithExchangeRedirectURI sets the redirect URI for the exchange (must match the one used in AuthURL).

type ExchangeOptions

type ExchangeOptions struct {
	RedirectURI  string
	CodeVerifier string
}

ExchangeOptions holds the configuration for token exchange.

func ApplyExchangeOptions

func ApplyExchangeOptions(opts []ExchangeOption) ExchangeOptions

ApplyExchangeOptions applies options and returns the resolved configuration. This is a helper for Provider implementations to process ExchangeOption parameters.

type IDToken

type IDToken struct {
	// Issuer is the "iss" claim.
	Issuer string

	// Subject is the "sub" claim (provider's unique user ID).
	Subject string

	// Audience is the "aud" claim.
	Audience []string

	// ExpiresAt is the "exp" claim.
	ExpiresAt time.Time

	// IssuedAt is the "iat" claim.
	IssuedAt time.Time

	// Nonce is the "nonce" claim (for replay protection).
	Nonce string

	// Claims holds all token claims for project-specific extraction.
	Claims map[string]interface{}
}

IDToken represents a parsed and verified OIDC ID token.

func (*IDToken) ToUserInfo

func (t *IDToken) ToUserInfo() *UserInfo

ToUserInfo extracts standard OIDC UserInfo claims from the ID token.

type PKCE

type PKCE struct {
	// CodeVerifier is the random secret (kept by the client, sent during exchange).
	CodeVerifier string

	// CodeChallenge is the SHA-256 hash of the verifier (sent in the auth URL).
	CodeChallenge string

	// CodeChallengeMethod is always "S256".
	CodeChallengeMethod string
}

PKCE holds a PKCE (Proof Key for Code Exchange) challenge/verifier pair. Use NewPKCE to generate a pair, then:

  • Send CodeChallenge + CodeChallengeMethod in the authorization URL
  • Send CodeVerifier in the token exchange

func NewPKCE

func NewPKCE() (*PKCE, error)

NewPKCE generates a new PKCE challenge/verifier pair using S256 method. The verifier is a 32-byte random value, base64url-encoded (43 characters).

type Provider

type Provider interface {
	// Name returns the provider identifier (e.g., "google", "github").
	Name() string

	// AuthURL returns the authorization URL for initiating the OAuth2 flow.
	// The state parameter should be a cryptographically random value for CSRF protection.
	// Options allow passing additional parameters (PKCE, nonce, login_hint, etc.).
	AuthURL(state string, opts ...AuthURLOption) string

	// Exchange trades an authorization code for tokens.
	// Returns the token set (access, refresh, ID token if OIDC) and user information.
	Exchange(ctx context.Context, code string, opts ...ExchangeOption) (*TokenResult, error)

	// UserInfo fetches the user's profile from the provider using an access token.
	// Not all providers support this endpoint (GitHub uses a different API).
	UserInfo(ctx context.Context, accessToken string) (*UserInfo, error)
}

Provider defines the contract for an OAuth2/OIDC authentication provider. Projects implement this per-provider (Google, GitHub, Microsoft, etc.) or use the generic OIDC implementation for standard-compliant providers.

This interface covers the Authorization Code flow — the most common server-side OAuth2 pattern.

type TokenResult

type TokenResult struct {
	// AccessToken is the OAuth2 access token.
	AccessToken string

	// RefreshToken is the OAuth2 refresh token (may be empty).
	RefreshToken string

	// IDToken is the raw OIDC ID token JWT string (empty for non-OIDC providers).
	IDToken string

	// TokenType is typically "Bearer".
	TokenType string

	// ExpiresAt is when the access token expires.
	ExpiresAt time.Time

	// Scopes are the granted scopes (may differ from requested).
	Scopes []string
}

TokenResult holds the tokens returned from an OAuth2/OIDC exchange.

type UserInfo

type UserInfo struct {
	// Subject is the provider's unique identifier for the user.
	Subject string `json:"sub"`

	// Email is the user's email address (may be empty if not in scope).
	Email string `json:"email,omitempty"`

	// EmailVerified indicates if the provider has verified the email.
	EmailVerified bool `json:"email_verified,omitempty"`

	// Name is the user's full display name.
	Name string `json:"name,omitempty"`

	// GivenName is the user's first name.
	GivenName string `json:"given_name,omitempty"`

	// FamilyName is the user's last name.
	FamilyName string `json:"family_name,omitempty"`

	// Picture is a URL to the user's profile picture.
	Picture string `json:"picture,omitempty"`

	// Locale is the user's locale (e.g., "en-US").
	Locale string `json:"locale,omitempty"`

	// Raw holds all claims from the provider for project-specific extraction.
	Raw map[string]interface{} `json:"raw,omitempty"`
}

UserInfo represents the standard OIDC UserInfo claims. Only standard fields are included — projects extract provider-specific claims by parsing the ID token or calling provider-specific APIs.

type Verifier

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

Verifier validates OIDC ID tokens using auto-discovery and JWKS key rotation. It discovers the issuer's OpenID configuration and caches the JWKS for efficient token verification.

func NewVerifier

func NewVerifier(ctx context.Context, issuer string, cfg VerifierConfig) (*Verifier, error)

NewVerifier creates a new OIDC token verifier for the given issuer. It performs OIDC discovery to find the JWKS endpoint.

func (*Verifier) DiscoveryEndpoints

func (v *Verifier) DiscoveryEndpoints() DiscoveryEndpoints

DiscoveryEndpoints returns the discovered OAuth2/OIDC endpoints. Useful for projects that need to build OAuth2 configs from discovery.

func (*Verifier) Verify

func (v *Verifier) Verify(ctx context.Context, rawIDToken string) (*IDToken, error)

Verify validates a raw ID token string and returns the parsed claims. It checks the signature, issuer, audience, and expiry.

type VerifierConfig

type VerifierConfig struct {
	// ClientID is the expected "aud" claim in the ID token (required).
	ClientID string

	// SkipExpiryCheck skips the expiry validation (for testing only).
	SkipExpiryCheck bool

	// SkipIssuerCheck skips the issuer validation.
	SkipIssuerCheck bool

	// SupportedSigningAlgs restricts allowed signing algorithms.
	// Default: ["RS256"].
	SupportedSigningAlgs []string

	// HTTPClient is an optional HTTP client for discovery and JWKS requests.
	// Useful for testing or custom TLS configurations.
	HTTPClient *http.Client

	// JWKSCacheDuration controls how long JWKS keys are cached (default: 1h).
	JWKSCacheDuration time.Duration
}

VerifierConfig configures the OIDC token verifier.

Jump to

Keyboard shortcuts

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