Documentation
¶
Overview ¶
Package ratelimit provides HTTP rate limiting middleware with support for per-principal and per-application rate limits.
The package supports multiple storage backends (in-memory, Redis) and integrates with Cedar policies for dynamic tier-based rate limiting.
Index ¶
- Variables
- func NewRedisClient(cfg *RedisConfig) redis.UniversalClient
- type CoreAPIResolver
- type CoreAPIResolverOption
- type KeyFunc
- type Limit
- type LimitResolver
- type Limiter
- type MemoryOption
- type MemoryStorage
- type Option
- type RedisConfig
- type RedisOption
- type RedisStorage
- type Result
- type StaticResolver
- type Storage
- type TieredResolver
Constants ¶
This section is empty.
Variables ¶
var ( ErrRateLimitExceeded = errors.New("rate limit exceeded") ErrStorageFailure = errors.New("rate limit storage failure") )
Common errors returned by the rate limiter.
Functions ¶
func NewRedisClient ¶
func NewRedisClient(cfg *RedisConfig) redis.UniversalClient
NewRedisClient creates a Redis client from configuration.
Types ¶
type CoreAPIResolver ¶
type CoreAPIResolver struct {
// contains filtered or unexported fields
}
CoreAPIResolver adapts coreapi.PolicyStore to the LimitResolver interface. It looks up rate limit policies based on the OAuth client ID from JWT claims.
func NewCoreAPIResolver ¶
func NewCoreAPIResolver(store coreapi.PolicyStore, opts ...CoreAPIResolverOption) *CoreAPIResolver
NewCoreAPIResolver creates a LimitResolver that uses coreapi.PolicyStore.
func (*CoreAPIResolver) GetPolicyForRequest ¶
func (r *CoreAPIResolver) GetPolicyForRequest(ctx context.Context, req *http.Request) *coreapi.RateLimitPolicy
GetPolicyForRequest returns the policy that would be applied to a request. Useful for debugging and displaying policy info in responses.
func (*CoreAPIResolver) InvalidateCache ¶
func (r *CoreAPIResolver) InvalidateCache(clientID string)
InvalidateCache clears the policy cache.
type CoreAPIResolverOption ¶
type CoreAPIResolverOption func(*CoreAPIResolver)
CoreAPIResolverOption configures a CoreAPIResolver.
func WithResolverCache ¶
func WithResolverCache(ttl time.Duration) CoreAPIResolverOption
WithResolverCache enables caching of policy lookups.
type KeyFunc ¶
KeyFunc extracts the rate limit key from a request. Common implementations include extracting principal ID or client ID from JWT.
func ClientEndpointKey ¶
func ClientEndpointKey() KeyFunc
ClientEndpointKey is a convenience function combining ClientKey with EndpointKey.
func ClientKey ¶
func ClientKey() KeyFunc
ClientKey returns a KeyFunc that extracts the OAuth client ID (azp) from JWT claims. Falls back to IP address if no client ID is present.
func CompositeKey ¶
func CompositeKey() KeyFunc
CompositeKey returns a KeyFunc that combines principal and client IDs. Format: "pid:{principal_id}:client:{client_id}" or fallback to IP.
func EndpointKey ¶
EndpointKey wraps another KeyFunc to add endpoint-specific rate limiting. Format: "{inner_key}:path:{path}:method:{method}"
func PrincipalEndpointKey ¶
func PrincipalEndpointKey() KeyFunc
PrincipalEndpointKey is a convenience function combining PrincipalKey with EndpointKey.
func PrincipalKey ¶
func PrincipalKey() KeyFunc
PrincipalKey returns a KeyFunc that extracts the principal ID from JWT claims. Falls back to IP address if no principal is authenticated.
type Limit ¶
type Limit struct {
// Rate is the number of requests allowed per Period.
Rate int
// Period is the time window for the rate limit (e.g., time.Minute).
Period time.Duration
// Burst is the maximum number of requests allowed in a single burst.
// If zero, defaults to Rate.
Burst int
}
Limit defines rate limit parameters.
func DefaultLimit ¶
func DefaultLimit() Limit
DefaultLimit returns a sensible default rate limit (100 requests per minute).
type LimitResolver ¶
type LimitResolver interface {
// Resolve returns the rate limit for the given key and context.
// The key is typically derived from the principal ID or client ID.
Resolve(ctx context.Context, key string, r *http.Request) Limit
}
LimitResolver determines the rate limit for a given request. This allows dynamic rate limiting based on user tier, endpoint, etc.
type Limiter ¶
type Limiter struct {
// contains filtered or unexported fields
}
Limiter is the main rate limiter type.
type MemoryOption ¶
type MemoryOption func(*MemoryStorage)
MemoryOption configures MemoryStorage.
func WithCleanupInterval ¶
func WithCleanupInterval(d time.Duration) MemoryOption
WithCleanupInterval sets the interval for cleaning up expired windows.
type MemoryStorage ¶
type MemoryStorage struct {
// contains filtered or unexported fields
}
MemoryStorage is an in-memory rate limit storage using sliding window algorithm. Suitable for single-instance deployments and development/testing.
func NewMemoryStorage ¶
func NewMemoryStorage(opts ...MemoryOption) *MemoryStorage
NewMemoryStorage creates a new in-memory rate limit storage.
type Option ¶
type Option func(*Limiter)
Option configures a Limiter.
func WithKeyFunc ¶
WithKeyFunc sets the function to extract rate limit keys from requests.
func WithObservability ¶
func WithObservability(obs *observability.Observability) Option
WithObservability sets the observability provider for metrics and tracing.
func WithResolver ¶
func WithResolver(resolver LimitResolver) Option
WithResolver sets a custom limit resolver.
type RedisConfig ¶
type RedisConfig struct {
// Addr is the Redis server address (e.g., "localhost:6379").
Addr string
// Password is the Redis password (optional).
Password string
// DB is the Redis database number (default 0).
DB int
// PoolSize is the maximum number of connections (default 10).
PoolSize int
// Cluster enables Redis Cluster mode.
Cluster bool
// ClusterAddrs are the cluster node addresses (used when Cluster is true).
ClusterAddrs []string
}
RedisConfig contains configuration for connecting to Redis.
type RedisOption ¶
type RedisOption func(*RedisStorage)
RedisOption configures RedisStorage.
func WithKeyPrefix ¶
func WithKeyPrefix(prefix string) RedisOption
WithKeyPrefix sets a prefix for all rate limit keys in Redis.
type RedisStorage ¶
type RedisStorage struct {
// contains filtered or unexported fields
}
RedisStorage is a Redis-backed rate limit storage using sliding window algorithm. Suitable for distributed deployments where multiple instances share rate limit state.
func NewRedisStorage ¶
func NewRedisStorage(client redis.UniversalClient, opts ...RedisOption) *RedisStorage
NewRedisStorage creates a new Redis-backed rate limit storage. The client can be *redis.Client, *redis.ClusterClient, or any UniversalClient.
func (*RedisStorage) Allow ¶
Allow implements Storage.Allow using a sliding window algorithm with Redis.
func (*RedisStorage) Close ¶
func (r *RedisStorage) Close() error
Close implements Storage.Close. Note: This does NOT close the Redis client since it may be shared.
type Result ¶
type Result struct {
// Allowed is true if the request should be permitted.
Allowed bool
// Remaining is the number of requests remaining in the current window.
Remaining int
// ResetAt is when the rate limit window resets.
ResetAt time.Time
// RetryAfter is the duration to wait before retrying (only set if not allowed).
RetryAfter time.Duration
}
Result contains the outcome of a rate limit check.
type StaticResolver ¶
type StaticResolver struct {
Limit Limit
}
StaticResolver always returns the same limit.
type Storage ¶
type Storage interface {
// Allow checks if a request should be allowed and updates the counter.
// Returns the result of the check and any error.
Allow(ctx context.Context, key string, limit Limit) (Result, error)
// Reset clears the rate limit state for a key.
Reset(ctx context.Context, key string) error
// Close releases any resources held by the storage.
Close() error
}
Storage defines the interface for rate limit state storage.