AuthGate provides built-in rate limiting to protect against brute force attacks and API abuse. This guide covers configuration and deployment scenarios.
Rate limiting is enabled by default and uses an in-memory store suitable for single-instance deployments. For multi-pod/multi-instance deployments, Redis-backed rate limiting ensures consistent rate limits across all instances.
Best for:
- Single instance deployments
- Development environments
- Simple deployments without scaling requirements
Configuration:
ENABLE_RATE_LIMIT=true
RATE_LIMIT_STORE=memory # or omit this line (default)Limitations:
- Each instance has independent rate limits
- Example: With 3 pods and
LOGIN_RATE_LIMIT=5, users can make 15 requests/minute (5 per pod) - Not suitable for load-balanced deployments
Best for:
- Multi-pod Kubernetes deployments
- Load-balanced instances
- Production environments with horizontal scaling
Configuration:
ENABLE_RATE_LIMIT=true
RATE_LIMIT_STORE=redis
REDIS_ADDR=redis-service:6379
REDIS_PASSWORD=your-redis-password # Optional
REDIS_DB=0Benefits:
- Shared rate limit state across all pods
- Accurate global rate limiting (5 req/min = 5 total across all pods)
- Survives pod restarts (Redis persists state)
| Endpoint | Requests/Minute | Purpose |
|---|---|---|
/login |
5 | Prevent password brute force |
/oauth/device/code |
10 | Prevent device code spam |
/oauth/token |
20 | Allow polling while preventing abuse |
/device/verify |
10 | Prevent user code guessing |
/oauth/register |
5 | Prevent registration spam |
/oauth/introspect |
20 | Prevent client secret brute force |
Adjust limits via environment variables:
# More permissive (e.g., high-traffic API)
LOGIN_RATE_LIMIT=20
TOKEN_RATE_LIMIT=60
# More restrictive (e.g., security-critical)
LOGIN_RATE_LIMIT=3
DEVICE_VERIFY_RATE_LIMIT=5
# Dynamic client registration and introspection
DYNAMIC_CLIENT_REGISTRATION_RATE_LIMIT=10
INTROSPECT_RATE_LIMIT=50Not recommended for production:
ENABLE_RATE_LIMIT=false# docker-compose.yml
services:
authgate:
image: authgate:latest
environment:
- ENABLE_RATE_LIMIT=true
- RATE_LIMIT_STORE=memory # Default
- LOGIN_RATE_LIMIT=5# kubernetes/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: authgate
spec:
replicas: 3 # Multiple pods
template:
spec:
containers:
- name: authgate
image: authgate:latest
env:
- name: ENABLE_RATE_LIMIT
value: "true"
- name: RATE_LIMIT_STORE
value: "redis"
- name: REDIS_ADDR
value: "redis-service:6379"
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secret
key: password
---
apiVersion: v1
kind: Service
metadata:
name: redis-service
spec:
selector:
app: redis
ports:
- port: 6379
targetPort: 6379# nginx.conf
upstream authgate {
server authgate-1:8080;
server authgate-2:8080;
server authgate-3:8080;
}
server {
listen 80;
location / {
proxy_pass http://authgate;
}
}# Each AuthGate instance
ENABLE_RATE_LIMIT=true
RATE_LIMIT_STORE=redis
REDIS_ADDR=redis.example.com:6379# Docker
docker run -d --name redis -p 6379:6379 redis:7-alpine
# Environment
REDIS_ADDR=localhost:6379REDIS_ADDR=redis-cluster.prod.example.com:6379
REDIS_PASSWORD=your-strong-password
REDIS_DB=1 # Use dedicated database# Use Redis Sentinel for HA
REDIS_ADDR=sentinel-1:26379,sentinel-2:26379,sentinel-3:26379
REDIS_PASSWORD=your-passwordRate limiting failures are logged:
# Check logs for rate limiting issues
docker logs authgate | grep -i "rate"Verify Redis connectivity on startup:
2024/01/01 12:00:00 Rate limiting enabled (store: redis)
2024/01/01 12:00:00 Redis rate limiting configured: redis-service:6379 (DB: 0)
When a client is rate limited, a 429 response is returned:
{
"error": "rate_limit_exceeded",
"error_description": "Too many requests. Please try again later."
}Cause: Redis server unreachable or incorrect address
Solution:
- Verify Redis is running:
redis-cli ping - Check
REDIS_ADDRconfiguration - Verify network connectivity
- Check Redis password if authentication is enabled
Cause: Using memory store with multiple pods
Solution: Switch to Redis store:
RATE_LIMIT_STORE=redis
REDIS_ADDR=your-redis-service:6379Cause: Limits too restrictive or shared IP (NAT/proxy)
Solutions:
-
Increase rate limits:
LOGIN_RATE_LIMIT=10
-
Configure reverse proxy to preserve client IPs:
proxy_set_header X-Forwarded-For $remote_addr;
Cause: Rate limiter keys accumulating
Solution: Verify cleanup is working:
# Check Redis keys
redis-cli KEYS "ratelimit:*"
# Set TTL on keys (automatic with limiter)
# Increase cleanup interval if needed
RATE_LIMIT_CLEANUP_INTERVAL=10m- Use Redis in production: Always use Redis store for multi-instance deployments
- Monitor Redis health: Set up Redis monitoring and alerting
- Test rate limits: Verify limits with load testing before production
- Log rate limit events: Monitor for unusual patterns
- Adjust based on traffic: Start conservative, increase as needed
- Use Redis persistence: Enable AOF or RDB for Redis durability
- Separate Redis instance: Use dedicated Redis for rate limiting (optional)
- Latency: ~1ms (in-memory)
- Throughput: 10,000+ req/s per instance
- Memory: ~1KB per active IP
- Latency: ~2-5ms (network + Redis)
- Throughput: 5,000+ req/s (depends on Redis)
- Memory: ~1KB per active IP (stored in Redis)
- Rate limiting is per IP address
- Use
X-Forwarded-Forheader when behind proxy/load balancer - Consider additional WAF rules for sophisticated attacks
- Rate limiting is one layer; combine with other security measures
- Review logs regularly for attack patterns
- Adjust limits based on your threat model
For high-security environments:
# Very restrictive limits
LOGIN_RATE_LIMIT=3 # 3 login attempts per minute
LOGIN_RATE_LIMIT_BURST=1 # No burst (memory store only)
DEVICE_CODE_RATE_LIMIT=5 # 5 device codes per minute
TOKEN_RATE_LIMIT=10 # 10 token requests per minute
DEVICE_VERIFY_RATE_LIMIT=5 # 5 verifications per minute
# Use Redis for consistent enforcement
RATE_LIMIT_STORE=redis
REDIS_ADDR=redis:6379For internal APIs or development:
# More permissive limits
LOGIN_RATE_LIMIT=20 # 20 login attempts per minute
DEVICE_CODE_RATE_LIMIT=30 # 30 device codes per minute
TOKEN_RATE_LIMIT=60 # 60 token requests per minute (every second)
DEVICE_VERIFY_RATE_LIMIT=30 # 30 verifications per minute
# Memory store is fine for single instance
RATE_LIMIT_STORE=memory-
Deploy Redis:
kubectl apply -f redis-deployment.yaml
-
Update AuthGate configuration:
RATE_LIMIT_STORE=redis REDIS_ADDR=redis-service:6379
-
Rolling restart (Kubernetes):
kubectl rollout restart deployment/authgate
-
Verify:
kubectl logs -f deployment/authgate | grep "Redis rate limiting configured"