A fair, highly scalable virtual queueing system with built-in IP-based rate limiting that protects backends during high-traffic events. Instead of overwhelming your servers, Gatekeeper places users in a cryptographically secure queue and controls access to your protected resources.
┌─────────────────────────────────────────────────────────────┐
│ GATEKEEPER API │
│ (FastAPI + Redis + PostgreSQL + Background Workers) │
│ │
│ Endpoints: /queue/enqueue, /queue/status, │
│ /queue/verify, /queue/finish, /config │
└─────────────────────────────────────────────────────────────┘
▲ ▲
│ │
┌───────────┘ └───────────┐
│ │
│ Frontend Calls Backend Calls │
│ /enqueue, /status /verify, /finish
│ │
┌───────┴────────┐ ┌───────┴────────┐
│ Browser │ │ Business │
│ │ │ Backend │
│ client_side.js │ 1. enqueue(userId) │ │
│ (Frontend) │ 2. waitUntilReady() │ server_side.py │
│ │ 3. Redirect to /checkout?jwt=.. │ (Backend) │
│ │ ────────────────────────────>│ │
└────────────────┘ │ 4. verify(jwt) │
│ 5. Process │
│ 6. finish(jwt) │
└────────────────┘
- Docker & Docker Compose
- Python 3.11+ (for local development)
git clone https://github.com/yourusername/GatekeeperAPI.git
cd GatekeeperAPI
# Create environment file
cp .env.example .envEdit .env and set:
JWT_SECRET=your_super_secret_random_string_here
BUSINESS_IDS=your_api_key_1:your_api_key_2
DATABASE_URL=postgresql+asyncpg://user:password@db:5432/gatekeeperdb
REDIS_URL=redis://redis:6379docker-compose up -dThis starts:
- API Server on
http://localhost:8000 - Background Workers for queue processing
- PostgreSQL database
- Redis cache
curl http://localhost:8000/health
# Expected: {"status": "healthy"}curl -X POST http://localhost:8000/config \
-H "business_id: your_api_key_1" \
-H "Content-Type: application/json" \
-d '{
"admission_limit": 10,
"admission_frequency": 5,
"jwt_expiry_seconds": 120,
"ready_ttl_seconds": 300,
"ip_enqueue_limit": 100,
"ip_enqueue_limit_interval": 60,
"ip_status_polling_limit": 60,
"ip_status_polling_limit_interval": 60
}'Configuration Explained:
admission_limit: 10→ Allow 10 users per intervaladmission_frequency: 5→ Process queue every 5 secondsjwt_expiry_seconds: 120→ Tokens expire after 2 minutes (min: 60, max: 600)ready_ttl_seconds: 300→ Ready state lasts 5 minutes (min: 60, max: 3600)ip_enqueue_limit: 100→ Max 100 enqueue requests per window (rate limit per IP)ip_enqueue_limit_interval: 60→ Enqueue rate limit window in secondsip_status_polling_limit: 60→ Max 60 status polls per window (rate limit per IP)ip_status_polling_limit_interval: 60→ Status polling rate limit window in seconds
For local development with api server hot-reload, real time code sync into the container (volume mount) and debugging:
# Start development environment
docker-compose -f docker-compose.dev.yml up -d
# Stop development environment
docker-compose -f docker-compose.dev.yml down# Create virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
pip install -r dev_requirements.txt
# Set up local environment
cp .env.example .env
# Edit .env with local settings (Redis/PostgreSQL running locally)
# Run API with hot-reload
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
# In another terminal, run workers
python -m app.worker.run_workers
# Run tests
pytest app/tests/ -vDevelopment Features:
- 🔄 Hot-reload on code changes
- 🐛 Debug mode enabled
- 📊 Detailed error traces
- 🧪 Access to test suite
All endpoints (except /health, /docs) require:
business_idheader: Your API key
Token-based endpoints also require:
jwtheader: User's queue token
Add a user to the waiting queue.
POST /queue/enqueue
Headers:
business_id: your_api_key
user_id: user123
Response:
{
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", // Empty string if already queued/ready
"position": 42,
"message": "User enqueued successfully."
}Note: If user is already in queue or ready state, JWT will be an empty string.
Poll queue position and ready state. Auto-refreshes JWT if expired.
GET /queue/status
Headers:
business_id: your_api_key
jwt: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Response:
{
"warning_msg": null, // Warning if user not found
"jwt_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", // Regenerated if expired
"position": 35, // null if ready or not found
"ready": false
}Note: Always use the returned jwt_token for subsequent requests.
Simple boolean check for backend validation.
GET /queue/verify
Headers:
business_id: your_api_key
jwt: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Response:
{
"message": "User is ready",
"ready": true
}Remove user from ready state after serving.
DELETE /queue/finish
Headers:
business_id: your_api_key
jwt: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Response:
{
"status": "ready_cleared", // or "not_ready"
"message": "User removed from ready state"
}Retrieve current business configuration.
GET /config
Headers:
business_id: your_api_key
Response:
{
"message": "Configuration retrieved successfully",
"updated_config": {
"ip_enqueue_limit": 1,
"ip_enqueue_limit_interval": 1,
"ip_status_polling_limit": 1,
"ip_status_polling_limit_interval": 1,
"admission_limit": 1000,
"admission_frequency": 5,
"jwt_expiry_seconds": 300,
"ready_ttl_seconds": 600
}
}Update business-specific settings.
POST /config
Headers:
business_id: your_api_key
Content-Type: application/json
Body:
{
"admission_limit": 20,
"admission_frequency": 10
}
Response:
{
"message": "Configuration updated successfully",
"updated_config": { ... }
}No authentication required.
GET /health
Response:
{
"status": "healthy"
}Interactive API documentation (Swagger UI). No authentication required.
GET /docs
Browser: Opens interactive API documentation with "Try it out" functionalityAlternative: Visit /redoc for ReDoc-style documentation.