Skip to content

Latest commit

 

History

History
505 lines (404 loc) · 18.3 KB

File metadata and controls

505 lines (404 loc) · 18.3 KB

Auth Engine

A high-performance, enterprise-grade User Management System built with FastAPI, MongoDB, and Redis. Auth Engine provides secure user authentication, role-based access control, advanced caching, rate limiting, and comprehensive CRUD operations.

📋 Table of Contents

🚀 Features

Core Functionality

  • User Management: Complete CRUD operations for user accounts
  • Authentication & Authorization: JWT-based authentication with role-based access control
  • Role-Based Access Control: Admin, Manager, and User roles with different permissions
  • User Registration: Secure user creation with validation
  • User Profile Management: Update user information and manage account status

Performance & Scalability

  • Redis Caching: Intelligent caching with cache invalidation strategies
  • Rate Limiting: Dynamic rate limiting based on user roles and IP
  • Database Indexing: Optimized MongoDB indexes for fast queries
  • Connection Pooling: Efficient database connection management
  • Load Testing: Built-in Locust performance testing

Security Features

  • Password Hashing: Argon2 and bcrypt for secure password storage
  • JWT Tokens: EdDSA algorithm for secure token generation
  • CORS Support: Configurable cross-origin resource sharing
  • Input Validation: Comprehensive data validation using Pydantic
  • Error Handling: Centralized error handling with detailed logging

Advanced Features

  • Search & Filtering: Full-text search with gender and role filtering
  • Pagination: Efficient pagination for large datasets
  • Real-time Monitoring: Comprehensive logging and monitoring
  • Docker Support: Containerized deployment with Docker Compose
  • Environment Configuration: Flexible configuration management

🏗️ Architecture

┌──────────────────────────┐     ┌─────────────────────┐     ┌─────────────────────┐
│        FastAPI App       │     │       MongoDB       │     │        Redis        │
│                          │     │                     │     │                     │
│ • API (Auth, User CRUD)  │◄───►│ • Collections       │     │ • Caching           │
│ • Security (JWT, RBAC)   │     │ • Indexes           │     │ • Rate limiting     │
│ • Middleware (CORS, RL)  │     │ • Full-text search  │     │ • Session store     │
│ • Error handling         │     │                     │     │                     │
└──────────────────────────┘     └─────────────────────┘     └─────────────────────┘

🛠️ Tech Stack

Backend

  • FastAPI - Modern, fast web framework for building APIs
  • MongoDB - NoSQL database with Motor async driver
  • Redis - In-memory data store for caching and rate limiting
  • Pydantic - Data validation and settings management
  • JWT - JSON Web Tokens for authentication
  • Argon2/bcrypt - Secure password hashing
  • Locust - Load testing framework

Infrastructure

  • Docker - Containerization
  • Docker Compose - Multi-container orchestration

📋 Prerequisites

  • Python 3.12+
  • Docker & Docker Compose
  • MongoDB 7.0+
  • Redis 7.0+

🚀 Quick Start

1. Clone the Repository

git clone https://github.com/Khailas12/Auth-Engine.git
cd Auth-Engine

2. Environment Setup

Create a .env file in the root directory:

# MongoDB Configuration
MONGO_URI=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/?retryWrites=true&w=majority&appName=<app>
DB_NAME=authengine

# Admin User (seeded on startup)
EMAIL=admin@authengine.com
FIRST_NAME=Admin
LAST_NAME=User
PASSWORD=Admin@1234

# JWT Configuration
ALGORITHM=EdDSA
ACCESS_TOKEN_EXPIRE_MINUTES=30

# Redis Configuration
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_DB=0

# Rate Limiting
RATE_LIMIT_PRIMARY=100
RATE_LIMIT_SECONDARY=50

3. Generate JWT Keys

Note: The repository already includes secrets/ed25519-private.pem and secrets/ed25519-public.pem for easier access. If you want to explore OpenSSL or regenerate keys, follow the steps below.

Follow these steps on Windows using OpenSSL:

  1. Install OpenSSL for Windows
  • Download and install Win64 OpenSSL (Light is sufficient) from the official Windows builds: Win32/Win64 OpenSSL.
  • Prefer the latest 3.x series (3.5.x is LTS as of 2025).
  1. Open the OpenSSL terminal
  • After installation, open the Start Menu and launch "OpenSSL Command Prompt" (installed with OpenSSL), or
  • Use PowerShell and call the installed binary directly, e.g. "C:\\Program Files\\OpenSSL-Win64\\bin\\openssl.exe".
  1. Choose the output folder
  • From your project root, place keys in secrets/ (recommended):
    • PowerShell: cd C:\\Users\\ADMIN\\Documents\\Projects\\Personal\\Mongo-CRUD\\secrets
  1. Generate the Ed25519 key pair (run in the chosen folder)
  • Use the commands below. They will create ed25519-private.pem and ed25519-public.pem in the current directory.
  1. Verify the keys (optional)
  • Private (text view): openssl pkey -in ed25519-private.pem -text -noout
  • Public (text view): openssl pkey -in ed25519-public.pem -pubin -text -noout
  1. Secure the private key (Windows ACLs)
  • Restrict permissions so only your user can read it:
    • icacls ed25519-private.pem /inheritance:r
    • icacls ed25519-private.pem /grant:r "%USERNAME%:R"
  1. Keep keys out of source control
  • Ensure secrets/ or the .pem files are excluded by .gitignore.
# Generate Ed25519 private key
openssl genpkey -algorithm Ed25519 -out ed25519-private.pem

# Generate Ed25519 public key
openssl pkey -in ed25519-private.pem -pubout -out ed25519-public.pem

4. Start with Docker Compose

docker-compose up --build

The application will be available at http://localhost:8000

5. Access API Documentation

  • Swagger UI: http://localhost:8000/docs

🗄️ MongoDB Setup

You can use either MongoDB Atlas (cloud) or a local MongoDB instance. Provide the connection via MONGO_URI and the database name via DB_NAME in .env.

Option A: MongoDB Atlas (recommended)

  1. Create an Atlas account and a free/shared cluster.
  2. Create a database user and password.
  3. Allow IP access (add your IP or 0.0.0.0/0 for testing only).
  4. Get your connection string (Driver: Python, Version: 3.12+):
    • Example: MONGO_URI=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/?retryWrites=true&w=majority&appName=<app>
  5. Set your database name, e.g. DB_NAME=authengine.

Option B: Local MongoDB

  • Install MongoDB Community Server and start the service.
  • Example .env:
    • MONGO_URI=mongodb://localhost:27017
    • DB_NAME=authengine

What happens on startup

  • A connection is established and pinged (app/db/mongo.py).
  • Indexes are created on users for text search and filtering (app/db/indexes.py).
  • An Admin user is seeded if missing, using .env credentials (app/db/seeder.py).

Indexes created

  • Text index: email, full_name (name: email_fullname_text_index).
  • Compound index: (is_active, gender, role) (name: active_gender_role_idx).
  • Compound index: (is_active, created_at desc) (name: active_createdAt_idx).

Seeding Admin user

  • Uses .env: EMAIL, FIRST_NAME, LAST_NAME, PASSWORD.
  • Role: Admin, Gender: default Male, is_active: true.
  • Password is securely hashed before insertion.

📚 API Documentation

Authentication Endpoints

POST /api/signup

Create a new user account (Admin/Manager only)

Request Body:

{
  "first_name": "John",
  "last_name": "Doe",
  "email": "john.doe@example.com",
  "password": "SecurePass123!",
  "gender": "Male",
  "role": "User",
  "is_active": true
}

POST /api/login

Authenticate user and get access token

Request Body:

username: user@example.com
password: userpassword

Response:

{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "token_type": "bearer"
}

User Management Endpoints

GET /api/user/

Get all users with filtering and pagination

Query Parameters:

  • skip (int): Number of records to skip (default: 0)
  • limit (int): Number of records to return (default: 10, max: 100)
  • search_key (str): Search term for full-text search
  • gender (str): Filter by gender (Male, Female, Other)
  • role (str): Filter by role (Admin, Manager, User)

Example:

GET /api/user/?skip=0&limit=10&search_key=john&gender=Male&role=User

GET /api/user/{user_id}

Get specific user by ID

PUT /api/user/{user_id}Update user information

Request Body:

{
  "first_name": "John",
  "last_name": "Smith",
  "password": "NewPassword123!",
  "role": "Manager",
  "is_active": true
}

DELETE /api/user/{user_id}

Delete user (Admin only)

🔐 User Roles & Permissions

Admin

  • Full access to all endpoints
  • Can create, read, update, and delete users
  • Higher rate limits (100 requests/minute)
  • Can manage all user roles

Manager

  • Can create and manage regular users
  • Cannot delete users or manage other managers/admins
  • Moderate rate limits (75 requests/minute)

User

  • Can view and update own profile
  • Cannot create or delete other users
  • Standard rate limits (50 requests/minute)

🏃‍♂️ Performance Testing

Run load tests using Locust:

# Install Locust
pip install locust

# Run load tests
locust -f backend/app/tests/locustfile.py --host=http://localhost:8000

Access the Locust web interface at http://localhost:8089

🐳 Docker Deployment

Development

docker-compose up --build

📁 Project Structure

Auth-Engine/
├── backend/
│   ├── app/
│   │   ├── api/                 # API routes and dependencies
│   │   │   ├── endpoints/       # Route handlers
│   │   │   └── deps/           # Dependency injection
│   │   ├── core/               # Core configuration
│   │   ├── db/                 # Database management
│   │   ├── enums/              # Enumerations
│   │   ├── helpers/            # Utility functions
│   │   ├── middleware/         # Custom middleware
│   │   ├── schemas/            # Pydantic models
│   │   ├── services/           # Business logic
│   │   └── tests/              # Test files
│   ├── Dockerfile
│   └── requirements.txt
├── secrets/                    # JWT keys
├── docker-compose.yml
└── README.md

🔧 Configuration

Environment Variables

Variable Description Default
MONGO_URI MongoDB connection string Required
DB_NAME Database name Required
REDIS_HOST Redis host Required
REDIS_PORT Redis port Required
RATE_LIMIT_PRIMARY Admin rate limit Required
RATE_LIMIT_SECONDARY User rate limit Required
ALGORITHM JWT algorithm Ed25519
ACCESS_TOKEN_EXPIRE_MINUTES Token expiration 30

🚨 Rate Limiting

This service enforces role-aware, Redis-backed rate limiting to protect the API and ensure fair usage.

  • Admin: 100 requests/minute
  • Manager: 75 requests/minute
  • User: 50 requests/minute
  • Anonymous: 25 requests/minute

How it works

  1. The middleware inspects the Authorization header. If a valid JWT is present, it extracts sub (user id) and role. Otherwise, it treats the caller as Anonymous and uses the client IP.
  2. It computes a Redis key ratelimit:{role|anonymous}:{idOrIp} and atomically increments it using a short Lua script. On first increment in a window, it sets the key’s TTL to the period (60s).
  3. If the counter exceeds the role’s limit, the request is blocked with HTTP 429 and retry metadata is returned.
  4. For allowed requests, response headers include the current limit, remaining quota, and reset timestamp.
Request → [RateLimitMiddleware]
  ├─ parse JWT (sub, role) or use client IP
  ├─ Redis EVAL (INCR + EXPIRE on first hit)
  ├─ if count > limit ⇒ 429 with Retry-After
  └─ else → next handler + X-RateLimit-* headers
  • Headers added on responses:
    • X-RateLimit-Limit: Max requests in the current window
    • X-RateLimit-Remaining: Remaining requests in the window
    • X-RateLimit-Reset: Unix timestamp when the window resets

Role-based limits

  • Limits per role are defined in settings and passed into the middleware. The middleware chooses the tuple (limit, periodSeconds) by role, defaulting to secondary/user limits for unknown roles.
  • Keying strategy ensures users are isolated by id, and unauthenticated callers are limited by IP.

Configuration (.env)

  • RATE_LIMIT_PRIMARY: Primary limit (used for Admin), integer requests per 60s window.
  • RATE_LIMIT_SECONDARY: Secondary limit (used for User/unknown roles), integer requests per 60s window.
  • These are loaded by app/core/config.py into settings and wired into RateLimitMiddleware in app/main.py:
# app/main.py (excerpt)
app.add_middleware(
    RateLimitMiddleware,
    limits={
        Role.ADMIN.value: (settings.RATE_LIMIT_PRIMARY, 100),  
        Role.USER.value: (settings.RATE_LIMIT_SECONDARY, 60),  
        Role.MANAGER.value: (settings.RATE_LIMIT_SECONDARY, 60),
    }
)

Per-endpoint dynamic limits

  • Some endpoints can apply additional, per-route limits based on the current user using a dependency (see app/helpers/dynamic_rate_limit.py). This can be stacked with the global middleware for stricter control on sensitive routes.

Why this design (benefits)

  • Abuse prevention: Shields against brute force and scraping.
  • Fairness: Ensures Admins/Managers have higher throughput without impacting Users.
  • Performance: Uses Redis atomic INCR + EXPIRE for O(1) ops and low latency.
  • Scalability: Shared Redis allows consistent limits across multiple app instances.
  • Observability: Standard headers make client-side backoff straightforward.

🔒 Security Considerations

  • Store private keys in a secure location (restrict FS permissions).
  • Never commit secret material. Ensure secrets/ is ignored by git.
  • Rotate keys periodically; reissue tokens after rotation if needed.
  • Validate JWT alg, exp, iss, and sub.
  • Enforce strong password policy and hashing (Argon2/bcrypt).

🛠️ Troubleshooting

  • Redis connection errors: verify REDIS_HOST, REDIS_PORT, and that Redis is running.
  • Mongo connection errors: check MONGO_URI, DB_NAME, and network access.
  • 429 Too Many Requests: reduce request rate or adjust limits in .env.
  • Invalid JWT: ensure keys paths in .env point to existing .pem files.
  • Windows OpenSSL not found: use the OpenSSL Command Prompt or full path to openssl.exe.

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🆘 Support

For support and questions:

  • Create an issue in the repository
  • Check the API documentation at /docs
  • Review the logs for debugging information

🔮 Roadmap

  • User profile pictures
  • Email verification
  • Password reset functionality
  • Audit logging
  • Multi-tenancy support
  • GraphQL API
  • WebSocket support for real-time updates

Auth Engine - Secure, Scalable, Simple User Management 🚀