Authentication Service
The Authentication Service provides secure JWT-based authentication for the OpenLift platform, handling user login, registration, token management, and security validation.
Overviewβ
The Authentication Service is the security foundation of OpenLift, responsible for:
- User registration and login
- JWT access and refresh token management
- HMAC request signing for production security
- Password validation and security enforcement
- Token refresh and logout operations
Key Featuresβ
π JWT Authenticationβ
- RSA-256 Signing: Public/private key pair for secure token generation
- Dual Token System: Short-lived access tokens (15 min) + long-lived refresh tokens (7 days)
- Automatic Refresh: Seamless token renewal without user intervention
π‘οΈ Production Securityβ
- HMAC Request Signing: All GraphQL and sensitive REST requests require HMAC verification
- Environment-Aware: HMAC disabled in development, enabled in production
- Request Tampering Protection: Ensures request integrity with timestamp validation
π± Client Integrationβ
- Stateless Authentication: JWTs contain all necessary user information
- Secure Storage: Refresh tokens stored server-side for revocation capability
- Mobile-Friendly: Designed for Flutter mobile app integration
Architectureβ
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β Client App β β Auth Service β β Database β
β β β β β β
β β’ Login Form βββββΆβ β’ Validation βββββΆβ β’ User Storage β
β β’ Token Storage ββββββ β’ JWT Creation ββββββ β’ Refresh Token β
β β’ Auto Refresh β β β’ HMAC Signing β β β’ Security Info β
β β’ Logout β β β’ Token Refresh β β β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
Service Responsibilitiesβ
β Authentication Service Handlesβ
- User credential validation
- JWT access token generation and validation
- Refresh token management and rotation
- Password strength enforcement
- User registration with duplicate email/username prevention
- Secure logout with token invalidation
- HMAC signature generation and verification
β Authentication Service Does NOT Handleβ
- User profile management (handled by User Management Service)
- User preferences and settings
- Password reset email sending (delegates to external service)
- User activity tracking and analytics
Key Operationsβ
User Registrationβ
mutation RegisterUser($input: RegisterUserInput!) {
registerUser(input: $input) {
accessToken
refreshToken
user {
id
email
username
}
}
}
User Loginβ
mutation LoginUser($input: LoginUserInput!) {
loginUser(input: $input) {
accessToken
refreshToken
user {
id
email
username
}
}
}
Token Refreshβ
mutation RefreshToken($refreshToken: String!) {
refreshToken(refreshToken: $refreshToken) {
accessToken
refreshToken
}
}
Security Modelβ
Token Structureβ
// Access Token Payload
{
userId: string;
email: string;
username: string;
exp: number; // 15 minutes
iat: number;
}
// Refresh Token (Database)
{
token: string; // Secure random token
userId: string;
expiresAt: Date; // 7 days
createdAt: Date;
}
HMAC Protectionβ
Production requests require HMAC signature headers:
headers: {
'X-Signature': 'sha256=<hmac_signature>',
'X-Timestamp': '<unix_timestamp>',
'X-User-ID': '<user_id>'
}
Integration Patternsβ
Flutter Mobile Appβ
class AuthService {
// Login with automatic token storage
Future<AuthResult> login(String email, String password) async {
final result = await graphql.mutate(loginMutation);
await secureStorage.write('access_token', result.accessToken);
await secureStorage.write('refresh_token', result.refreshToken);
return AuthResult.success(result.user);
}
// Automatic token refresh interceptor
Future<void> refreshTokenIfNeeded() async {
if (isTokenExpired(await getAccessToken())) {
await refreshToken();
}
}
}
GraphQL Client Setupβ
// HTTP interceptor for automatic token management
class AuthInterceptor extends HttpInterceptor {
@override
Future<HttpInterceptorResponse> intercept(HttpInterceptorRequest request) async {
// Add access token to all requests
request.headers['Authorization'] = 'Bearer ${await getAccessToken()}';
// Add HMAC signature in production
if (isProduction) {
final signature = generateHMAC(request.body, timestamp, userId);
request.headers['X-Signature'] = signature;
request.headers['X-Timestamp'] = timestamp;
request.headers['X-User-ID'] = userId;
}
return super.intercept(request);
}
}
Error Handlingβ
Common Authentication Errorsβ
// Handle authentication errors
try {
await authService.login(email, password);
} on GraphQLError catch (e) {
switch (e.extensions?['code']) {
case 'INVALID_CREDENTIALS':
showError('Invalid email or password');
break;
case 'USER_NOT_FOUND':
showError('No account found with this email');
break;
case 'ACCOUNT_LOCKED':
showError('Account temporarily locked due to failed attempts');
break;
case 'WEAK_PASSWORD':
showError('Password must meet security requirements');
break;
default:
showError('Login failed. Please try again.');
}
}
Event Systemβ
Authentication Eventsβ
// Events emitted by Authentication Service
interface AuthEvents {
'user.registered': { userId: string; email: string; };
'user.logged_in': { userId: string; timestamp: Date; };
'user.logged_out': { userId: string; };
'token.refreshed': { userId: string; newTokenId: string; };
'auth.failed': { email: string; reason: string; };
}
Performance Considerationsβ
Token Managementβ
- Short Access Token Lifespans: Reduces security window if compromised
- Stateless Verification: JWTs validated without database lookups
- Efficient Refresh: Only refresh tokens require database operations
HMAC Overheadβ
- Production Only: No HMAC overhead in development
- Request Integrity: Prevents tampering but adds computational cost
- Selective Application: Only applied to sensitive GraphQL and auth endpoints
Development vs Productionβ
Development Modeβ
// Simplified authentication for development
- HMAC signing disabled
- Relaxed password requirements (configurable)
- Extended token lifespans for easier testing
- Detailed error messages for debugging
Production Modeβ
// Enhanced security for production
- HMAC signing required for all sensitive operations
- Strong password requirements enforced
- Standard token lifespans
- Generic error messages to prevent information leakage
Testing Strategyβ
Unit Testsβ
- Password validation logic
- JWT token generation and verification
- HMAC signature creation and validation
- Token expiration handling
Integration Testsβ
- Complete authentication flows
- Token refresh scenarios
- Error handling and edge cases
- HMAC request validation
Security Testsβ
- Brute force protection
- Token tampering resistance
- Expired token handling
- Invalid signature rejection
Monitoring & Analyticsβ
Security Metricsβ
- Failed login attempt rates
- Token refresh frequency
- HMAC validation failures
- Unusual authentication patterns
Performance Metricsβ
- Authentication request latency
- JWT verification performance
- Token generation throughput
- HMAC computation overhead
Related Servicesβ
Dependenciesβ
- Database: User credential storage, refresh token management
- Configuration Service: JWT keys, HMAC secrets, security settings
Consumersβ
- All Services: JWT validation for authenticated requests
- User Management Service: User profile creation after registration
- Activity Tracking: Login/logout event handling
Best Practicesβ
For Flutter Developersβ
- Store tokens in secure storage (never SharedPreferences)
- Implement automatic token refresh with retry logic
- Handle authentication errors gracefully with user-friendly messages
- Always validate token expiration before making requests
For Backend Developersβ
- Use environment variables for JWT signing keys
- Implement proper token rotation on refresh
- Log security events for monitoring
- Never expose sensitive authentication details in error responses
API Documentationβ
For detailed GraphQL schema and usage examples, see:
- Authentication API documentation: coming soon
Supportβ
For authentication-related questions:
- Review the Authentication API documentation
- Check JWT token structure and validation
- Test authentication flows in GraphQL Playground
- Contact the security team for HMAC implementation details