Architecture Overview
This document provides a comprehensive overview of the Rust OAuth2 Server architecture, design patterns, and implementation details.
System Architecture
The Rust OAuth2 Server is built using modern architectural patterns that prioritize performance, security, and maintainability.
graph TB
subgraph ClientLayer[Client Layer]
WebApp[Web Application]
MobileApp[Mobile App]
Service[Backend Service]
end
subgraph LoadBalancer[Load Balancer]
LB[Load Balancer]
end
subgraph OAuth2ServerInstances[OAuth2 Server Instances]
Server1[OAuth2 Server 1]
Server2[OAuth2 Server 2]
Server3[OAuth2 Server 3]
end
subgraph MiddlewareLayer[Middleware Layer]
Auth[Auth Middleware]
Metrics[Metrics Middleware]
Tracing[Tracing Middleware]
CORS[CORS Middleware]
end
subgraph HandlerLayer[Handler Layer]
OAuthHandler[OAuth Handler]
TokenHandler[Token Handler]
ClientHandler[Client Handler]
AdminHandler[Admin Handler]
end
subgraph ActorLayer[Actor Layer]
TokenActor[Token Actor]
ClientActor[Client Actor]
AuthActor[Auth Actor]
end
subgraph DataLayer[Data Layer]
DB[(PostgreSQL/SQLite)]
Cache[Redis Cache]
end
subgraph Observability
Prometheus[Prometheus]
Jaeger[Jaeger]
Logs[Log Aggregator]
end
WebApp --> LB
MobileApp --> LB
Service --> LB
LB --> Server1
LB --> Server2
LB --> Server3
Server1 --> Auth
Server2 --> Auth
Server3 --> Auth
Auth --> Metrics
Metrics --> Tracing
Tracing --> CORS
CORS --> OAuthHandler
CORS --> TokenHandler
CORS --> ClientHandler
CORS --> AdminHandler
OAuthHandler --> AuthActor
TokenHandler --> TokenActor
ClientHandler --> ClientActor
AdminHandler --> ClientActor
TokenActor --> DB
ClientActor --> DB
AuthActor --> DB
TokenActor -.-> Cache
ClientActor -.-> Cache
Metrics --> Prometheus
Tracing --> Jaeger
Server1 --> Logs
Server2 --> Logs
Server3 --> Logs
style WebApp fill:#e1f5ff
style MobileApp fill:#e1f5ff
style Service fill:#e1f5ff
style DB fill:#f3e5f5
style Prometheus fill:#e8f5e9
style Jaeger fill:#fff9c4
style Logs fill:#fff9c4
Core Components
1. HTTP Server (Actix-Web)
The foundation of the application is built on Actix-Web, a powerful, pragmatic, and extremely fast web framework for Rust.
Key Features:
- Asynchronous request handling
- HTTP/1.x and HTTP/2 support
- WebSocket support
- Streaming and pipelining
- SSL/TLS support via OpenSSL or Rustls
- Middleware support
Configuration:
HttpServer::new(move || {
App::new()
.wrap(TracingLogger::default())
.wrap(SessionMiddleware::new(/* ... */))
.wrap(Cors::default())
.wrap(MetricsMiddleware)
// Routes configuration
})
.workers(4)
.bind("0.0.0.0:8080")?
.run()
2. Actor Model
The server uses the Actor Model for concurrent state management, provided by the Actix framework.
graph LR
subgraph ActorSystem[Actor System]
Request[HTTP Request] --> Router[Router]
Router --> Handler[Request Handler]
Handler --> TokenActor
Handler --> ClientActor
Handler --> AuthActor
TokenActor --> Message1[Token Message]
ClientActor --> Message2[Client Message]
AuthActor --> Message3[Auth Message]
Message1 --> DB[(Database)]
Message2 --> DB
Message3 --> DB
DB --> Response1[Response]
Response1 --> Handler
Handler --> Response[HTTP Response]
end
style Request fill:#e1f5ff
style Response fill:#e8f5e9
style DB fill:#f3e5f5
Benefits:
- Isolation: Each actor manages its own state
- Concurrency: Actors process messages concurrently
- Fault Tolerance: Actor failures don't cascade
- Scalability: Easy to scale horizontally
See Actor Model Documentation for detailed implementation.
3. Database Layer
The server uses SQLx for database interactions, providing compile-time verified SQL queries.
Supported Databases:
- SQLite (development/testing)
- PostgreSQL (production)
Features:
- Async database operations
- Connection pooling
- Compile-time query verification
- Automatic SQL migration
- Transaction support
Schema Overview:
erDiagram
CLIENTS ||--o{ TOKENS : issues
CLIENTS ||--o{ AUTHORIZATION_CODES : creates
USERS ||--o{ TOKENS : owns
USERS ||--o{ AUTHORIZATION_CODES : authorizes
CLIENTS {
text id PK "UUID primary key"
text client_id UK "Unique client identifier"
text client_secret "Hashed secret"
text client_name "Client display name"
text redirect_uris "JSON array"
text grant_types "JSON array"
text scope "Space-separated scopes"
text created_at "ISO 8601 timestamp"
text updated_at "ISO 8601 timestamp"
}
TOKENS {
text id PK "UUID primary key"
text token_value UK "Token value"
text token_type "Token type (Bearer)"
text client_id FK "Reference to clients"
text user_id FK "Reference to users"
text scope "Granted scopes"
text expires_at "ISO 8601 timestamp"
text created_at "ISO 8601 timestamp"
integer revoked "Revocation status (0/1)"
}
AUTHORIZATION_CODES {
text id PK "UUID primary key"
text code UK "Authorization code"
text client_id FK "Reference to clients"
text user_id FK "Reference to users"
text redirect_uri "Callback URL"
text scope "Requested scopes"
text code_challenge "PKCE challenge"
text code_challenge_method "S256 or plain"
text expires_at "ISO 8601 timestamp"
text created_at "ISO 8601 timestamp"
integer used "Usage status (0/1)"
}
USERS {
text id PK "UUID primary key"
text email UK "User email"
text username "Username"
text password_hash "Argon2 hash"
text provider "Local/social provider"
text provider_user_id "Provider user id"
text metadata "JSON blob"
text created_at "ISO 8601 timestamp"
text updated_at "ISO 8601 timestamp"
}
See Database Documentation for schema details and migrations.
Request Flow
Complete Request Flow Diagram
sequenceDiagram
participant Client
participant LB as Load Balancer
participant Server as OAuth2 Server
participant MW as Middleware Stack
participant Handler as Request Handler
participant Actor as Actor System
participant DB as Database
participant Telemetry as Observability
Client->>LB: HTTP Request
LB->>Server: Forward Request
Server->>MW: Process Request
activate MW
MW->>MW: CORS Check
MW->>MW: Auth Check
MW->>MW: Start Trace Span
MW->>Telemetry: Record Metrics
MW->>Handler: Validated Request
deactivate MW
activate Handler
Handler->>Actor: Send Message
activate Actor
Actor->>DB: Query/Update
activate DB
DB-->>Actor: Result
deactivate DB
Actor-->>Handler: Response
deactivate Actor
Handler->>MW: HTTP Response
deactivate Handler
activate MW
MW->>Telemetry: Record Duration
MW->>Telemetry: End Trace Span
MW->>Server: Final Response
deactivate MW
Server->>LB: HTTP Response
LB->>Client: Forward Response
OAuth2 Authorization Flow
sequenceDiagram
participant User
participant Client as Client App
participant Browser
participant OAuth2 as OAuth2 Server
participant AuthActor as Auth Actor
participant TokenActor as Token Actor
participant DB as Database
User->>Client: Initiate Login
Client->>Browser: Redirect to /oauth/authorize
Browser->>OAuth2: GET /oauth/authorize
OAuth2->>AuthActor: ValidateAuthRequest
AuthActor->>DB: Check Client
DB-->>AuthActor: Client Valid
AuthActor-->>OAuth2: Request Valid
OAuth2->>User: Show Login/Consent
User->>OAuth2: Approve
OAuth2->>AuthActor: CreateAuthCode
AuthActor->>DB: Store Auth Code
DB-->>AuthActor: Code Stored
AuthActor-->>OAuth2: Authorization Code
OAuth2->>Browser: Redirect with Code
Browser->>Client: Return Code
Client->>OAuth2: POST /oauth/token
OAuth2->>TokenActor: ExchangeCodeForToken
TokenActor->>DB: Validate & Consume Code
TokenActor->>DB: Create Token
DB-->>TokenActor: Token Created
TokenActor-->>OAuth2: Access Token
OAuth2->>Client: Return Token
Client->>User: Authentication Complete
Component Details
Middleware Stack
The middleware stack processes all requests in order:
- TracingLogger: Records request/response with spans
- SessionMiddleware: Manages user sessions
- CorsMiddleware: Handles CORS policies
- MetricsMiddleware: Records metrics
- AuthMiddleware: Validates authentication (selective routes)
App::new()
.wrap(TracingLogger::default()) // 1. Tracing
.wrap(SessionMiddleware::new(/*...*/)) // 2. Sessions
.wrap(Cors::default()) // 3. CORS
.wrap(MetricsMiddleware) // 4. Metrics
.service(
web::scope("/api")
.wrap(AuthMiddleware) // 5. Auth (API only)
.route("/protected", web::get().to(handler))
)
Handler Layer
Handlers process HTTP requests and coordinate with actors:
Handler Responsibilities:
- Request validation
- Parameter extraction
- Actor coordination
- Response formatting
- Error handling
Example Handler Flow:
async fn token_handler(
req: TokenRequest,
token_actor: Data<Addr<TokenActor>>,
) -> Result<HttpResponse, OAuth2Error> {
// 1. Validate request
req.validate()?;
// 2. Send message to actor
let result = token_actor
.send(CreateTokenMessage { /* ... */ })
.await??;
// 3. Format response
Ok(HttpResponse::Ok().json(result))
}
JWT Token Structure
The server issues JWT tokens with the following structure:
{
"header": {
"alg": "HS256",
"typ": "JWT"
},
"payload": {
"sub": "user-id",
"client_id": "client-id",
"scope": "read write",
"iss": "rust_oauth2_server",
"aud": "api.example.com",
"exp": 1704067200,
"iat": 1704063600,
"jti": "token-id"
}
}
Token Claims:
sub: Subject (user ID)
client_id: OAuth2 client identifier
scope: Granted scopes
iss: Issuer
aud: Audience
exp: Expiration time
iat: Issued at time
jti: JWT ID (token identifier)
Security Architecture
Defense in Depth
graph TD
subgraph Layer1[Layer 1 - Network]
TLS[TLS/HTTPS]
FW[Firewall]
DDoS[DDoS Protection]
end
subgraph Layer2[Layer 2 - Application]
CORS[CORS Policy]
CSRF[CSRF Protection]
RateLimit[Rate Limiting]
end
subgraph Layer3[Layer 3 - Authentication]
OAuth2Flow[OAuth2 Flows]
PKCE[PKCE]
Social[Social Login]
end
subgraph Layer4[Layer 4 - Authorization]
Scopes[Scope-Based Access]
JWT[JWT Validation]
TokenIntrospection[Token Introspection]
end
subgraph Layer5[Layer 5 - Data]
Encryption[Data Encryption]
SecretMgmt[Secret Management]
Hashing[Password Hashing]
end
TLS --> CORS
FW --> CORS
DDoS --> CORS
CORS --> OAuth2Flow
CSRF --> OAuth2Flow
RateLimit --> OAuth2Flow
OAuth2Flow --> Scopes
PKCE --> Scopes
Social --> Scopes
Scopes --> Encryption
JWT --> Encryption
TokenIntrospection --> Encryption
style TLS fill:#f44336,color:#fff
style CORS fill:#ff9800,color:#fff
style OAuth2Flow fill:#ffc107
style Scopes fill:#8bc34a
style Encryption fill:#4caf50,color:#fff
Security Features
- PKCE Support: Protects against authorization code interception
- Secure Token Storage: Tokens hashed in database
- Scope-Based Authorization: Fine-grained access control
- Token Revocation: Immediate token invalidation
- Session Security: Secure, HTTP-only cookies
- Password Hashing: Argon2 for password storage
- SQL Injection Prevention: Parameterized queries via SQLx
- XSS Prevention: Input sanitization and CSP headers
- CSRF Protection: State parameter validation
Concurrency Model
graph LR
subgraph HTTPServer[HTTP Server]
W1[Worker 1]
W2[Worker 2]
W3[Worker 3]
W4[Worker 4]
end
subgraph ActorSystem[Actor System]
TA1[Token Actor 1]
TA2[Token Actor 2]
CA1[Client Actor 1]
CA2[Client Actor 2]
end
subgraph DatabasePool[Database Pool]
Conn1[Connection 1]
Conn2[Connection 2]
Conn3[Connection 3]
ConnN[Connection N]
end
W1 --> TA1
W2 --> TA2
W3 --> CA1
W4 --> CA2
TA1 --> Conn1
TA2 --> Conn2
CA1 --> Conn3
CA2 --> ConnN
Performance Benefits:
- Async I/O: Non-blocking operations
- Worker Threads: CPU core utilization
- Connection Pooling: Database efficiency
- Actor Isolation: No lock contention
- Zero-Copy: Efficient data handling
Scalability
Horizontal Scaling:
- Stateless server design
- Session stored in database/Redis
- Load balancer compatible
- No inter-server communication required
Vertical Scaling:
- Multi-threaded workers
- Efficient memory usage
- Fast request processing
- Database connection pooling
Technology Stack
Core Technologies
| Component |
Technology |
Purpose |
| Language |
Rust 2021 |
Type safety, performance |
| Web Framework |
Actix-Web 4.x |
HTTP server |
| Actor Framework |
Actix 0.13 |
Concurrency |
| Database |
SQLx |
Database access |
| JWT |
jsonwebtoken |
Token handling |
| Serialization |
Serde |
JSON processing |
| OpenAPI |
utoipa |
API documentation |
Observability Stack
| Component |
Technology |
Purpose |
| Metrics |
Prometheus |
Metrics collection |
| Tracing |
OpenTelemetry |
Distributed tracing |
| Logging |
tracing-subscriber |
Structured logging |
| Monitoring |
Grafana |
Metrics visualization |
Infrastructure
| Component |
Technology |
Purpose |
| Container |
Docker |
Containerization |
| Orchestration |
Kubernetes |
Container orchestration |
| Database |
PostgreSQL |
Production database |
| Migrations |
Flyway |
Schema management |
| Reverse Proxy |
Nginx/Traefik |
Load balancing, TLS |
Design Principles
1. Type Safety
Rust's type system prevents entire classes of bugs:
- No null pointer exceptions
- No data races
- Memory safety without garbage collection
- Compile-time error detection
2. Actor Model
Benefits of actor-based concurrency:
- Isolated state management
- Message-passing communication
- Fault tolerance
- Scalable design
3. Asynchronous I/O
Non-blocking operations for efficiency:
- Efficient resource utilization
- High concurrency support
- Responsive under load
- Scalable architecture
4. Security First
Security built into every layer:
- Secure by default configuration
- Principle of least privilege
- Defense in depth
- Regular security audits
5. Observability
Comprehensive monitoring and debugging:
- Structured logging
- Distributed tracing
- Prometheus metrics
- Health checks
Configuration Architecture
Configuration is loaded in this order:
- Default values (code)
- Configuration file
- Environment variables (override)
graph LR
Defaults[Default Values] --> ConfigFile[Config File]
ConfigFile --> EnvVars[Environment Variables]
EnvVars --> FinalConfig[Final Configuration]
FinalConfig --> Validation{Validation}
Validation -->|Pass| Server[Start Server]
Validation -->|Fail| Error[Configuration Error]
style Defaults fill:#e3f2fd
style EnvVars fill:#fff3e0
style Server fill:#e8f5e9
style Error fill:#ffebee
Deployment Architecture
Single Instance Deployment
graph TB
subgraph DockerComposeStack[Docker Compose Stack]
Internet[Internet] --> ReverseProxy[Nginx/Traefik]
ReverseProxy --> OAuth2[OAuth2 Server]
OAuth2 --> DB[(PostgreSQL)]
OAuth2 --> OTLP[OTLP Collector]
OTLP --> Jaeger[Jaeger]
OTLP --> Prometheus[Prometheus]
end
style Internet fill:#e1f5ff
style OAuth2 fill:#fff3e0
style DB fill:#f3e5f5
High Availability Deployment
graph TB
Internet[Internet] --> LB[Load Balancer]
LB --> OAuth2_1[OAuth2 Server 1]
LB --> OAuth2_2[OAuth2 Server 2]
LB --> OAuth2_3[OAuth2 Server 3]
OAuth2_1 --> DB_Primary[(PostgreSQL Primary)]
OAuth2_2 --> DB_Primary
OAuth2_3 --> DB_Primary
DB_Primary --> DB_Replica1[(PostgreSQL Replica 1)]
DB_Primary --> DB_Replica2[(PostgreSQL Replica 2)]
OAuth2_1 --> Redis[(Redis Cache)]
OAuth2_2 --> Redis
OAuth2_3 --> Redis
style Internet fill:#e1f5ff
style LB fill:#fff3e0
style DB_Primary fill:#c8e6c9
style DB_Replica1 fill:#f3e5f5
style DB_Replica2 fill:#f3e5f5
Extension Points
The architecture supports extensions through:
- Custom Grant Types: Add new OAuth2 flows
- Token Enhancers: Add custom token claims
- Event Hooks: React to OAuth2 events
- Custom Middleware: Add request/response processing
- Storage Backends: Implement alternative storage
- Social Providers: Add new login providers
Next Steps