Skip to content

ianlintner/rust_oauth2_server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

28 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Rust OAuth2 Server

CI/CD Pipeline

Rust OAuth2 Server screenshot

A complete, production-ready OAuth2 authorization server built with Rust and Actix-web, featuring the actor model for concurrency, type safety, and comprehensive observability.

🌟 Overview

The Rust OAuth2 Server is a high-performance, secure, and scalable OAuth2 implementation designed for modern cloud-native applications. Built with Rust's safety guarantees and Actix's actor model, it provides enterprise-grade authentication and authorization services.

graph LR
    A[Web Apps] -->|OAuth2| S[OAuth2 Server]
    B[Mobile Apps] -->|OAuth2| S
    C[Services] -->|OAuth2| S
    S -->|Issues| T[JWT Tokens]
    T -->|Authorize| API[Protected APIs]
    
    style S fill:#ff9800,color:#fff
    style T fill:#4caf50,color:#fff
Loading

πŸš€ Features

OAuth2 Compliance

  • βœ… Authorization Code Flow with PKCE support
  • βœ… Client Credentials Flow for service-to-service
  • βœ… Resource Owner Password Credentials Flow
  • βœ… Refresh Token Flow with rotation
  • βœ… Token Introspection (RFC 7662)
  • βœ… Token Revocation (RFC 7009)
  • βœ… Discovery Endpoint (RFC 8414)

Architecture

  • 🎭 Actor Model using Actix for concurrent request handling
  • πŸ”’ Type-Safe Rust implementation
  • πŸ” JWT Tokens with configurable expiration
  • πŸ’Ύ Database Support (SQLite/PostgreSQL via SQLx, optional MongoDB via --features mongo)
  • πŸ—„οΈ Flyway Migrations for database schema management

Authentication Eventing (NEW! ✨)

  • πŸ“‘ Comprehensive Event System - Emit events for all auth operations
  • πŸ”§ Configurable Filtering - Include/exclude specific event types
  • πŸ”Œ Pluggable Backends - In-memory, console, and extensible for Redis/Kafka/RabbitMQ
  • 🎯 Actor-Based - Non-blocking, concurrent event processing
  • πŸ“Š Rich Metadata - Events include user/client IDs, timestamps, and custom data
  • πŸ›‘οΈ Audit-Ready - Perfect for compliance and security monitoring
  • See Eventing Documentation for details

Observability & Monitoring

  • πŸ“Š Prometheus Metrics - Request rates, token metrics, database performance
  • πŸ” OpenTelemetry Tracing - Distributed tracing with OTLP export
  • πŸ“ Structured Logging - JSON logs with correlation IDs
  • ❀️ Health & Readiness Checks - Kubernetes-ready endpoints
  • πŸ“ˆ Admin Dashboard - Web-based monitoring and management

Documentation

  • πŸ“š OpenAPI 3.0 Specification - Auto-generated from code
  • 🎨 Swagger UI - Interactive API documentation
  • πŸ“– Admin Control Panel - Web-based administration interface
  • πŸ€– MCP Server - Model Context Protocol server for AI integration

Deployment

  • 🐳 Docker - Container images with multi-stage builds
  • ☸️ Kubernetes - Production-ready manifests with Kustomize
  • πŸ”„ CI/CD - GitHub Actions with E2E testing
  • πŸ“¦ Helm - (Planned) Helm charts for easy deployment

Security

  • πŸ” PKCE Support (Proof Key for Code Exchange)
  • πŸ”‘ Secure Client Credentials generation
  • πŸ›‘οΈ Scope-based Authorization
  • 🚫 Token Revocation
  • πŸ” Social Login Integration (Google, Microsoft, GitHub, Azure, Okta, Auth0)
  • 🎫 Session Management with secure cookies
  • ⚠️ Rate Limiting (planned)

πŸ“‹ Prerequisites

  • Rust 1.70 or higher
  • SQLite or PostgreSQL (default)
  • MongoDB (optional, only if you want to run with --features mongo)
  • Docker (optional, for containerized deployment)
  • Flyway (optional, or use Docker for migrations)

πŸ› οΈ Installation

Clone the Repository

git clone https://github.com/ianlintner/rust_oauth2_server.git
cd rust_oauth2_server

Run Database Migrations

Using the provided script (uses Docker if Flyway not installed):

./scripts/migrate.sh

Or using Docker directly:

docker run --rm \
  -v "$(pwd)/migrations/sql:/flyway/sql" \
  -v "$(pwd)/flyway.conf:/flyway/conf/flyway.conf" \
  flyway/flyway:10-alpine migrate

Build the Project

cargo build --release

πŸš€ Running the Server

Development Mode

cargo run

Production Mode

cargo run --release

Using Docker Compose

docker-compose up -d

Using Kubernetes

Deploy to Kubernetes using Kustomize:

# Development
kubectl apply -k k8s/overlays/dev

# Staging
kubectl apply -k k8s/overlays/staging

# Production
kubectl apply -k k8s/overlays/production

See Kubernetes Deployment Guide for detailed instructions.

πŸ€– MCP Server (AI Integration)

The project includes a Model Context Protocol (MCP) server that enables AI assistants like Claude to interact with the OAuth2 server through natural language commands.

MCP Server Features

  • Register and manage OAuth2 clients
  • Generate and manage access tokens
  • Introspect and revoke tokens
  • Check server health and metrics
  • Access OpenID configuration

Installation

cd mcp-server
npm install
cp .env.example .env
# Edit .env with your OAuth2 server URL

Configuration

Add to your Claude Desktop configuration:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "oauth2-server": {
      "command": "node",
      "args": ["/path/to/rust_oauth2_server/mcp-server/src/index.js"],
      "env": {
        "OAUTH2_BASE_URL": "http://localhost:8080"
      }
    }
  }
}

Usage Examples

Once configured, you can ask your AI assistant:

  • "Register a new OAuth2 client called 'My App'"
  • "Get an access token for client ID abc123"
  • "Check the health status of the OAuth2 server"
  • "Show me the server metrics"

See MCP Server Documentation for more details.

πŸ”§ Configuration

The OAuth2 server uses HOCON (Human-Optimized Config Object Notation) for configuration, providing a human-readable format with powerful features like:

  • Comments and documentation within config files
  • Nested configuration structures
  • Environment variable substitution with ${?VAR} syntax
  • Value composition and inheritance
  • Fallback to environment variables for backward compatibility

Configuration Methods

The server loads configuration in the following priority order:

  1. HOCON file (application.conf) - Main configuration file with sensible defaults
  2. Environment variables - Override any HOCON setting using OAUTH2_* prefix
  3. Fallback defaults - Built-in defaults if no configuration is provided

Quick Start

Copy the example configuration:

cp application.conf.example application.conf

Then edit application.conf to customize your settings, or use environment variables to override specific values.

Basic Configuration

Using HOCON file (application.conf):

# Server Configuration
server {
  host = "127.0.0.1"      # Override with OAUTH2_SERVER_HOST
  port = 8080              # Override with OAUTH2_SERVER_PORT
}

# Database Configuration
database {
  # SQLite (default)
  url = "sqlite:oauth2.db"
  
  # PostgreSQL
  # url = "postgresql://oauth2_user:password@localhost:5432/oauth2"
  
  # MongoDB (requires building with --features mongo)
  # url = "mongodb://localhost:27017/oauth2"
  
  # Override with OAUTH2_DATABASE_URL
}

# JWT Configuration
jwt {
  # MUST be changed for production (minimum 32 characters)
  # Generate with: openssl rand -base64 48
  secret = "insecure-default-for-testing-only-change-in-production"
  # Override with OAUTH2_JWT_SECRET
}

Using Environment Variables (legacy method, still fully supported):

export OAUTH2_SERVER_HOST=127.0.0.1
export OAUTH2_SERVER_PORT=8080
export OAUTH2_DATABASE_URL=sqlite:oauth2.db
export OAUTH2_JWT_SECRET=your-secret-key-change-in-production

Event System Configuration

Configure the authentication eventing system using HOCON or environment variables:

Using HOCON (application.conf):

events {
  enabled = true                    # Override with OAUTH2_EVENTS_ENABLED
  backend = "in_memory"             # Override with OAUTH2_EVENTS_BACKEND
  filter_mode = "allow_all"         # Override with OAUTH2_EVENTS_FILTER_MODE
  
  # Redis Streams backend (requires --features events-redis)
  redis {
    url = "redis://127.0.0.1:6379"
    stream = "oauth2_events"
    maxlen = null                   # Optional max length
  }
  
  # Kafka backend (requires --features events-kafka)
  kafka {
    brokers = "127.0.0.1:9092"
    topic = "oauth2_events"
    client_id = null                # Optional client ID
  }
  
  # RabbitMQ backend (requires --features events-rabbit)
  rabbit {
    url = "amqp://127.0.0.1:5672/%2f"
    exchange = "oauth2.events"
    routing_key = "oauth2.event"
  }
}

Using Environment Variables:

# Enable/disable events (default: true)
export OAUTH2_EVENTS_ENABLED=true

# Backend options: in_memory, console, both, redis, kafka, rabbit
export OAUTH2_EVENTS_BACKEND=console

# Filter mode: allow_all, include, or exclude (default: allow_all)
export OAUTH2_EVENTS_FILTER_MODE=include

# Event types (comma-separated, used with include/exclude modes)
export OAUTH2_EVENTS_TYPES=token_created,token_revoked,client_registered

# Redis Streams (requires --features events-redis)
export OAUTH2_EVENTS_REDIS_URL=redis://localhost:6379
export OAUTH2_EVENTS_REDIS_STREAM=oauth2:events
export OAUTH2_EVENTS_REDIS_MAXLEN=10000

# Kafka (requires --features events-kafka)
export OAUTH2_EVENTS_KAFKA_BROKERS=localhost:9092
export OAUTH2_EVENTS_KAFKA_TOPIC=oauth2-events
export OAUTH2_EVENTS_KAFKA_CLIENT_ID=rust-oauth2-server

# RabbitMQ (requires --features events-rabbit)
export OAUTH2_EVENTS_RABBIT_URL=amqp://guest:guest@localhost:5672/%2f
export OAUTH2_EVENTS_RABBIT_EXCHANGE=oauth2.events
export OAUTH2_EVENTS_RABBIT_ROUTING_KEY=auth.*

See Eventing Documentation and Examples for more details.

Social Login Configuration

Configure social login providers using HOCON or environment variables. Providers are only enabled when their credentials are provided.

Using HOCON (application.conf):

social {
  google {
    enabled = false  # Set to true and provide credentials to enable
    # These values are loaded from environment variables:
    # OAUTH2_GOOGLE_CLIENT_ID
    # OAUTH2_GOOGLE_CLIENT_SECRET
    # OAUTH2_GOOGLE_REDIRECT_URI
  }
  
  microsoft {
    enabled = false
    # OAUTH2_MICROSOFT_CLIENT_ID
    # OAUTH2_MICROSOFT_CLIENT_SECRET
    # OAUTH2_MICROSOFT_REDIRECT_URI
    # OAUTH2_MICROSOFT_TENANT_ID (optional, defaults to "common")
  }
  
  github {
    enabled = false
    # OAUTH2_GITHUB_CLIENT_ID
    # OAUTH2_GITHUB_CLIENT_SECRET
    # OAUTH2_GITHUB_REDIRECT_URI
  }
  
  okta {
    enabled = false
    # OAUTH2_OKTA_CLIENT_ID
    # OAUTH2_OKTA_CLIENT_SECRET
    # OAUTH2_OKTA_REDIRECT_URI
    # OAUTH2_OKTA_DOMAIN (required)
  }
  
  auth0 {
    enabled = false
    # OAUTH2_AUTH0_CLIENT_ID
    # OAUTH2_AUTH0_CLIENT_SECRET
    # OAUTH2_AUTH0_REDIRECT_URI
    # OAUTH2_AUTH0_DOMAIN (required)
  }
}

Using Environment Variables:

Google OAuth2

export OAUTH2_GOOGLE_CLIENT_ID=your-google-client-id
export OAUTH2_GOOGLE_CLIENT_SECRET=your-google-client-secret
export OAUTH2_GOOGLE_REDIRECT_URI=http://localhost:8080/auth/callback/google

Microsoft/Azure AD

export OAUTH2_MICROSOFT_CLIENT_ID=your-microsoft-client-id
export OAUTH2_MICROSOFT_CLIENT_SECRET=your-microsoft-client-secret
export OAUTH2_MICROSOFT_REDIRECT_URI=http://localhost:8080/auth/callback/microsoft
export OAUTH2_MICROSOFT_TENANT_ID=common  # or your tenant ID

GitHub

export OAUTH2_GITHUB_CLIENT_ID=your-github-client-id
export OAUTH2_GITHUB_CLIENT_SECRET=your-github-client-secret
export OAUTH2_GITHUB_REDIRECT_URI=http://localhost:8080/auth/callback/github

Okta

export OAUTH2_OKTA_CLIENT_ID=your-okta-client-id
export OAUTH2_OKTA_CLIENT_SECRET=your-okta-client-secret
export OAUTH2_OKTA_REDIRECT_URI=http://localhost:8080/auth/callback/okta
export OAUTH2_OKTA_DOMAIN=your-okta-domain.okta.com

Auth0

export OAUTH2_AUTH0_CLIENT_ID=your-auth0-client-id
export OAUTH2_AUTH0_CLIENT_SECRET=your-auth0-client-secret
export OAUTH2_AUTH0_REDIRECT_URI=http://localhost:8080/auth/callback/auth0
export OAUTH2_AUTH0_DOMAIN=your-tenant.auth0.com

πŸ“ Endpoints

User Interface

  • GET / - Redirects to login page
  • GET /auth/login - Modern login page with social login options
  • GET /error - Error page with detailed error information

Social Login

  • GET /auth/login/google - Initiate Google login
  • GET /auth/login/microsoft - Initiate Microsoft/Azure AD login
  • GET /auth/login/github - Initiate GitHub login
  • GET /auth/login/azure - Initiate Azure AD login
  • GET /auth/login/okta - Initiate Okta login
  • GET /auth/login/auth0 - Initiate Auth0 login
  • GET /auth/callback/{provider} - OAuth callback handler
  • GET /auth/success - Authentication success page
  • POST /auth/logout - Logout endpoint

OAuth2 Endpoints

  • GET /oauth/authorize - Authorization endpoint
  • POST /oauth/token - Token endpoint
  • POST /oauth/introspect - Token introspection
  • POST /oauth/revoke - Token revocation

Client Management

  • POST /clients/register - Register a new OAuth2 client

Discovery

  • GET /.well-known/openid-configuration - OAuth2 server metadata

Admin & Monitoring

  • GET /admin - Admin dashboard
  • GET /health - Health check endpoint
  • GET /ready - Readiness check endpoint
  • GET /metrics - Prometheus metrics

API Documentation

  • GET /swagger-ui - Interactive API documentation

πŸ“Š Metrics

The server exposes Prometheus metrics at /metrics:

  • oauth2_server_http_requests_total - Total HTTP requests
  • oauth2_server_http_request_duration_seconds - Request duration histogram
  • oauth2_server_oauth_token_issued_total - Tokens issued counter
  • oauth2_server_oauth_token_revoked_total - Tokens revoked counter
  • oauth2_server_oauth_clients_total - Total registered clients
  • oauth2_server_oauth_active_tokens - Active tokens gauge
  • oauth2_server_db_queries_total - Database queries counter
  • oauth2_server_db_query_duration_seconds - DB query duration histogram

πŸ” OpenTelemetry

The server exports traces to an OTLP endpoint (default: http://localhost:4317). Configure your OpenTelemetry collector to receive traces.

Example with Jaeger:

docker run -d --name jaeger \
  -p 4317:4317 \
  -p 16686:16686 \
  jaegertracing/all-in-one:latest

Then access Jaeger UI at http://localhost:16686

πŸ§ͺ Testing

Run Unit Tests

cargo test

Run Integration Tests

cargo test --test integration

Run BDD Tests

cargo test --test bdd

πŸ“š API Examples

Register a Client

curl -X POST http://localhost:8080/clients/register \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "My Application",
    "redirect_uris": ["http://localhost:3000/callback"],
    "grant_types": ["authorization_code", "refresh_token"],
    "scope": "read write"
  }'

Authorization Code Flow

  1. Get Authorization Code:
http://localhost:8080/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=http://localhost:3000/callback&scope=read
  1. Exchange Code for Token:
curl -X POST http://localhost:8080/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code&code=AUTH_CODE&redirect_uri=http://localhost:3000/callback&client_id=CLIENT_ID&client_secret=CLIENT_SECRET"

Client Credentials Flow

curl -X POST http://localhost:8080/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&scope=read"

Token Introspection

curl -X POST http://localhost:8080/oauth/introspect \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=ACCESS_TOKEN"

πŸ—οΈ Architecture

The server uses the Actor model for concurrent, fault-tolerant request handling:

graph TB
    subgraph "Client Layer"
        Client1[Web Apps]
        Client2[Mobile Apps]
        Client3[Services]
    end
    
    subgraph "OAuth2 Server"
        LB[Load Balancer]
        MW[Middleware Stack]
        
        subgraph "Handlers"
            OAuth[OAuth Handler]
            Token[Token Handler]
            ClientH[Client Handler]
        end
        
        subgraph "Actor System"
            TokenA[Token Actor]
            ClientA[Client Actor]
            AuthA[Auth Actor]
        end
    end
    
    subgraph "Data & Observability"
        DB[(Database)]
        Metrics[Prometheus]
        Traces[Jaeger]
    end
    
    Client1 --> LB
    Client2 --> LB
    Client3 --> LB
    
    LB --> MW
    MW --> OAuth
    MW --> Token
    MW --> ClientH
    
    OAuth --> AuthA
    Token --> TokenA
    ClientH --> ClientA
    
    TokenA --> DB
    ClientA --> DB
    AuthA --> DB
    MW --> Metrics
    MW --> Traces
    
    style LB fill:#ff9800,color:#fff
    style TokenA fill:#4caf50,color:#fff
    style ClientA fill:#2196f3,color:#fff
    style AuthA fill:#9c27b0,color:#fff
    style DB fill:#f3e5f5
Loading

Key Components

  • Actix-Web Server: High-performance async HTTP server
  • Actor Model: Isolated, concurrent request processing
  • SQLx Database: Compile-time verified queries
  • JWT Tokens: Stateless authentication
  • Middleware Stack: Metrics, tracing, CORS, authentication
  • OpenTelemetry: Distributed tracing and observability

OAuth2 Flows

graph LR
    subgraph AuthCodeFlow["Authorization Code Flow"]
        User1[User] -->|Login| Auth1["/oauth/authorize"]
        Auth1 -->|Code| Client1[Client]
        Client1 -->|Exchange| Token1["/oauth/token"]
        Token1 -->|Access Token| Client1
    end
    
    subgraph ClientCredsFlow["Client Credentials Flow"]
        Service[Service] -->|Credentials| Token2["/oauth/token"]
        Token2 -->|Access Token| Service
    end
    
    style Auth1 fill:#4caf50,color:#fff
    style Token1 fill:#2196f3,color:#fff
    style Token2 fill:#2196f3,color:#fff
Loading

For detailed architecture documentation, see Architecture Overview.

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

For development guidelines, see Contributing Guide.

πŸ“š Documentation

Comprehensive documentation is available in the /docs directory:

Agent Instructions

For AI-assisted development and operations, see:

πŸ“„ License

This project is licensed under either of:

  • MIT License
  • Apache License, Version 2.0

at your option.

πŸ”— Resources

About

Rust OAuth2 Server with Social Logins with observability. Typesafe and Actor System.

Topics

Resources

License

Unknown and 2 other licenses found

Licenses found

Unknown
LICENSE
Unknown
LICENSE-APACHE
MIT
LICENSE-MIT

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors 2

  •  
  •