JWT Authentication Strategy for Reckon Microservices

View Source

This 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 credentials
  • security_challenge_required: Additional verification needed
  • authentication_blocked: Account blocked due to security

Token Errors

  • token_invalid: Malformed or tampered token
  • token_expired: Token past expiration time
  • invalid_signature: Token signature verification failed
  • insufficient_scopes: User lacks required permissions

Session Errors

  • session_invalid: Session no longer active
  • session_refresh_failed: Unable to refresh session
  • security_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

  1. Use HTTPS: Always transmit tokens over encrypted connections
  2. Rotate Secrets: Regularly rotate JWT signing keys
  3. Monitor Activity: Track authentication events and anomalies
  4. Scope Permissions: Use minimal required scopes for each service
  5. Token Storage: Store tokens securely on client side

Performance

  1. Token Caching: Cache validation results when appropriate
  2. Async Logging: Use async security event logging
  3. Connection Pooling: Pool database connections for session validation
  4. Load Balancing: Distribute authentication load across instances

Monitoring

  1. Authentication Metrics: Track login success/failure rates
  2. Token Usage: Monitor token validation frequency
  3. Security Events: Alert on suspicious authentication patterns
  4. Performance Metrics: Track authentication latency

Troubleshooting

Common Issues

  1. Clock Skew: Ensure system clocks are synchronized
  2. Secret Mismatch: Verify all services use the same JWT secret
  3. Token Expiration: Check token lifetime configuration
  4. Network Issues: Verify service-to-service connectivity
  5. 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.