JWT Authentication Strategy for Reckon Microservices
View SourceThis document outlines the shared JWT token authentication strategy implemented across Reckon microservices, enabling secure, stateless authentication between reckon_identity
and other services like reckon_portal
.
Architecture Overview
The JWT authentication system consists of several key components:
- ReckonIdentityJwt: Core JWT token generation and validation
- ReckonIdentitySecurity: Authentication attempts and risk assessment
- ReckonIdentitySessions: Session lifecycle management
- ReckonIdentityAuth: Authentication orchestrator coordinating all domains
Key Components
JWT Library (reckon_identity_jwt
)
The foundational JWT library providing:
- Token generation with custom claims
- Token validation and verification
- Plug middleware for Phoenix applications
- Cross-service authentication support
Authentication Orchestrator (reckon_identity_auth
)
High-level authentication workflows:
- Complete login flow (security → session → JWT)
- Token validation across domains
- Token refresh with security checks
- Logout and token revocation
Security Integration (reckon_identity_security
)
Security-focused authentication:
- Risk assessment and monitoring
- Security challenge issuance
- Authentication event logging
- JWT-specific security validation
Session Management (reckon_identity_sessions
)
Session lifecycle with JWT integration:
- Session initialization with token generation
- JWT token validation with session verification
- Token refresh with session updates
- Session revocation affecting JWT validity
Authentication Flow
1. User Login
POST /api/auth/login
{
"account_id": "acc_123",
"credentials": {"password": "secret"},
"device_info": {"type": "web", "fingerprint": "abc123"}
}
Response:
{
"success": true,
"data": {
"account_id": "acc_123",
"session_id": "sess_456",
"access_token": "eyJ0eXAiOiJKV1Qi...",
"refresh_token": "eyJ0eXAiOiJKV1Qi...",
"expires_at": 1640995200,
"token_type": "Bearer"
}
}
2. Token Validation
GET /api/auth/validate
Authorization: Bearer eyJ0eXAiOiJKV1Qi...
3. Token Refresh
POST /api/auth/refresh
{
"refresh_token": "eyJ0eXAiOiJKV1Qi..."
}
4. Logout
POST /api/auth/logout
Authorization: Bearer eyJ0eXAiOiJKV1Qi...
Integration with Other Microservices
For reckon_portal
and Other Services
1. Add JWT Dependency
# In your mix.exs
defp deps do
[
{:reckon_identity_jwt, git: "..."},
# ... other deps
]
end
2. Configure JWT Settings
# In config/config.exs
config :reckon_identity_jwt, ReckonIdentityJwt.Guardian,
issuer: "reckon_identity",
secret_key: "your-shared-secret-key",
ttl: {4, :hours},
verify_issuer: true
3. Use Middleware in Phoenix Router
# In your router.ex
pipeline :authenticated do
plug ReckonIdentityJwt.Middleware
end
pipeline :admin do
plug ReckonIdentityJwt.Middleware, required_scopes: ["admin"]
end
scope "/api", YourAppWeb do
pipe_through [:api, :authenticated]
get "/dashboard", DashboardController, :index
get "/profile", ProfileController, :show
end
4. Access Authentication Context in Controllers
defmodule YourAppWeb.DashboardController do
use YourAppWeb, :controller
def index(conn, _params) do
account_id = ReckonIdentityJwt.Middleware.current_account_id(conn)
claims = ReckonIdentityJwt.Middleware.jwt_claims(conn)
# Use account_id for user-specific data
render(conn, "index.json", account_id: account_id)
end
end
NGINX Configuration
For the microservices architecture with NGINX reverse proxy:
upstream reckon_identity {
server localhost:4000;
}
upstream reckon_portal {
server localhost:4001;
}
server {
listen 80;
server_name reckon.local;
# Route identity requests
location /identity {
proxy_pass http://reckon_identity;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Route main application requests
location / {
proxy_pass http://reckon_portal;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Security Features
JWT Token Claims
Tokens include comprehensive claims for security and session tracking:
{
"sub": "acc_123",
"iss": "reckon_identity",
"aud": "reckon_services",
"exp": 1640995200,
"iat": 1640991600,
"session_id": "sess_456",
"device_fingerprint": "abc123",
"device_type": "web",
"ip_address": "192.168.1.100",
"user_agent": "Mozilla/5.0...",
"token_type": "session"
}
Security Validation
- Risk Assessment: Each authentication attempt is risk-assessed
- Device Tracking: Device fingerprinting and change detection
- IP Monitoring: Location change detection and suspicious activity
- Security Events: Comprehensive audit logging
- Token Expiration: Configurable token lifetimes
- Refresh Security: Additional validation during token refresh
Session Coordination
- Session Validity: JWT tokens are tied to active sessions
- Session Revocation: Revoking sessions invalidates associated JWTs
- Cross-Domain Validation: Sessions verified across all domains
- Device Management: Multi-device session tracking
Error Handling
The system provides detailed error responses for different scenarios:
Authentication Errors
authentication_failed
: Invalid credentialssecurity_challenge_required
: Additional verification neededauthentication_blocked
: Account blocked due to security
Token Errors
token_invalid
: Malformed or tampered tokentoken_expired
: Token past expiration timeinvalid_signature
: Token signature verification failedinsufficient_scopes
: User lacks required permissions
Session Errors
session_invalid
: Session no longer activesession_refresh_failed
: Unable to refresh sessionsecurity_risk_elevated
: Security assessment failed
Development and Testing
Testing Authentication
# Login and get tokens
curl -X POST http://localhost:4000/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"account_id": "test_account",
"credentials": {"password": "test_password"},
"device_info": {"type": "web"}
}'
# Use token to access protected resources
curl -X GET http://localhost:4001/api/dashboard \
-H "Authorization: Bearer eyJ0eXAiOiJKV1Qi..."
Configuration for Different Environments
Development
config :reckon_identity_jwt, ReckonIdentityJwt.Guardian,
secret_key: "dev-secret-key-not-secure",
ttl: {8, :hours}
Production
config :reckon_identity_jwt, ReckonIdentityJwt.Guardian,
secret_key: System.get_env("JWT_SECRET_KEY"),
ttl: {4, :hours},
verify_issuer: true,
allowed_drift: 2000
Best Practices
Security
- Use HTTPS: Always transmit tokens over encrypted connections
- Rotate Secrets: Regularly rotate JWT signing keys
- Monitor Activity: Track authentication events and anomalies
- Scope Permissions: Use minimal required scopes for each service
- Token Storage: Store tokens securely on client side
Performance
- Token Caching: Cache validation results when appropriate
- Async Logging: Use async security event logging
- Connection Pooling: Pool database connections for session validation
- Load Balancing: Distribute authentication load across instances
Monitoring
- Authentication Metrics: Track login success/failure rates
- Token Usage: Monitor token validation frequency
- Security Events: Alert on suspicious authentication patterns
- Performance Metrics: Track authentication latency
Troubleshooting
Common Issues
- Clock Skew: Ensure system clocks are synchronized
- Secret Mismatch: Verify all services use the same JWT secret
- Token Expiration: Check token lifetime configuration
- Network Issues: Verify service-to-service connectivity
- Configuration: Ensure consistent configuration across services
Debug Mode
Enable debug logging for troubleshooting:
config :logger, :console,
level: :debug,
metadata: [:request_id, :account_id, :session_id]
This comprehensive JWT authentication strategy provides secure, scalable authentication across all Reckon microservices while maintaining proper domain separation and security best practices.