Documentation
¶
Overview ¶
Package oauth provides OAuth 2.1 server capabilities.
Index ¶
- Constants
- Variables
- func BuildAuthorizationURL(baseURL, clientID, redirectURI, scope, state string) string
- func GenerateCodeChallenge(verifier string, method PKCEMethod) (string, error)
- func HashToken(token string) string
- func ValidateCodeChallenge(challenge string) error
- func ValidateCodeVerifier(verifier string) error
- func VerifyCodeChallenge(verifier, challenge string, method PKCEMethod) (bool, error)
- type AuthorizationCode
- type AuthorizationRequest
- type AuthorizationState
- type Client
- type DCRConfig
- type DCRRequest
- type DCRResponse
- type DCRService
- type ErrorResponse
- type MemoryStateStore
- func (s *MemoryStateStore) CleanupExpiredStates(_ context.Context, maxAge time.Duration) error
- func (s *MemoryStateStore) DeleteState(_ context.Context, key string) error
- func (s *MemoryStateStore) GetState(_ context.Context, key string) (*AuthorizationState, error)
- func (s *MemoryStateStore) SaveState(_ context.Context, key string, state *AuthorizationState) error
- type MemoryStorage
- func (m *MemoryStorage) CleanupExpiredCodes(_ context.Context) error
- func (m *MemoryStorage) CleanupExpiredTokens(_ context.Context) error
- func (m *MemoryStorage) ConsumeAuthorizationCode(_ context.Context, code string) (*AuthorizationCode, error)
- func (m *MemoryStorage) ConsumeRefreshToken(_ context.Context, token string) (*RefreshToken, error)
- func (m *MemoryStorage) CreateClient(_ context.Context, client *Client) error
- func (m *MemoryStorage) DeleteAuthorizationCode(_ context.Context, code string) error
- func (m *MemoryStorage) DeleteClient(_ context.Context, clientID string) error
- func (m *MemoryStorage) DeleteRefreshToken(_ context.Context, token string) error
- func (m *MemoryStorage) DeleteRefreshTokensForClient(_ context.Context, clientID string) error
- func (m *MemoryStorage) GetAuthorizationCode(_ context.Context, code string) (*AuthorizationCode, error)
- func (m *MemoryStorage) GetClient(_ context.Context, clientID string) (*Client, error)
- func (m *MemoryStorage) GetRefreshToken(_ context.Context, token string) (*RefreshToken, error)
- func (m *MemoryStorage) ListClients(_ context.Context) ([]*Client, error)
- func (m *MemoryStorage) SaveAuthorizationCode(_ context.Context, code *AuthorizationCode) error
- func (m *MemoryStorage) SaveRefreshToken(_ context.Context, token *RefreshToken) error
- func (m *MemoryStorage) UpdateClient(_ context.Context, client *Client) error
- type PKCEMethod
- type RateLimitConfig
- type RefreshToken
- type Server
- func (s *Server) Authorize(ctx context.Context, req AuthorizationRequest, userID string, ...) (string, error)
- func (s *Server) Close() error
- func (s *Server) Issuer() string
- func (s *Server) RegisterClient(ctx context.Context, req DCRRequest) (*DCRResponse, error)
- func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (s *Server) SetMetrics(m *observability.Metrics)
- func (s *Server) SetStateStore(store StateStore)
- func (s *Server) SigningKey() []byte
- func (s *Server) StartCleanupRoutine(ctx context.Context, interval time.Duration)
- func (s *Server) Token(ctx context.Context, req TokenRequest) (*TokenResponse, error)
- type ServerConfig
- type StateStore
- type Storage
- type TokenRequest
- type TokenResponse
- type UpstreamConfig
Constants ¶
const StateMaxAge = time.Hour
StateMaxAge is how long an in-flight authorization state stays valid. The window spans the user's whole trip through the upstream IdP login form, so it is generous relative to the auth-code TTL.
Variables ¶
var ( ErrStateNotFound = errors.New("authorization state not found") // ErrNotFound indicates a stored OAuth record (authorization code, // refresh token) does not exist. Storage implementations return it // from Consume* so the grant handlers can distinguish a genuinely // invalid/replayed credential from a storage outage. ErrNotFound = errors.New("record not found") // ErrStorageFailure indicates the backing store failed while // processing a grant. The token endpoint maps it to a 500 // server_error response so clients retry with the same credentials // instead of treating the failure as a terminal invalid_grant and // discarding a still-valid refresh token. ErrStorageFailure = errors.New("temporary storage failure") )
Errors returned by the OAuth server.
Functions ¶
func BuildAuthorizationURL ¶
BuildAuthorizationURL builds an authorization URL. Uses paths without /oauth prefix for Claude Desktop compatibility.
func GenerateCodeChallenge ¶
func GenerateCodeChallenge(verifier string, method PKCEMethod) (string, error)
GenerateCodeChallenge generates a code challenge from a verifier.
func HashToken ¶ added in v1.101.0
HashToken returns the hex-encoded SHA-256 digest of a token value. Opaque bearer credentials (refresh tokens, authorization codes) are stored only as digests so a database read never yields a usable credential; lookups hash the presented value and compare digests.
func ValidateCodeChallenge ¶
ValidateCodeChallenge validates a code challenge.
func ValidateCodeVerifier ¶
ValidateCodeVerifier validates a code verifier. Per RFC 7636, it must be 43-128 characters of [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~".
func VerifyCodeChallenge ¶
func VerifyCodeChallenge(verifier, challenge string, method PKCEMethod) (bool, error)
VerifyCodeChallenge verifies a code verifier against a challenge.
Types ¶
type AuthorizationCode ¶
type AuthorizationCode struct {
ID string `json:"id"`
// Code carries the raw value when issuing; Storage implementations
// persist only its SHA-256 digest (HashToken), so records read back
// from storage hold the digest, never a usable credential.
Code string `json:"code"`
ClientID string `json:"client_id"`
UserID string `json:"user_id"`
UserClaims map[string]any `json:"user_claims"`
CodeChallenge string `json:"code_challenge"`
RedirectURI string `json:"redirect_uri"`
Scope string `json:"scope"`
ExpiresAt time.Time `json:"expires_at"`
Used bool `json:"used"`
CreatedAt time.Time `json:"created_at"`
}
AuthorizationCode represents an OAuth authorization code.
func (*AuthorizationCode) IsExpired ¶
func (c *AuthorizationCode) IsExpired() bool
IsExpired checks if the authorization code has expired.
type AuthorizationRequest ¶
type AuthorizationRequest struct {
ResponseType string
ClientID string
RedirectURI string
Scope string
State string
CodeChallenge string
CodeChallengeMethod string
}
AuthorizationRequest represents an authorization request.
type AuthorizationState ¶ added in v0.3.0
type AuthorizationState struct {
// ClientID is the OAuth client's client_id (e.g., Claude Desktop).
ClientID string
// RedirectURI is where to send the client after authentication.
RedirectURI string
// State is the client's original state parameter.
State string
// CodeChallenge is the PKCE challenge from the client.
CodeChallenge string
// CodeChallengeMethod is the PKCE method (S256; the only supported method).
CodeChallengeMethod string
// Scope is the requested scope.
Scope string
// UpstreamState is the state for the upstream IdP (e.g., Keycloak).
UpstreamState string
// PromptNoneAttempted tracks whether we already tried prompt=none
// for this flow. Used to prevent infinite redirect loops when the
// upstream IdP returns login_required.
PromptNoneAttempted bool
// CreatedAt is when this state was created.
CreatedAt time.Time
}
AuthorizationState holds state for linking upstream IdP callbacks to original client authorization requests.
type Client ¶
type Client struct {
ID string `json:"id"`
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"` // #nosec G117 -- bcrypt hashed, required for OAuth client storage
Name string `json:"name"`
RedirectURIs []string `json:"redirect_uris"`
GrantTypes []string `json:"grant_types"`
RequirePKCE bool `json:"require_pkce"`
CreatedAt time.Time `json:"created_at"`
Active bool `json:"active"`
// DynamicallyRegistered marks clients created through the unauthenticated
// DCR /register endpoint (RFC 7591), as opposed to pre-registered
// config-file clients. Only DCR clients are eligible for TTL-based cleanup
// of unused registrations.
DynamicallyRegistered bool `json:"dynamically_registered"`
}
Client represents an OAuth 2.1 client.
func (*Client) SupportsGrantType ¶
SupportsGrantType checks if the client supports a grant type.
func (*Client) ValidRedirectURI ¶
ValidRedirectURI checks if a redirect URI is valid for this client. For loopback redirect URIs (127.0.0.1, [::1], localhost), matching follows RFC 8252 Section 7.3: scheme and host must match, but port and path are ignored.
type DCRConfig ¶
type DCRConfig struct {
// Enabled enables DCR.
Enabled bool
// AllowedRedirectPatterns are regex patterns for allowed redirect URIs.
// The registration endpoint is unauthenticated, so leaving this empty
// denies all registrations unless AllowAllRedirectURIs is set.
AllowedRedirectPatterns []string
// AllowAllRedirectURIs explicitly opts out of redirect URI pattern
// matching, accepting any HTTPS (or loopback HTTP) redirect URI. An
// attacker-controlled redirect URI is the setup for authorization-code
// interception, so this is an explicit escape hatch rather than the
// default for an empty pattern list.
AllowAllRedirectURIs bool
// DefaultGrantTypes are the default grant types for new clients.
DefaultGrantTypes []string
// RequirePKCE requires PKCE for all clients.
RequirePKCE bool
}
DCRConfig configures Dynamic Client Registration.
type DCRRequest ¶
type DCRRequest struct {
ClientName string `json:"client_name"`
RedirectURIs []string `json:"redirect_uris"`
GrantTypes []string `json:"grant_types,omitempty"`
TokenEndpointAuthMethod string `json:"token_endpoint_auth_method,omitempty"`
}
DCRRequest is a Dynamic Client Registration request.
type DCRResponse ¶
type DCRResponse struct {
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret,omitempty"` // #nosec G117 -- required by OAuth 2.0 DCR spec (RFC 7591)
ClientName string `json:"client_name"`
RedirectURIs []string `json:"redirect_uris"`
GrantTypes []string `json:"grant_types"`
ClientSecretExpiresAt int `json:"client_secret_expires_at"` // 0 means never
}
DCRResponse is a Dynamic Client Registration response.
type DCRService ¶
type DCRService struct {
// contains filtered or unexported fields
}
DCRService handles Dynamic Client Registration.
func NewDCRService ¶
func NewDCRService(storage Storage, config DCRConfig) (*DCRService, error)
NewDCRService creates a new DCR service.
func (*DCRService) Register ¶
func (s *DCRService) Register(ctx context.Context, req DCRRequest) (*DCRResponse, error)
Register registers a new OAuth client.
type ErrorResponse ¶
type ErrorResponse struct {
Error string `json:"error"`
ErrorDescription string `json:"error_description,omitempty"`
}
ErrorResponse represents an OAuth error response.
type MemoryStateStore ¶ added in v0.3.0
type MemoryStateStore struct {
// contains filtered or unexported fields
}
MemoryStateStore is an in-memory implementation of StateStore.
func NewMemoryStateStore ¶ added in v0.3.0
func NewMemoryStateStore() *MemoryStateStore
NewMemoryStateStore creates a new in-memory state store.
func (*MemoryStateStore) CleanupExpiredStates ¶ added in v1.96.0
CleanupExpiredStates removes states older than maxAge.
func (*MemoryStateStore) DeleteState ¶ added in v1.96.0
func (s *MemoryStateStore) DeleteState(_ context.Context, key string) error
DeleteState removes an authorization state.
func (*MemoryStateStore) GetState ¶ added in v1.96.0
func (s *MemoryStateStore) GetState(_ context.Context, key string) (*AuthorizationState, error)
GetState retrieves an authorization state.
func (*MemoryStateStore) SaveState ¶ added in v1.96.0
func (s *MemoryStateStore) SaveState(_ context.Context, key string, state *AuthorizationState) error
SaveState stores an authorization state.
type MemoryStorage ¶ added in v0.3.0
type MemoryStorage struct {
// contains filtered or unexported fields
}
MemoryStorage is an in-memory implementation of Storage. It is thread-safe and suitable for development/testing. For production, use PostgresStorage.
func NewMemoryStorage ¶ added in v0.3.0
func NewMemoryStorage() *MemoryStorage
NewMemoryStorage creates a new in-memory storage.
func (*MemoryStorage) CleanupExpiredCodes ¶ added in v0.3.0
func (m *MemoryStorage) CleanupExpiredCodes(_ context.Context) error
CleanupExpiredCodes removes expired authorization codes.
func (*MemoryStorage) CleanupExpiredTokens ¶ added in v0.3.0
func (m *MemoryStorage) CleanupExpiredTokens(_ context.Context) error
CleanupExpiredTokens removes expired refresh tokens.
func (*MemoryStorage) ConsumeAuthorizationCode ¶ added in v1.96.0
func (m *MemoryStorage) ConsumeAuthorizationCode(_ context.Context, code string) (*AuthorizationCode, error)
ConsumeAuthorizationCode atomically deletes and returns an authorization code by its raw value.
func (*MemoryStorage) ConsumeRefreshToken ¶ added in v1.96.0
func (m *MemoryStorage) ConsumeRefreshToken(_ context.Context, token string) (*RefreshToken, error)
ConsumeRefreshToken atomically deletes and returns a refresh token by its raw value.
func (*MemoryStorage) CreateClient ¶ added in v0.3.0
func (m *MemoryStorage) CreateClient(_ context.Context, client *Client) error
CreateClient stores a new client.
func (*MemoryStorage) DeleteAuthorizationCode ¶ added in v0.3.0
func (m *MemoryStorage) DeleteAuthorizationCode(_ context.Context, code string) error
DeleteAuthorizationCode deletes an authorization code by its raw value.
func (*MemoryStorage) DeleteClient ¶ added in v0.3.0
func (m *MemoryStorage) DeleteClient(_ context.Context, clientID string) error
DeleteClient deletes a client.
func (*MemoryStorage) DeleteRefreshToken ¶ added in v0.3.0
func (m *MemoryStorage) DeleteRefreshToken(_ context.Context, token string) error
DeleteRefreshToken deletes a refresh token by its raw value.
func (*MemoryStorage) DeleteRefreshTokensForClient ¶ added in v0.3.0
func (m *MemoryStorage) DeleteRefreshTokensForClient(_ context.Context, clientID string) error
DeleteRefreshTokensForClient deletes all refresh tokens for a client.
func (*MemoryStorage) GetAuthorizationCode ¶ added in v0.3.0
func (m *MemoryStorage) GetAuthorizationCode(_ context.Context, code string) (*AuthorizationCode, error)
GetAuthorizationCode retrieves an authorization code by its raw value.
func (*MemoryStorage) GetRefreshToken ¶ added in v0.3.0
func (m *MemoryStorage) GetRefreshToken(_ context.Context, token string) (*RefreshToken, error)
GetRefreshToken retrieves a refresh token by its raw value.
func (*MemoryStorage) ListClients ¶ added in v0.3.0
func (m *MemoryStorage) ListClients(_ context.Context) ([]*Client, error)
ListClients returns all clients.
func (*MemoryStorage) SaveAuthorizationCode ¶ added in v0.3.0
func (m *MemoryStorage) SaveAuthorizationCode(_ context.Context, code *AuthorizationCode) error
SaveAuthorizationCode stores an authorization code. Only the SHA-256 digest of the code value is retained; the caller's struct is not mutated, so the raw value it holds stays usable for issuance.
func (*MemoryStorage) SaveRefreshToken ¶ added in v0.3.0
func (m *MemoryStorage) SaveRefreshToken(_ context.Context, token *RefreshToken) error
SaveRefreshToken stores a refresh token. Only the SHA-256 digest of the token value is retained; the caller's struct is not mutated, so the raw value it holds stays usable for issuance.
func (*MemoryStorage) UpdateClient ¶ added in v0.3.0
func (m *MemoryStorage) UpdateClient(_ context.Context, client *Client) error
UpdateClient updates an existing client.
type PKCEMethod ¶
type PKCEMethod string
PKCEMethod defines the code challenge method.
const ( // PKCEMethodS256 uses SHA-256 hashing. Per OAuth 2.1 it is the only // supported code challenge method; the "plain" method is not accepted. PKCEMethodS256 PKCEMethod = "S256" )
func DefaultPKCEMethod ¶
func DefaultPKCEMethod() PKCEMethod
DefaultPKCEMethod returns the default (and recommended) PKCE method.
type RateLimitConfig ¶ added in v1.101.0
type RateLimitConfig struct {
// Enabled turns limiting on/off; nil means enabled (platform default-on).
Enabled *bool
// TrustedProxies is the set of CIDRs whose X-Forwarded-For headers are
// trusted for client attribution. Empty means trust none: the direct peer
// address is used and forwarding headers are ignored.
TrustedProxies []string
// TokenRPM / TokenBurst limit /token per client IP.
TokenRPM int
TokenBurst int
// RegisterRPM / RegisterBurst limit /register per client IP.
RegisterRPM int
RegisterBurst int
}
RateLimitConfig configures rate limiting for the unauthenticated OAuth HTTP endpoints. /token performs a bcrypt compare per attempt and /register performs a bcrypt hash plus a DB insert per request, so both are CPU (and, for /register, storage) amplification levers. Limiting is on by default (Enabled nil == enabled); the per-endpoint knobs default to the *Default* constants below.
Attribution is trusted-proxy-aware (TrustedProxies) rather than naive leftmost-X-Forwarded-For, and each endpoint additionally has a global backstop bucket (see ratelimit.HTTPLimiter) so total throughput — and therefore worst-case bcrypt work — is bounded even when per-IP attribution is defeated or collapses behind a proxy.
type RefreshToken ¶
type RefreshToken struct {
ID string `json:"id"`
// Token carries the raw value when issuing; Storage implementations
// persist only its SHA-256 digest (HashToken), so records read back
// from storage hold the digest, never a usable credential.
Token string `json:"token"`
ClientID string `json:"client_id"`
UserID string `json:"user_id"`
UserClaims map[string]any `json:"user_claims"`
Scope string `json:"scope"`
ExpiresAt time.Time `json:"expires_at"`
CreatedAt time.Time `json:"created_at"`
}
RefreshToken represents an OAuth refresh token.
func (*RefreshToken) IsExpired ¶
func (t *RefreshToken) IsExpired() bool
IsExpired checks if the refresh token has expired.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is an OAuth 2.1 authorization server.
func NewServer ¶
func NewServer(config ServerConfig, storage Storage) (*Server, error)
NewServer creates a new OAuth server.
func (*Server) Authorize ¶
func (s *Server) Authorize(ctx context.Context, req AuthorizationRequest, userID string, userClaims map[string]any) (string, error)
Authorize handles the authorization endpoint.
func (*Server) Close ¶ added in v1.101.0
Close releases the server's background resources. It stops the rate-limiter cleanup goroutines; it is nil-safe and idempotent. Storage and authorization-state cleanup are owned by their respective callers.
func (*Server) RegisterClient ¶
func (s *Server) RegisterClient(ctx context.Context, req DCRRequest) (*DCRResponse, error)
RegisterClient handles Dynamic Client Registration.
func (*Server) ServeHTTP ¶
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP implements http.Handler for the OAuth server. Handles both standard paths (with /oauth prefix) and Claude Desktop compatible paths (without prefix).
func (*Server) SetMetrics ¶ added in v1.70.0
func (s *Server) SetMetrics(m *observability.Metrics)
SetMetrics attaches the observability recorder so token issuance and refresh outcomes are recorded. Nil-safe: the Record* calls no-op when metrics are disabled, so the token path behaves identically either way.
func (*Server) SetStateStore ¶ added in v1.96.0
func (s *Server) SetStateStore(store StateStore)
SetStateStore replaces the in-memory authorization state store. Call it during setup, before the server handles requests: in multi-replica deployments the upstream IdP callback can land on a different replica than the one that started the flow, so the state must live in a shared (database-backed) store.
func (*Server) SigningKey ¶ added in v0.4.0
SigningKey returns the OAuth server's signing key. This is needed by the OAuth JWT authenticator to validate tokens.
func (*Server) StartCleanupRoutine ¶
StartCleanupRoutine starts a background routine to clean up expired codes, tokens, and in-flight authorization states.
func (*Server) Token ¶
func (s *Server) Token(ctx context.Context, req TokenRequest) (*TokenResponse, error)
Token handles the token endpoint.
type ServerConfig ¶
type ServerConfig struct {
// Issuer is the OAuth issuer URL.
Issuer string
// AccessTokenTTL is the access token lifetime.
AccessTokenTTL time.Duration
// RefreshTokenTTL is the refresh token lifetime.
RefreshTokenTTL time.Duration
// AuthCodeTTL is the authorization code lifetime.
AuthCodeTTL time.Duration
// SigningKey is the HMAC key used to sign JWT access tokens.
// If not provided, tokens will be opaque (not recommended for production).
// Generate with: openssl rand -base64 32
SigningKey []byte
// DCR configures Dynamic Client Registration.
DCR DCRConfig
// Upstream configures the upstream identity provider (e.g., Keycloak).
Upstream *UpstreamConfig
// RateLimit configures rate limiting for the unauthenticated /token and
// /register endpoints. Limiting is on by default (see RateLimitConfig).
RateLimit RateLimitConfig
}
ServerConfig configures the OAuth server.
type StateStore ¶ added in v0.3.0
type StateStore interface {
// SaveState stores an authorization state, replacing any existing
// state under the same key.
SaveState(ctx context.Context, key string, state *AuthorizationState) error
// GetState retrieves an authorization state.
GetState(ctx context.Context, key string) (*AuthorizationState, error)
// DeleteState removes an authorization state.
DeleteState(ctx context.Context, key string) error
// CleanupExpiredStates removes states older than maxAge.
CleanupExpiredStates(ctx context.Context, maxAge time.Duration) error
}
StateStore manages authorization states for the OAuth flow. In multi-replica deployments the store must be shared (database-backed): the /oauth/authorize redirect and the upstream IdP callback can land on different replicas.
type Storage ¶
type Storage interface {
// Client management
CreateClient(ctx context.Context, client *Client) error
GetClient(ctx context.Context, clientID string) (*Client, error)
UpdateClient(ctx context.Context, client *Client) error
DeleteClient(ctx context.Context, clientID string) error
ListClients(ctx context.Context) ([]*Client, error)
// Authorization code management. Implementations persist only the
// SHA-256 digest of the code value (HashToken); the get, delete, and
// consume methods take the raw value and hash it before comparison.
SaveAuthorizationCode(ctx context.Context, code *AuthorizationCode) error
GetAuthorizationCode(ctx context.Context, code string) (*AuthorizationCode, error)
DeleteAuthorizationCode(ctx context.Context, code string) error
// ConsumeAuthorizationCode atomically deletes the authorization code
// and returns it, so single-use invalidation and retrieval cannot
// diverge: a replayed or concurrently exchanged code fails because
// the record is already gone. Returns an error when the code does
// not exist.
ConsumeAuthorizationCode(ctx context.Context, code string) (*AuthorizationCode, error)
CleanupExpiredCodes(ctx context.Context) error
// Token management. Implementations persist only the SHA-256 digest
// of the token value (HashToken); the get, delete, and consume
// methods take the raw value and hash it before comparison.
SaveRefreshToken(ctx context.Context, token *RefreshToken) error
GetRefreshToken(ctx context.Context, token string) (*RefreshToken, error)
DeleteRefreshToken(ctx context.Context, token string) error
// ConsumeRefreshToken atomically deletes the refresh token and
// returns it, backing rotation: the old token is provably invalid
// before new tokens are issued. Returns an error when the token
// does not exist.
ConsumeRefreshToken(ctx context.Context, token string) (*RefreshToken, error)
DeleteRefreshTokensForClient(ctx context.Context, clientID string) error
CleanupExpiredTokens(ctx context.Context) error
}
Storage defines the interface for OAuth data persistence.
type TokenRequest ¶
type TokenRequest struct {
GrantType string
Code string
RedirectURI string
ClientID string
ClientSecret string // #nosec G117 -- required by OAuth 2.1 token request (RFC 6749 §4.1.3)
CodeVerifier string
RefreshToken string // #nosec G117 -- required by OAuth 2.1 refresh grant (RFC 6749 §6)
Scope string
}
TokenRequest represents a token request.
type TokenResponse ¶
type TokenResponse struct {
AccessToken string `json:"access_token"` // #nosec G117 -- required by OAuth 2.1 token response (RFC 6749 §5.1)
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
RefreshToken string `json:"refresh_token,omitempty"` // #nosec G117 -- required by OAuth 2.1 token response (RFC 6749 §5.1)
Scope string `json:"scope,omitempty"`
}
TokenResponse represents a token response.
type UpstreamConfig ¶ added in v0.3.0
type UpstreamConfig struct {
// Issuer is the upstream IdP issuer URL (e.g., Keycloak realm URL).
Issuer string
// ClientID is the MCP server's client ID in the upstream IdP.
ClientID string
// ClientSecret is the MCP server's client secret.
ClientSecret string // #nosec G117 -- required for upstream IdP token exchange
// RedirectURI is the callback URL for the upstream IdP.
RedirectURI string
// AuthorizationEndpoint, when set, is used verbatim as the upstream IdP's
// authorization endpoint, bypassing OIDC discovery. Empty (default) means
// discover it from the issuer's well-known configuration document. Provide it
// only for IdPs whose discovery document is broken or unreachable.
AuthorizationEndpoint string
// TokenEndpoint, when set, is used verbatim as the upstream IdP's token
// endpoint, bypassing OIDC discovery. Empty (default) means discover it.
// Discovery is skipped entirely only when BOTH endpoints are set.
TokenEndpoint string
}
UpstreamConfig configures the upstream identity provider.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package postgres provides PostgreSQL storage for OAuth 2.1 data.
|
Package postgres provides PostgreSQL storage for OAuth 2.1 data. |
|
Package signkey manages the HMAC key ring used to sign and verify HS256 JWT access tokens.
|
Package signkey manages the HMAC key ring used to sign and verify HS256 JWT access tokens. |