This project implements a robust rate limiting system for MinIO S3 API using HAProxy 3.0 and Lua scripts. The system provides dynamic, hot-reloadable rate limiting based on API key authentication with zero external dependencies.
┌─────────────┐ ┌────────────────┐ ┌───────────────┐
│ S3 Clients │ ───────▶│ HAProxy 3.0 │ ───────▶│ MinIO Cluster │
│ (AWS SDK) │ │ Rate Limiting │ │ (S3 Storage) │
└─────────────┘ └────────────────┘ └───────────────┘
▲
│
┌──────┴───────┐
│ Config Maps │
└──────────────┘
- Function: Authenticates and rate limits S3 API requests
- Configuration:
haproxy/haproxy.cfgwith dynamic map files - Benefits: No restart required for config changes
- Authentication Script: Extracts API keys from various S3 auth methods
- Rate Limiting Script: Applies tiered rate limits based on API key group
- File Location:
haproxy/lua/*.lua
- API Key Groups:
haproxy/config/api_key_groups.map - Rate Limits:
haproxy/config/rate_limits_*.map - Hot-Reloadable: Changes take effect immediately
- Function: S3-compatible object storage
- Configuration: Docker container with volume mounts
- Authentication: Service accounts with IAM policies
- Centralized Versions: All versions defined in
versions.mk - Verification System:
scripts/verify_versions.shensures consistency - Environment Variables:
scripts/export_versions.shfor version exports
- Request Arrival: Client sends S3 API request to HAProxy
- Authentication: Lua script extracts API key from request
- Group Assignment: API key mapped to rate limit group
- Rate Limiting: Request counted against tier-specific limits
- Forwarding/Rejection: Request forwarded to MinIO or rejected based on limits
- Response: MinIO response returned to client or error if rate limited
- Premium: Highest limits for priority workloads
- Standard: Normal limits for regular applications
- Basic: Lower limits for less critical workloads
- Default: Fallback limits for unrecognized keys
- Edit the appropriate map file in
haproxy/config/ - Changes take effect immediately without restart
- Add the API key to
haproxy/config/api_key_groups.map - Format:
<api_key> <group_name>
- Update central version in
versions.mk - Run
make verify-versionsto check consistency - Use
source ./scripts/export_versions.shfor environment variables
- Use
make testto run validation tests - Use
cmd/ratelimit-testtool for performance testing
- Clone repository
- Run
make setupto prepare environment - Run
docker-compose upto start services - Access HAProxy stats on port 8404
- Access MinIO console on port 9001
GitHub Actions workflows for:
- Linting & validation
- Integration testing
- Version verification
- Performance benchmarking
- HAProxy 3.0
- Lua 5.3
- Go 1.24
- Docker & Docker Compose 2.26.0+
- SSL/TLS termination
- Support for all S3 authentication methods
- Protection against API key abuse
- Secure key extraction from various auth methods
For detailed documentation, see:
This directory contains the consolidated CI/CD workflow for validating and testing the MinIO Rate Limiting project.
The single CI workflow runs on every push to main/master branches and pull requests. It includes 5 orchestrated jobs:
- Extracts versions from
versions.mk - Runs environment check using
make check-versions - Provides version outputs for other jobs
Depends on: setup
- Sets up CI environment using
make ci-setup - Runs all linting and validation using
make ci-validate - Includes: Go linting, HAProxy config validation, Lua script validation
Depends on: setup
- Runs Go unit tests using
make ci-test - Generates and uploads test coverage reports
Depends on: lint, setup
- Sets up CI environment using
make ci-setup - Runs full validation using
make validate-all - Starts services using
make up - Runs integration tests using
make test-quick - Stops services using
make down - Uploads integration test results
Depends on: lint, test, setup
- Builds test tool and verifies functionality
- Runs version verification using
make verify-versions
- Single consolidated workflow: Eliminates duplication from previous multiple workflows
- Make-based execution: Uses proven Makefile targets for all operations
- Proper job dependencies: Ensures logical execution order and parallel efficiency
- Version management: Centralized version extraction from
versions.mk - Docker Compose integration: Automatic detection of v1 vs v2 via make system
You can run the same checks locally using Make targets:
# Environment setup and checks
make check-versions # Check if environment meets requirements
make ci-setup # Set up CI environment locally
make versions # Display current project versions
# Linting and validation
make lint # Run all linting checks
make lint-go # Lint Go code only
make lint-haproxy # Validate HAProxy configuration only
make lint-lua # Validate Lua scripts only
make validate-all # Run comprehensive validation
# Testing
make ci-test # Run tests with CI settings
make ci-validate # Run validations with CI settings
make test-quick # Run quick integration tests
# Docker services
make up # Start all services
make status # Check service status
make down # Stop all servicesAll versions are centrally managed in versions.mk:
# Version management commands
make update-versions # Update all versions
make verify-versions # Verify version consistency
make update-go-version # Update Go version in go.mod filesThe GitHub Actions workflow uses Ubuntu latest runners with versions specified in versions.mk:
- Go: 1.24+ (from
GO_VERSION) - HAProxy: 3.0+ (from
HAPROXY_VERSION) - Lua: 5.3+ (from
LUA_VERSION) - Docker: 20.10.0+ (from
DOCKER_MINIMUM_VERSION) - Docker Compose: 2.26.0+ (from
DOCKER_COMPOSE_VERSION)
The workflow automatically sets:
CI=true- Enables CI mode in make targetsCI_NO_COLOR=true- Disables colors for clean logsHAPROXY_VERSION- From versions.mk for Docker ComposeMINIO_VERSION- From versions.mk for Docker Compose
To add new tests:
- Add test files to the appropriate directories
- Update Makefile targets if needed (in
*_targets.mkfiles) - Run
make validate-alllocally to ensure everything passes - Commit and push - CI will run automatically
If GitHub Actions builds fail:
- Check the specific job logs for error messages
- Verify versions in
versions.mkare correct - Try running the failing make target locally:
make ci-setupfor setup issuesmake ci-validatefor validation failuresmake ci-testfor test failuresmake test-quickfor integration test issues
- Check Docker Compose compatibility with
make up - Verify all required scripts exist and are executable