server

package
v0.7.2 Latest Latest
Warning

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

Go to latest
Published: Jan 19, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package server provides the OAuth 2.0 authorization server implementation for ToolHive.

This package implements a standards-compliant OAuth 2.0 authorization server that acts as an intermediary between MCP clients and upstream identity providers (IdPs). It issues its own JWTs while federating authentication to external IdPs.

Architecture

The server package is organized into focused sub-packages:

  • server/registration: OAuth client types including RFC 8252 compliant LoopbackClient for native applications with dynamic port matching
  • server/crypto: Cryptographic utilities for key loading, PKCE, and signing
  • server/session: Session management linking issued tokens to upstream IdP tokens

Protocol Compliance

This implementation follows these OAuth 2.0 and OIDC specifications:

  • RFC 6749: OAuth 2.0 Authorization Framework
  • RFC 6750: Bearer Token Usage
  • RFC 7636: Proof Key for Code Exchange (PKCE)
  • RFC 7591: OAuth 2.0 Dynamic Client Registration
  • RFC 8252: OAuth 2.0 for Native Apps (loopback redirect URI handling)
  • OpenID Connect Core 1.0: Discovery and JWT claims

Main Entry Points

For creating an authorization server configuration:

params := &server.AuthorizationServerParams{
    Issuer:              "https://auth.example.com",
    AccessTokenLifespan: time.Hour,
    SigningKeyID:        "key-1",
    SigningKeyAlgorithm: "RS256",
    SigningKey:          privateKey,
    HMACSecrets:         &crypto.HMACSecrets{
        Current: currentSecret,       // Active secret for signing
        Rotated: [][]byte{oldSecret}, // Previous secrets for verification (optional)
    },
}
authServerConfig, err := server.NewAuthorizationServerConfig(params)

For creating OAuth clients:

client, err := registration.New(registration.Config{
    ID:           "my-client",
    RedirectURIs: []string{"http://127.0.0.1:8080/callback"},
    Public:       true,
})

Token Flow

The authorization server implements the authorization code flow with PKCE:

  1. Client initiates auth at /oauth/authorize with PKCE challenge
  2. Server redirects to upstream IdP for authentication
  3. IdP calls back to /oauth/callback with auth code
  4. Server exchanges code with IdP and stores IdP tokens
  5. Server issues its own auth code and redirects to client
  6. Client exchanges code at /oauth/token for JWT access token
  7. JWT contains "tsid" claim linking to stored IdP tokens

Sub-package Details

Use the sub-packages directly for more granular control:

import "github.com/stacklok/toolhive/pkg/authserver/server/registration"   // Client types
import "github.com/stacklok/toolhive/pkg/authserver/server/crypto"   // Key loading, PKCE
import "github.com/stacklok/toolhive/pkg/authserver/server/session"  // Session types

Index

Constants

View Source
const (
	// MinAccessTokenLifespan is the minimum allowed access token lifetime.
	MinAccessTokenLifespan = 1 * time.Minute
	// MaxAccessTokenLifespan is the maximum allowed access token lifetime.
	MaxAccessTokenLifespan = 24 * time.Hour
	// MinRefreshTokenLifespan is the minimum allowed refresh token lifetime.
	MinRefreshTokenLifespan = 1 * time.Hour
	// MaxRefreshTokenLifespan is the maximum allowed refresh token lifetime (30 days).
	MaxRefreshTokenLifespan = 30 * 24 * time.Hour
	// MinAuthCodeLifespan is the minimum allowed authorization code lifetime.
	MinAuthCodeLifespan = 30 * time.Second
	// MaxAuthCodeLifespan is the maximum allowed authorization code lifetime (RFC 6749 recommends 10 min max).
	MaxAuthCodeLifespan = 10 * time.Minute
)

Token lifespan bounds for validation.

Variables

This section is empty.

Functions

func NewAuthorizationServer

func NewAuthorizationServer(
	config *AuthorizationServerConfig,
	storage fosite.Storage,
	strategy any,
	factories ...Factory,
) fosite.OAuth2Provider

NewAuthorizationServer creates a new fosite OAuth2Provider with the given configuration, storage, strategy, and endpoint handler factories.

Types

type AuthorizationServerConfig

type AuthorizationServerConfig struct {
	*fosite.Config
	SigningKey  *jose.JSONWebKey
	SigningJWKS *jose.JSONWebKeySet
}

AuthorizationServerConfig wraps fosite.Config with additional configuration for JWT signing and other extensions.

func NewAuthorizationServerConfig

func NewAuthorizationServerConfig(cfg *AuthorizationServerParams) (*AuthorizationServerConfig, error)

NewAuthorizationServerConfig creates an AuthorizationServerConfig from the provided configuration.

func (*AuthorizationServerConfig) GetAccessTokenIssuer

func (c *AuthorizationServerConfig) GetAccessTokenIssuer() string

GetAccessTokenIssuer returns the issuer URL for access tokens. This is an adapter method that wraps the embedded fosite.Config method.

func (*AuthorizationServerConfig) GetAccessTokenLifespan

func (c *AuthorizationServerConfig) GetAccessTokenLifespan() time.Duration

GetAccessTokenLifespan returns the lifetime for access tokens. This is an adapter method that wraps the embedded fosite.Config method.

func (*AuthorizationServerConfig) GetAuthorizeCodeLifespan

func (c *AuthorizationServerConfig) GetAuthorizeCodeLifespan() time.Duration

GetAuthorizeCodeLifespan returns the lifetime for authorization codes. This is an adapter method that wraps the embedded fosite.Config method.

func (*AuthorizationServerConfig) GetPrivateSigningJWKS

func (c *AuthorizationServerConfig) GetPrivateSigningJWKS(_ context.Context) *jose.JSONWebKeySet

GetPrivateSigningJWKS returns the config's signing JWKS containing private keys.

WARNING: This JWKS contains PRIVATE key material and MUST NOT be exposed publicly. Use PublicJWKS() for the /.well-known/jwks.json endpoint.

func (*AuthorizationServerConfig) GetRefreshTokenLifespan

func (c *AuthorizationServerConfig) GetRefreshTokenLifespan() time.Duration

GetRefreshTokenLifespan returns the lifetime for refresh tokens. This is an adapter method that wraps the embedded fosite.Config method.

func (*AuthorizationServerConfig) GetSigningKey

GetSigningKey returns the config's signing key.

func (*AuthorizationServerConfig) PublicJWKS

func (c *AuthorizationServerConfig) PublicJWKS() *jose.JSONWebKeySet

PublicJWKS returns a copy of the JWKS containing only public keys.

type AuthorizationServerParams

type AuthorizationServerParams struct {
	Issuer               string
	AccessTokenLifespan  time.Duration
	RefreshTokenLifespan time.Duration
	AuthCodeLifespan     time.Duration
	HMACSecrets          *servercrypto.HMACSecrets
	SigningKeyID         string
	SigningKeyAlgorithm  string
	SigningKey           crypto.Signer
}

AuthorizationServerParams contains the configuration needed to create an AuthorizationServerConfig. This is a minimal subset of the authserver.Config fields needed for OAuth2.

type Factory

type Factory func(config *AuthorizationServerConfig, storage fosite.Storage, strategy any) any

Factory is a constructor which is used to create an OAuth2 endpoint handler. NewAuthorizationServer handles consuming the new struct and attaching it to the parts of the config that it implements.

The strategy parameter is typed as any because fosite uses different strategy interfaces for different flows (e.g., oauth2.CoreStrategy, openid.OpenIDConnectTokenStrategy) that do not share a common base interface.

Directories

Path Synopsis
Package crypto provides cryptographic utilities for the OAuth authorization server.
Package crypto provides cryptographic utilities for the OAuth authorization server.
Package registration provides OAuth client types and utilities, including RFC 8252 compliant loopback redirect URI support for native OAuth clients.
Package registration provides OAuth client types and utilities, including RFC 8252 compliant loopback redirect URI support for native OAuth clients.
Package session provides OAuth session management for the authorization server.
Package session provides OAuth session management for the authorization server.

Jump to

Keyboard shortcuts

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