Documentation
¶
Overview ¶
Rate limiting middleware with pluggable backends. Supports in-memory (single instance) and Redis (multi-instance) backends. Set REDIS_URL to enable Redis backend; falls back to in-memory if not set.
Index ¶
- Variables
- func APIKeyAuth(s *store.Store) gin.HandlerFunc
- func AdminOnly() gin.HandlerFunc
- func IssueJWT(secret, userID, email, name string, isAdmin bool, ttl time.Duration) (string, error)
- func LicenseBruteForceGuard(bf *BruteForceProtection) gin.HandlerFunc
- func PrometheusMetrics() gin.HandlerFunc
- func RateLimit(rate int, window time.Duration) gin.HandlerFunc
- func RateLimitByIP(rate int, window time.Duration) gin.HandlerFunc
- func RequestID() gin.HandlerFunc
- func RequireScope(scope string) gin.HandlerFunc
- func SessionAuth(secret string, adminCheck ...AdminChecker) gin.HandlerFunc
- func SetRateLimitBackend(b RateLimitBackend)
- type AdminChecker
- type BruteForceProtection
- type Claims
- type RateLimitBackend
- type RedisClient
- type RedisResult
Constants ¶
This section is empty.
Variables ¶
var ( // Business metrics LicenseActivations = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "keygate_license_activations_total", Help: "Total license activations", }, []string{"product_id", "status"}, ) LicenseVerifications = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "keygate_license_verifications_total", Help: "Total license verifications", }, []string{"product_id", "result"}, ) WebhookDeliveries = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "keygate_webhook_deliveries_total", Help: "Total webhook delivery attempts", }, []string{"status"}, ) EmailDeliveries = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "keygate_email_deliveries_total", Help: "Total email delivery attempts", }, []string{"status"}, ) ActiveLicenses = promauto.NewGauge( prometheus.GaugeOpts{ Name: "keygate_active_licenses", Help: "Current number of active licenses", }, ) BruteForceBlocks = promauto.NewCounter( prometheus.CounterOpts{ Name: "keygate_brute_force_blocks_total", Help: "Total brute force lockouts triggered", }, ) )
Functions ¶
func APIKeyAuth ¶
func APIKeyAuth(s *store.Store) gin.HandlerFunc
APIKeyAuth validates the Bearer token as an API key and injects the product context.
func AdminOnly ¶
func AdminOnly() gin.HandlerFunc
func LicenseBruteForceGuard ¶
func LicenseBruteForceGuard(bf *BruteForceProtection) gin.HandlerFunc
LicenseBruteForceGuard is a middleware that checks brute-force state before processing.
func PrometheusMetrics ¶
func PrometheusMetrics() gin.HandlerFunc
PrometheusMetrics is a Gin middleware that records HTTP metrics.
func RateLimit ¶
func RateLimit(rate int, window time.Duration) gin.HandlerFunc
RateLimit creates a rate limiting middleware using the configured backend.
func RateLimitByIP ¶
func RateLimitByIP(rate int, window time.Duration) gin.HandlerFunc
RateLimitByIP creates a rate limiter keyed by IP only.
func RequestID ¶
func RequestID() gin.HandlerFunc
RequestID adds a unique request ID to every request for tracing.
func RequireScope ¶
func RequireScope(scope string) gin.HandlerFunc
RequireScope checks the API key has a required scope.
func SessionAuth ¶
func SessionAuth(secret string, adminCheck ...AdminChecker) gin.HandlerFunc
SessionAuth validates a JWT from the Authorization header or session cookie. Admin status is checked at request time (from DB, not JWT claims) for security — this ensures role changes take effect immediately without waiting for JWT expiry.
func SetRateLimitBackend ¶
func SetRateLimitBackend(b RateLimitBackend)
SetRateLimitBackend sets the global rate limit backend (call once at startup).
Types ¶
type AdminChecker ¶
AdminChecker checks if a user has admin privileges by user ID. Injected at startup — queries the database for the user's role.
type BruteForceProtection ¶
type BruteForceProtection struct {
// contains filtered or unexported fields
}
BruteForceProtection tracks failed authentication attempts and blocks IPs/keys that exceed the threshold. Uses exponential backoff.
func NewBruteForceProtection ¶
func NewBruteForceProtection(maxFails int, lockout, maxLockout, window time.Duration) *BruteForceProtection
func (*BruteForceProtection) IsBlocked ¶
func (bf *BruteForceProtection) IsBlocked(key string) (bool, time.Duration)
IsBlocked checks if a key is currently locked out.
func (*BruteForceProtection) RecordFailure ¶
func (bf *BruteForceProtection) RecordFailure(key string)
RecordFailure records a failed attempt for a key (IP or license key).
func (*BruteForceProtection) RecordSuccess ¶
func (bf *BruteForceProtection) RecordSuccess(key string)
RecordSuccess clears the failure record for a key.
type RateLimitBackend ¶
RateLimitBackend abstracts the rate limiting storage.
func NewMemoryBackend ¶
func NewMemoryBackend() RateLimitBackend
func NewRedisBackend ¶
func NewRedisBackend(client RedisClient) RateLimitBackend
NewRedisBackend creates a Redis-backed rate limiter.
type RedisClient ¶
type RedisClient interface {
Eval(ctx context.Context, script string, keys []string, args ...interface{}) RedisResult
}
RedisClient is a minimal interface for Redis operations needed by rate limiting. Compatible with github.com/redis/go-redis/v9.
type RedisResult ¶
RedisResult is the minimal result interface.