storage

package
v0.7.0 Latest Latest
Warning

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

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

Documentation

Overview

Package storage provides storage interfaces and implementations for the OAuth authorization server.

Index

Constants

View Source
const (
	// TypeMemory uses in-memory storage (default).
	TypeMemory Type = "memory"

	// DefaultCleanupInterval is how often the background cleanup runs.
	DefaultCleanupInterval = 5 * time.Minute

	// DefaultAccessTokenTTL is the default TTL for access tokens when not extractable from session.
	DefaultAccessTokenTTL = 1 * time.Hour

	// DefaultRefreshTokenTTL is the default TTL for refresh tokens when not extractable from session.
	DefaultRefreshTokenTTL = 30 * 24 * time.Hour // 30 days

	// DefaultAuthCodeTTL is the default TTL for authorization codes (RFC 6749 recommendation).
	DefaultAuthCodeTTL = 10 * time.Minute

	// DefaultInvalidatedCodeTTL is how long invalidated codes are kept for replay detection.
	DefaultInvalidatedCodeTTL = 30 * time.Minute

	// DefaultPKCETTL is the default TTL for PKCE requests (same as auth codes).
	DefaultPKCETTL = 10 * time.Minute
)
View Source
const DefaultPendingAuthorizationTTL = 10 * time.Minute

DefaultPendingAuthorizationTTL is the default TTL for pending authorization requests.

Variables

View Source
var (
	// ErrNotFound is returned when an item is not found in storage.
	ErrNotFound = errors.New("storage: item not found")

	// ErrExpired is returned when an item exists but has expired.
	ErrExpired = errors.New("storage: item expired")

	// ErrAlreadyExists is returned when attempting to create an item that already exists.
	ErrAlreadyExists = errors.New("storage: item already exists")

	// ErrInvalidBinding is returned when token binding validation fails
	// (e.g., subject or client ID mismatch).
	ErrInvalidBinding = errors.New("storage: token binding validation failed")
)

Sentinel errors for storage operations. Use errors.Is() to check for these error types.

Functions

This section is empty.

Types

type ClientRegistry

type ClientRegistry interface {
	// ClientManager provides client lookup (GetClient)
	fosite.ClientManager

	// RegisterClient registers a new OAuth client.
	// This supports both static configuration and dynamic client registration (RFC 7591).
	// Returns ErrAlreadyExists if a client with the same ID already exists.
	RegisterClient(ctx context.Context, client fosite.Client) error
}

ClientRegistry provides client registration and lookup operations. It embeds fosite.ClientManager for client lookup (GetClient) and adds RegisterClient for dynamic client registration (RFC 7591).

type Config

type Config struct {
	// Type specifies the storage backend type. Defaults to memory.
	Type Type
}

Config configures the storage backend.

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns sensible defaults.

type PendingAuthorization

type PendingAuthorization struct {
	// ClientID is the ID of the OAuth client making the authorization request.
	ClientID string

	// RedirectURI is the client's callback URL where we'll redirect after authentication.
	RedirectURI string

	// State is the client's original state parameter for CSRF protection.
	State string

	// PKCEChallenge is the client's PKCE code challenge.
	PKCEChallenge string

	// PKCEMethod is the PKCE challenge method (must be "S256").
	PKCEMethod string

	// Scopes are the OAuth scopes requested by the client.
	Scopes []string

	// InternalState is our randomly generated state for correlating upstream callback.
	InternalState string

	// UpstreamPKCEVerifier is the PKCE code_verifier for the upstream IDP authorization.
	// This is generated when redirecting to the upstream IDP and used when exchanging
	// the authorization code. See RFC 7636.
	UpstreamPKCEVerifier string

	// UpstreamNonce is the OIDC nonce parameter sent to the upstream IDP for ID Token
	// replay protection. This is validated against the nonce claim in the returned
	// ID Token. See OIDC Core Section 3.1.2.1.
	UpstreamNonce string

	// CreatedAt is when the pending authorization was created.
	CreatedAt time.Time
}

PendingAuthorization tracks a client's authorization request while they authenticate with the upstream IDP.

type PendingAuthorizationStorage

type PendingAuthorizationStorage interface {
	// StorePendingAuthorization stores a pending authorization request.
	// The state is used to correlate the upstream IDP callback.
	StorePendingAuthorization(ctx context.Context, state string, pending *PendingAuthorization) error

	// LoadPendingAuthorization retrieves a pending authorization by internal state.
	// Returns ErrNotFound if the state does not exist.
	// Returns ErrExpired if the pending authorization has expired.
	LoadPendingAuthorization(ctx context.Context, state string) (*PendingAuthorization, error)

	// DeletePendingAuthorization removes a pending authorization.
	// Returns ErrNotFound if the state does not exist.
	DeletePendingAuthorization(ctx context.Context, state string) error
}

PendingAuthorizationStorage provides storage operations for pending authorization requests. These track the state of in-flight authorization requests while users authenticate with the upstream IDP, correlating the upstream callback with the original client request.

type RunConfig

type RunConfig struct {
	// Type specifies the storage backend type. Defaults to "memory".
	Type string `json:"type,omitempty" yaml:"type,omitempty"`
}

RunConfig is the serializable storage configuration for RunConfig. This is used when the config needs to be passed across process boundaries (e.g., in Kubernetes operator).

type Storage

type Storage interface {
	// Embed segregated interfaces for IDP tokens, pending authorizations, and client registry.
	UpstreamTokenStorage
	PendingAuthorizationStorage
	ClientRegistry

	// AuthorizeCodeStorage provides authorization code storage
	oauth2.AuthorizeCodeStorage

	// AccessTokenStorage provides access token storage
	oauth2.AccessTokenStorage

	// RefreshTokenStorage provides refresh token storage
	oauth2.RefreshTokenStorage

	// TokenRevocationStorage provides token revocation per RFC 7009
	oauth2.TokenRevocationStorage

	// PKCERequestStorage provides PKCE storage
	pkce.PKCERequestStorage

	// Close releases any resources held by the storage implementation.
	// This should be called when the storage is no longer needed.
	Close() error
}

Storage combines fosite storage interfaces with ToolHive-specific storage for upstream IDP tokens, pending authorization requests, and client registration. The auth server requires a Storage implementation; use NewMemoryStorage() for single-instance deployments or NewRedisStorage() for distributed deployments.

type Type

type Type string

Type defines the type of storage backend.

type UpstreamTokenStorage

type UpstreamTokenStorage interface {
	// StoreUpstreamTokens stores the upstream IDP tokens for a session.
	StoreUpstreamTokens(ctx context.Context, sessionID string, tokens *UpstreamTokens) error

	// GetUpstreamTokens retrieves the upstream IDP tokens for a session.
	// Returns ErrNotFound if the session does not exist.
	// Returns ErrExpired if the tokens have expired.
	// Returns ErrInvalidBinding if binding validation fails.
	GetUpstreamTokens(ctx context.Context, sessionID string) (*UpstreamTokens, error)

	// DeleteUpstreamTokens removes the upstream IDP tokens for a session.
	// Returns ErrNotFound if the session does not exist.
	DeleteUpstreamTokens(ctx context.Context, sessionID string) error
}

UpstreamTokenStorage provides storage for tokens obtained from upstream identity providers. The auth server exposes this interface via Server.UpstreamTokenStorage() for use by middleware that needs to retrieve upstream tokens (e.g., token swap middleware that replaces JWT auth with upstream IDP tokens for backend requests).

type UpstreamTokens

type UpstreamTokens struct {
	// AccessToken is the access token from the upstream IDP.
	AccessToken string

	// RefreshToken is the refresh token from the upstream IDP (if provided).
	RefreshToken string

	// IDToken is the ID token from the upstream IDP (for OIDC).
	IDToken string

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

	// Subject is the user identifier from the IDP.
	// This binding field is validated on lookup to prevent cross-session attacks
	// by ensuring the JWT "sub" claim matches this value.
	Subject string

	// ClientID is the OAuth client that initiated the authorization.
	// This binding field is validated on lookup to prevent cross-session attacks
	// by ensuring the JWT "client_id" or "azp" claim matches this value.
	ClientID string
}

UpstreamTokens represents the tokens obtained from an upstream Identity Provider, stored with binding fields for security validation.

func (*UpstreamTokens) IsExpired

func (t *UpstreamTokens) IsExpired(now time.Time) bool

IsExpired returns true if the access token has expired. The now parameter allows for deterministic testing.

Directories

Path Synopsis
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

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