ratelimit

package
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 23, 2026 License: MIT, MIT Imports: 13 Imported by: 0

README

GoModularAuth Rate Limit Plugin (gomodularauth-rate-limit)

Configurable authentication and security rate limiting for GoModularAuth with distributed counter support via the optional Cache Adapter. The Rate Limit plugin prevents brute-force attacks, credential stuffing, enumeration, and denial-of-service against authentication workflows (SignIn, SignUp, PasswordReset, Email OTP, Magic Link, Phone OTP, API Keys, and Administrative actions).

Installation

go get github.com/BladiCreator/go-modular-auth/plugins/rate-limit

Quick Start

package main

import (
	"context"
	"log"
	"time"

	auth "github.com/BladiCreator/go-modular-auth"
	adaptermem "github.com/BladiCreator/go-modular-auth/adapters/memory"
	ratelimit "github.com/BladiCreator/go-modular-auth/plugins/rate-limit"
	"github.com/BladiCreator/go-modular-auth/plugins/rate-limit/plugins"
)

func main() {
	rlModule := ratelimit.New(
		// Set fail mode behavior when cache adapter fails
		ratelimit.WithDefaultFailMode(ratelimit.FailOpen),

		// Custom policy override for Sign-In
		ratelimit.WithPolicy(ratelimit.Policy{
			Action:    ratelimit.ActionSignIn,
			Algorithm: ratelimit.AlgorithmSlidingWindow,
			Limit:     5,
			Window:    1 * time.Minute,
			KeyType:   ratelimit.KeyTypeComposite, // IP + Identity
		}),

		// Custom policy for API Keys (Token Bucket)
		ratelimit.WithPolicy(ratelimit.Policy{
			Action:     ratelimit.ActionAPIKey,
			Algorithm:  ratelimit.AlgorithmTokenBucket,
			Capacity:   100,
			RefillRate: 50.0, // 50 tokens / second
			KeyType:    ratelimit.KeyTypeIdentity,
		}),
	)

	appAuth, err := auth.New(auth.Config{
		Adapter: adaptermem.NewAdapter(),
		Cache:   adaptermem.NewCache(),
		Plugins: []auth.PluginModule{rlModule},
	})
	if err != nil {
		log.Fatal(err)
	}

	// Retrieve typed capability
	limiter, err := auth.Get[plugins.RateLimit](appAuth)
	if err != nil {
		log.Fatal(err)
	}

	// Evaluate manually for custom workflows
	decision, err := limiter.Allow(context.Background(), ratelimit.Request{
		Action:   ratelimit.ActionPasswordReset,
		Identity: "user@example.com",
		IP:       "203.0.113.195",
	})
	if err != nil {
		log.Fatal(err)
	}

	if !decision.Allowed {
		log.Printf("Rate limit exceeded! Retry after %v", decision.RetryAfter)
	}
}

Detailed guide: doc/plugins/rate-limit.md.

Documentation

Overview

Package ratelimit provides distributed rate limiting capabilities (reserved module).

Index

Constants

View Source
const (
	ActionSignIn          = "signin"
	ActionSignUp          = "signup"
	ActionPasswordReset   = "password_reset"
	ActionEmailOTP        = "email_otp"
	ActionMagicLink       = "magic_link"
	ActionPhoneOTP        = "phone_otp"
	ActionAccountRecovery = "account_recovery"
	ActionAPIKey          = "api_key"
	ActionAdmin           = "admin"
)

Standard rate-limited action identifiers in GoModularAuth.

View Source
const (
	EventRateLimitExceeded auth.EventName = "ratelimit.exceeded"
	EventRateLimitReset    auth.EventName = "ratelimit.reset"
)

Rate limiting event names emitted to the GoModularAuth event bus.

View Source
const PluginID = "rate-limit"

PluginID identifies this plugin in the GoModularAuth runtime.

Variables

View Source
var (
	// ErrRateLimitExceeded indicates that the client has performed too many requests within the window.
	ErrRateLimitExceeded = errors.New("ratelimit: rate limit exceeded")

	// ErrRateLimiterUnavailable indicates an infrastructure failure when FailClosed mode is active.
	ErrRateLimiterUnavailable = errors.New("ratelimit: rate limiter backend unavailable")

	// ErrInvalidPolicy indicates an unworkable or erroneous policy definition.
	ErrInvalidPolicy = errors.New("ratelimit: invalid policy configuration")

	// ErrActionRequired indicates that an evaluation request omitted the action name.
	ErrActionRequired = errors.New("ratelimit: action is required")
)

Functions

This section is empty.

Types

type Algorithm

type Algorithm string

Algorithm specifies the mathematical throttling model applied.

const (
	// AlgorithmSlidingWindow tracks request counts within a moving window.
	AlgorithmSlidingWindow Algorithm = "sliding_window"

	// AlgorithmTokenBucket provides burst capacity with steady token refill.
	AlgorithmTokenBucket Algorithm = "token_bucket"
)

type Config

type Config struct {
	Policies        map[string]Policy
	DefaultFailMode FailMode
	AutoHooks       bool
	Clock           func() time.Time
}

Config defines the configuration options for the rate-limit plugin.

type Decision

type Decision struct {
	Allowed    bool          `json:"allowed"`
	Remaining  int64         `json:"remaining"`
	Limit      int64         `json:"limit"`
	ResetAfter time.Duration `json:"reset_after"`
	RetryAfter time.Duration `json:"retry_after"`
	Action     string        `json:"action"`
	Key        string        `json:"key"`
}

Decision represents the outcome of a rate limit evaluation.

type ExceededPayload

type ExceededPayload struct {
	Action     string        `json:"action"`
	Key        string        `json:"key"`
	RetryAfter time.Duration `json:"retry_after"`
	OccurredAt time.Time     `json:"occurred_at"`
}

ExceededPayload describes a throttled request event for security auditing.

type FailMode

type FailMode string

FailMode determines behavior when the cache/counter infrastructure is unavailable.

const (
	// FailOpen permits requests when the counter store is unreachable (prioritizes availability).
	FailOpen FailMode = "fail_open"

	// FailClosed denies requests when the counter store is unreachable (prioritizes strict defense).
	FailClosed FailMode = "fail_closed"
)

type KeyType

type KeyType string

KeyType specifies which attributes form the rate limit counter key.

const (
	// KeyTypeIP rate limits solely based on client IP address.
	KeyTypeIP KeyType = "ip"

	// KeyTypeIdentity rate limits based on user ID, email hash, or username hash.
	KeyTypeIdentity KeyType = "identity"

	// KeyTypeComposite rate limits based on both IP and Identity.
	KeyTypeComposite KeyType = "composite"
)

type Module

type Module struct {
	// contains filtered or unexported fields
}

Module implements auth.PluginModule for configurable authentication rate limiting.

func New

func New(opts ...Option) *Module

New creates an installable rate-limiting PluginModule with options.

func (*Module) ID

func (m *Module) ID() string

ID returns the module's unique identifier.

func (*Module) Init

func (m *Module) Init(h *auth.Host) error

Init configures infrastructure, provides the typed Capability, and binds automatic Core workflow hooks when enabled.

type Option

type Option func(*Config)

Option modifies Config settings.

func WithAutoHooks

func WithAutoHooks(enabled bool) Option

WithAutoHooks enables or disables automated Core workflow interception (BeforeSignIn / BeforeSignUp).

func WithClock

func WithClock(clk func() time.Time) Option

WithClock overrides the system clock (useful in deterministic testing).

func WithDefaultFailMode

func WithDefaultFailMode(m FailMode) Option

WithDefaultFailMode configures whether throttling fails open or closed when the cache is down.

func WithPolicy

func WithPolicy(p Policy) Option

WithPolicy sets or overrides a rate limiting policy for an action.

type Policy

type Policy struct {
	Action     string        `json:"action"`
	Algorithm  Algorithm     `json:"algorithm"`
	Limit      int64         `json:"limit"`
	Window     time.Duration `json:"window"`
	Capacity   int64         `json:"capacity"`
	RefillRate float64       `json:"refill_rate"`
	KeyType    KeyType       `json:"key_type"`
	FailMode   FailMode      `json:"fail_mode"`
}

Policy defines the rate limiting parameters applied to an action.

func (Policy) BuildKey

func (p Policy) BuildKey(req Request) string

BuildKey generates a strictly namespaced, collision-resistant cache key. Sensitive identifiers (passwords, raw tokens, full emails) are never used in plaintext; identities are hashed with SHA-256 to protect privacy and prevent collisions.

type RateLimit

type RateLimit interface {
	// Check evaluates whether a request exceeds configured rate limits without consuming capacity.
	Check(ctx context.Context, req Request) (*Decision, error)

	// Allow evaluates and consumes one token if within limits, returning the full evaluation decision.
	Allow(ctx context.Context, req Request) (*Decision, error)

	// Require checks and consumes a token, returning ErrRateLimitExceeded if throttled.
	Require(ctx context.Context, req Request) error

	// Reset clears active rate limit counters for a given request target (e.g. upon successful authentication).
	Reset(ctx context.Context, req Request) error

	// Policy retrieves the currently configured policy for an action.
	Policy(action string) (Policy, bool)

	// SetPolicy registers or dynamically overrides the policy for an action.
	SetPolicy(policy Policy) error
}

RateLimit represents the strongly typed capability provided by the rate-limit plugin. Applications retrieve this capability via auth.Get[plugins.RateLimit]().

type Request

type Request struct {
	Action    string `json:"action"`
	IP        string `json:"ip,omitempty"`
	Identity  string `json:"identity,omitempty"`
	CustomKey string `json:"custom_key,omitempty"`
}

Request defines the context and caller attributes evaluated by the rate limiter.

Directories

Path Synopsis
Package plugins exposes capability aliases for GoModularAuth plugins.
Package plugins exposes capability aliases for GoModularAuth plugins.

Jump to

Keyboard shortcuts

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