formies/RATE_LIMITING.md
Mohamad.Elsena 2927013a6d Update environment configuration, add API documentation, and implement user authentication system
- Updated `.env` and added `.env.test` for environment variables.
- Introduced API documentation in `API_DOCUMENTATION.md`.
- Added authentication setup guide in `AUTHENTICATION_SETUP.md`.
- Implemented user authentication with JWT and email verification.
- Created new routes for user management and form submissions.
- Added middleware for API key authentication and error handling.
- Set up Redis for rate limiting and notifications.
- Removed obsolete files and configurations related to the previous Rust implementation.
2025-05-28 11:18:35 +02:00

4.5 KiB

Rate Limiting Documentation

Overview

This application now implements a scalable Redis-backed rate limiting system to protect against abuse and ensure fair usage of the form submission endpoints.

Rate Limiting Strategy

The /submit/:formUuid endpoint is protected by three layers of rate limiting:

1. Strict Rate Limiter (First Layer)

  • Window: 1 hour
  • Limit: 50 requests per IP address across all forms
  • Purpose: Prevents aggressive abuse from single IP addresses
  • Key: strict_ip:{ip_address}

2. General Submission Rate Limiter (Second Layer)

  • Window: 15 minutes
  • Limit: 10 requests per IP address for any form submissions
  • Purpose: Prevents rapid-fire submissions from legitimate users
  • Key: submit_ip:{ip_address}

3. Form-Specific Rate Limiter (Third Layer)

  • Window: 5 minutes
  • Limit: 3 requests per IP address per specific form
  • Purpose: Prevents spam on individual forms
  • Key: submit_form:{formUuid}:{ip_address}

Infrastructure

Redis Configuration

Development Environment

  • Service: redis:7-alpine
  • Port: 6379
  • Data Persistence: Yes (Redis AOF)
  • Volume: redis_data:/data

Production Environment

  • Service: redis:7-alpine
  • Port: 6380 (external, to avoid conflicts)
  • Data Persistence: Yes (Redis AOF)
  • Volume: redis_data:/data
  • Password Protection: Configurable via REDIS_PASSWORD
  • Health Checks: Enabled

Environment Variables

# Redis Configuration
REDIS_HOST=redis           # Redis hostname (default: redis in Docker, localhost otherwise)
REDIS_PORT=6379           # Redis port (default: 6379)
REDIS_PASSWORD=           # Optional Redis password (production recommended)

Fallback Mechanism

If Redis is unavailable, the system automatically falls back to an in-memory rate limiter:

  • Graceful Degradation: Application continues to function without Redis
  • Automatic Detection: Detects Redis availability and switches accordingly
  • Logging: Warns when falling back to memory store
  • Same Limits: Maintains the same rate limiting rules

Rate Limit Headers

When rate limits are applied, the following headers are returned:

  • RateLimit-Limit: Maximum number of requests allowed
  • RateLimit-Remaining: Number of requests remaining in window
  • RateLimit-Reset: Time when the rate limit window resets

Error Responses

When rate limits are exceeded, the API returns:

{
	"error": "Too many requests from this IP address. Please try again later."
}

The specific error message varies by rate limiter:

  • Strict: "Too many requests from this IP address. Please try again later."
  • General: "Too many form submissions from this IP address. Please try again later."
  • Form-Specific: "Too many submissions for this form from your IP address. Please try again later."

Deployment

Starting Services

Development

docker-compose up -d

Production

docker-compose -f docker-compose.prod.yml up -d

Monitoring Redis

Check Redis connection:

docker exec -it formies-redis-1 redis-cli ping

View rate limiting keys:

docker exec -it formies-redis-1 redis-cli --scan --pattern "submit_*"

Security Considerations

  1. Redis Security: In production, always use password authentication
  2. Network Security: Redis should not be exposed to public networks
  3. Data Persistence: Redis data is persisted to handle container restarts
  4. Graceful Shutdown: Application properly closes Redis connections on exit

Performance

  • Scalability: Redis-backed rate limiting scales across multiple application instances
  • Efficiency: O(1) operations for rate limit checks
  • Memory Usage: Efficient key expiration prevents memory leaks
  • High Availability: Can be configured with Redis clustering for production

Troubleshooting

Common Issues

  1. Redis Connection Failed

    • Check if Redis container is running
    • Verify environment variables
    • Check Docker network connectivity
  2. Rate Limiting Not Working

    • Verify Redis connection in application logs
    • Check if fallback to memory store is occurring
    • Ensure proper IP address detection
  3. Performance Issues

    • Monitor Redis memory usage
    • Check for connection pooling configuration
    • Verify network latency between app and Redis

Logs to Monitor

  • Redis connection status
  • Rate limiter fallback warnings
  • Rate limit exceeded events
  • Redis error messages