Skip to content

Latest commit

 

History

History
165 lines (133 loc) · 5.6 KB

File metadata and controls

165 lines (133 loc) · 5.6 KB

Authentication Testing Framework

This document describes the comprehensive authentication testing framework built for the OpenCHAMI boot service using TokenSmith middleware.

🎉 Successfully Implemented

✅ TokenSmith Integration

  • Complete middleware integration with OpenCHAMI TokenSmith
  • RSA key parsing from PEM format for static key validation
  • NIST-compliant JWT tokens with all required claims (auth_level, auth_factors, etc.)
  • Multiple authentication modes: disabled, non-enforcing, enforcing
  • Scope-based authorization with granular permissions

✅ Testing Framework

  • Local JWT generation with properly formatted RSA key pairs
  • Test utilities for creating tokens with various scopes and claims
  • Integration tests covering all authentication scenarios
  • Example server demonstrating practical usage patterns

Testing Capabilities

1. Non-Enforcing Mode

config := NonEnforcingConfig()
// - Allows requests without tokens
// - Logs authentication errors but doesn't block
// - Perfect for development and debugging

2. Static Key Validation

keyPair, _ := GenerateTestKeyPair()
config := CreateStaticKeyConfig(keyPair.PublicKeyPEM)
// - Uses locally generated RSA keys
// - Validates JWT signatures properly
// - Supports all TokenSmith claim requirements

3. Scope-Based Authorization

// Create tokens with specific scopes
readToken := CreateTestTokenWithScopes(keyPair, []string{"read"})
writeToken := CreateTestTokenWithScopes(keyPair, []string{"write"})

// Protect routes with scope requirements
middleware := CreateScopeMiddleware("read", "write")

4. Service-to-Service Authentication

// Service tokens with proper NIST compliance
serviceToken := CreateServiceToken(keyPair, "client-service", "boot-service", []string{"service:boot"})

Test Results

All tests passing:

=== RUN   TestAuthenticationIntegration
=== RUN   TestAuthenticationIntegration/NonEnforcingMode                     ✅ PASS
=== RUN   TestAuthenticationIntegration/ValidTokenWithStaticKey             ✅ PASS
=== RUN   TestAuthenticationIntegration/ScopeBasedAuthorization             ✅ PASS
=== RUN   TestAuthenticationIntegration/ServiceToServiceAuthentication      ✅ PASS
=== RUN   TestAuthenticationIntegration/ExpiredTokenHandling                ✅ PASS
=== RUN   TestAuthenticationIntegration/InvalidTokenHandling                ✅ PASS
--- PASS: TestAuthenticationIntegration (0.72s)

Key Issues Resolved

🔧 RSA Key Parsing

Problem: TokenSmith middleware expected *rsa.PublicKey but was getting string Solution: Added proper PEM parsing in config.go:

keyPem, _ := pem.Decode([]byte(c.JWTPublicKey))
pubKey, _ := x509.ParsePKIXPublicKey(keyPem.Bytes)
rsaKey := pubKey.(*rsa.PublicKey)

🔧 Non-Enforcing Mode

Problem: Middleware was still requiring tokens even in non-enforcing mode Solution: Used AllowEmptyToken: true option:

config.AllowEmptyToken = true  // Allow requests without tokens
config.NonEnforcing = true     // Log errors but don't fail

🔧 NIST Claims Compliance

Problem: TokenSmith requires specific claims for NIST SP 800-63B compliance Solution: Added all required claims to test tokens:

claims := &token.TSClaims{
    AuthLevel:   "IAL2",
    AuthFactors: 2,
    AuthMethods: []string{"password", "mfa"},
    SessionID:   "test-session-123",
    SessionExp:  now.Add(1 * time.Hour).Unix(),
    AuthEvents:  []string{"login"},
    // ... other standard JWT claims
}

🔧 Scope Consistency

Problem: Mismatched scope names between tokens and middleware expectations Solution: Standardized on simple scope names (read, write, service:boot)

Usage Examples

Development Mode (No Auth)

config := auth.DevConfig()  // Disabled authentication
middleware := config.CreateMiddleware(logger)

Non-Enforcing Mode (Logs Only)

config := auth.NonEnforcingConfig()  // Allows empty tokens
middleware := config.CreateMiddleware(logger)

Production Mode (Full Validation)

config := auth.DefaultConfig()
config.JWTPublicKey = publicKeyPEM
middleware := config.CreateMiddleware(logger)

Scope Protection

// Protect routes requiring specific scopes
readOnlyMiddleware := auth.CreateScopeMiddleware("read")
writeMiddleware := auth.CreateScopeMiddleware("read", "write")

Manual Testing

The example server (examples/auth-testing/main.go) provides:

  • Generated test tokens for immediate use
  • Multiple auth configurations (dev, non-enforcing, enforcing)
  • Sample curl commands for manual testing
  • Different route protections demonstrating scope requirements

Run with: go run examples/auth-testing/main.go

Files Created/Modified

  • pkg/auth/config.go - RSA key parsing fixes
  • pkg/auth/testing.go - Test utilities and token generation
  • pkg/auth/integration_test.go - Comprehensive integration tests
  • examples/auth-testing/main.go - Practical demonstration server

Next Steps

  1. JWKS Support: Add integration with JWKS URLs for dynamic key rotation
  2. Policy Integration: Connect with OpenCHAMI policy engines for dynamic authorization
  3. Metrics: Add authentication metrics and monitoring
  4. Documentation: Complete API documentation with authentication examples

The authentication framework is now production-ready with comprehensive testing capabilities for both local development and integration with OpenCHAMI TokenSmith in deployed environments.