WAGERBABE DOCS
All Stories
4-1-jwt-authentication-setupDoneEpic 4.1

Story 4.1: JWT Authentication Setup

Status: done

Tasks

  • Task 1: Generate RSA Keypair (AC: 1)
    • 1.1 Generate RSA 2048-bit private key using OpenSSL - Instructions in jwt_config.py
    • 1.2 Extract public key from private key - Instructions in jwt_config.py
    • 1.3 Document key generation in runbook - `generate_keypair_instructions()` function
    • 1.4 Add keys to `.gitignore` - *.pem already in gitignore
  • Task 2: Secure Key Storage (AC: 2, 10)
    • 2.1 Create `server/app/core/jwt_config.py` configuration module
    • 2.2 Add `JWT_PRIVATE_KEY` and `JWT_PUBLIC_KEY` environment variables
    • 2.4 Implement key loading with proper error handling (log warning, fallback to HS256)
    • 2.5 Add fallback to file-based keys for local development
  • Task 3: RS256 Token Generation (AC: 3, 4, 6)
    • 3.1 Update `create_access_token()` to use RS256 and private key
    • 3.2 Add `iat` (issued at) timestamp to token payload
    • 3.3 Add `iss` (issuer) = "wagerbabe.com" to token payload
    • 3.4 Add `aud` (audience) = "wagerbabe-api" to token payload
    • 3.5 Reduce ACCESS_TOKEN_EXPIRE_HOURS from 24 to 1
    • 3.6 Update `create_refresh_token()` to use RS256
  • Task 4: RS256 Token Validation (AC: 5)
    • 4.1 Create `verify_token()` function using public key only
    • 4.2 Validate `aud` claim matches "wagerbabe-api"
    • 4.3 Validate `iss` claim matches "wagerbabe.com"
    • 4.4 Handle `ExpiredSignatureError` with proper error tuple
    • 4.5 Handle `InvalidTokenError` with proper error tuple
  • Task 5: Migration Support (AC: 7, 8)
    • 5.1 Create `verify_token_hybrid()` function supporting both algorithms
    • 5.2 Try RS256 validation first, fall back to HS256 on failure
    • 5.3 Log deprecation warning when HS256 token validated
    • 5.4 Add `MIGRATION_END_DATE` constant (30 days from deploy: 2026-01-08)
    • 5.5 After migration period, reject HS256 tokens with clear error
  • Task 6: Update Auth Dependencies (AC: 3, 5, 7)
    • 6.1 Update `get_current_user()` to use new validation
    • 6.2 Update `get_current_agent()` - uses get_current_user dependency
    • 6.3 Update `get_current_user_ws()` for WebSocket auth
    • 6.4 Update refresh token endpoint to use hybrid validation
    • 6.5 Add GET /auth/jwt/config endpoint for debugging
  • Task 7: Testing (AC: 9)
    • 7.1 Test RS256 token generation with valid payload
    • 7.2 Test RS256 token validation with public key
    • 7.3 Test expired RS256 token rejection
    • 7.4 Test invalid RS256 token rejection
    • 7.5 Test hybrid validation (RS256 first, HS256 fallback)
    • 7.6 Test HS256 deprecation warning logging
    • 7.7 Test token includes user data
    • 7.8 23 unit tests passing
    • 8.1 Update CLAUDE.md with new JWT configuration - Deferred
    • 8.2 Key generation instructions in jwt_config.py
    • 8.3 Migration timeline documented (MIGRATION_END_DATE constant)

Progress

Tasks7/7
Acceptance Criteria0
Total Tasks7