# Rodauth-OAuth: Quick Reference Guide ## What Is It? A production-ready Ruby gem implementing OAuth 2.0 and OpenID Connect. Think of it as a complete, standards-certified OAuth/OIDC server library for Ruby apps. ## Key Stats - **Framework**: Roda (not Rails, but works with Rails via wrapper) - **Features**: 34 modular features you can enable/disable - **Certification**: Officially certified for 11 OpenID Connect profiles - **Test Coverage**: Hundreds of tests - **Status**: Production-ready, actively maintained ## Why Consider It? ### Advantages Over Your Implementation 1. **Complete OAuth/OIDC Implementation** - All major grant types supported - Certified compliance with standards - 20+ RFC implementations 2. **Security Features** - Token hashing (bcrypt) by default - DPoP support (token binding) - TLS mutual authentication - Proper scope enforcement 3. **Advanced Token Management** - Refresh tokens (you don't have) - Token revocation - Token introspection - Token rotation policies 4. **Low Maintenance** - Well-tested codebase - Active community - Regular spec updates - Battle-tested in production 5. **Extensible** - Highly configurable - Override any behavior you need - Database-agnostic - Works with any SQL DB ### What Your Implementation Does Better 1. **Simplicity** - Fewer lines of code, easier to understand 2. **Rails Native** - No need to learn Roda 3. **Control** - Full ownership of the codebase 4. **Minimal Dependencies** - Just JWT and OpenSSL ## Architecture Overview ### Your Current Setup ``` Rails App └─ OidcController (450 lines) ├─ /oauth/authorize ├─ /oauth/token ├─ /oauth/userinfo └─ /logout Models: ├─ OidcAuthorizationCode ├─ OidcAccessToken └─ OidcUserConsent Features Supported: ├─ Authorization Code Flow ✓ ├─ PKCE ✓ └─ Basic OIDC ✓ NOT Supported: ├─ Refresh Tokens ├─ Token Revocation ├─ Token Introspection ├─ Client Credentials Grant ├─ Device Code Flow ├─ Session Management ├─ Front/Back-Channel Logout └─ Dynamic Client Registration ``` ### Rodauth-OAuth Setup ``` Roda App (web framework) └─ Rodauth Plugin (authentication/authorization) ├─ oauth_base (foundation) ├─ oauth_authorization_code_grant ├─ oauth_pkce ├─ oauth_jwt (optional) ├─ oidc (OpenID core) ├─ oidc_session_management (optional) ├─ oidc_rp_initiated_logout (optional) ├─ oidc_frontchannel_logout (optional) ├─ oidc_backchannel_logout (optional) ├─ oauth_token_revocation (optional) ├─ oauth_token_introspection (optional) ├─ oauth_client_credentials_grant (optional) └─ ... (28+ more optional features) Routes Generated Automatically: ├─ /.well-known/openid-configuration ✓ ├─ /.well-known/jwks.json ✓ ├─ /oauth/authorize ✓ ├─ /oauth/token ✓ ├─ /oauth/userinfo ✓ ├─ /oauth/introspect (optional) ├─ /oauth/revoke (optional) └─ /logout ✓ ``` ## Database Schema Comparison ### Your Current Tables ``` oidc_authorization_codes ├─ id ├─ user_id ├─ application_id ├─ code (unique) ├─ redirect_uri ├─ scope ├─ nonce ├─ code_challenge ├─ code_challenge_method ├─ used (boolean) ├─ expires_at └─ created_at oidc_access_tokens ├─ id ├─ user_id ├─ application_id ├─ token (unique) ├─ scope ├─ expires_at └─ created_at oidc_user_consents ├─ user_id ├─ application_id ├─ scopes_granted └─ granted_at applications ├─ id ├─ name ├─ client_id (unique) ├─ client_secret ├─ redirect_uris (JSON) ├─ app_type └─ ... (few more fields) ``` ### Rodauth-OAuth Tables ``` accounts (from rodauth) ├─ id ├─ status_id ├─ email └─ password_hash oauth_applications (75+ columns!) ├─ Basic: id, account_id, name, description ├─ OAuth: client_id, client_secret, redirect_uri, scopes ├─ Config: token_endpoint_auth_method, grant_types, response_types ├─ JWT/JWKS: jwks_uri, jwks, jwt_public_key ├─ OIDC: subject_type, id_token_signed_response_alg, etc. ├─ PAR: require_pushed_authorization_requests ├─ DPoP: dpop_bound_access_tokens ├─ TLS: tls_client_auth_* fields └─ Logout: post_logout_redirect_uris, frontchannel_logout_uri, etc. oauth_grants (consolidated - replaces your two tables!) ├─ id, account_id, oauth_application_id ├─ type (authorization_code, refresh_token, etc.) ├─ code, token, refresh_token (with hashed versions) ├─ expires_in, revoked_at ├─ scopes, access_type ├─ code_challenge, code_challenge_method (PKCE) ├─ user_code, last_polled_at (Device code grant) ├─ nonce, acr, claims (OIDC) ├─ dpop_jkt (DPoP) └─ certificate_thumbprint, resource (advanced) [Optional tables for features you enable] ``` ## Feature Comparison Matrix | Feature | Your Code | Rodauth-OAuth | Effort to Add* | |---------|-----------|---------------|--------| | Authorization Code Flow | ✓ | ✓ | N/A | | PKCE | ✓ | ✓ | N/A | | Refresh Tokens | ✗ | ✓ | 1-2 weeks | | Token Revocation | ✗ | ✓ | 1 week | | Token Introspection | ✗ | ✓ | 1 week | | Client Credentials Grant | ✗ | ✓ | 2 weeks | | Device Code Flow | ✗ | ✓ | 3 weeks | | JWT Access Tokens | ✗ | ✓ | 1 week | | Session Management | ✗ | ✓ | 2-3 weeks | | Front-Channel Logout | ✗ | ✓ | 1-2 weeks | | Back-Channel Logout | ✗ | ✓ | 2 weeks | | Dynamic Client Reg | ✗ | ✓ | 3-4 weeks | | Token Hashing | ✗ | ✓ | 1 week | *Time estimates for adding to your implementation ## Code Examples ### Rodauth-OAuth: Minimal OAuth Server ```ruby # Gemfile gem 'roda' gem 'rodauth-oauth' gem 'sequel' # lib/auth_server.rb class AuthServer < Roda plugin :sessions, secret: ENV['SESSION_SECRET'] plugin :rodauth do db DB enable :login, :logout, :create_account, :oidc, :oauth_pkce, :oauth_authorization_code_grant, :oauth_token_revocation oauth_application_scopes %w[openid email profile] oauth_require_pkce true end route do |r| r.rodauth # All OAuth endpoints auto-mounted! # Your app logic here end end ``` That's it! All these endpoints are automatically available: - GET /.well-known/openid-configuration - GET /.well-known/jwks.json - GET /oauth/authorize - POST /oauth/token - POST /oauth/revoke - GET /oauth/userinfo - GET /logout ### Your Current Approach ```ruby # app/controllers/oidc_controller.rb class OidcController < ApplicationController def authorize # 150 lines of validation logic end def token # 100 lines of token generation logic end def userinfo # 50 lines of claims logic end def logout # 50 lines of logout logic end private def validate_pkce(auth_code, code_verifier) # 50 lines of PKCE validation end end ``` ## Integration Paths ### Option 1: Stick with Your Implementation - Keep building features incrementally - Effort: 2-3 months to reach feature parity - Pro: Rails native, full control - Con: Continuous maintenance burden ### Option 2: Switch to Rodauth-OAuth - Learn Roda/Rodauth (1-2 weeks) - Migrate database (1 week) - Replace 450 lines of code with config (1 week) - Testing & validation (2-3 weeks) - Effort: 4-8 weeks total - Pro: Production-ready, certified, maintained - Con: Different framework (Roda) ### Option 3: Hybrid Approach - Keep your Rails app for business logic - Use rodauth-oauth as separate OAuth/OIDC service - Services communicate via HTTP/APIs - Effort: 2-3 weeks (independent services) - Pro: Best of both worlds - Con: Operational complexity ## Decision Matrix ### Use Rodauth-OAuth If You Need... - [x] Standards compliance (OpenID certified) - [x] Multiple grant types (Client Credentials, Device Code, etc.) - [x] Token revocation/introspection - [x] Refresh tokens - [x] Advanced logout (front/back-channel) - [x] Session management - [x] Token hashing/security best practices - [x] Hands-off maintenance - [x] Production-battle-tested code ### Keep Your Implementation If You... - [x] Only need Authorization Code + PKCE - [x] Want zero Roda/external framework learning - [x] Value Rails patterns over standards - [x] Like to understand every line of code - [x] Can allocate time for ongoing maintenance - [x] Prefer minimal dependencies ## Key Differences You'll Notice ### 1. Framework Paradigm - **Your impl**: Rails (MVC, familiar) - **Rodauth**: Roda (routing-focused, lightweight) ### 2. Database ORM - **Your impl**: ActiveRecord (Rails native) - **Rodauth**: Sequel (lighter, more control) ### 3. Configuration Style - **Your impl**: Rails initializers, environment variables - **Rodauth**: Plugin block with DSL ### 4. Model Management - **Your impl**: Rails models with validations, associations - **Rodauth**: Minimal models, logic in database ### 5. Testing Approach - **Your impl**: RSpec, model/controller tests - **Rodauth**: Request-based integration tests ## File Locations (If You Switch) ``` Current Structure ├── app/controllers/oidc_controller.rb ├── app/models/ │ ├── oidc_authorization_code.rb │ ├── oidc_access_token.rb │ └── oidc_user_consent.rb ├── app/services/oidc_jwt_service.rb ├── db/migrate/*oidc*.rb Rodauth-OAuth Equivalent ├── lib/rodauth_app.rb # Configuration (replaces most controllers) ├── app/views/rodauth/ # Templates (consent form, etc.) ├── config/routes.rb # Simple: routes mount rodauth └── db/migrate/*rodauth_oauth*.rb ``` ## Performance Considerations ### Your Implementation - Small tables → fast queries - Fewer columns → less overhead - Simple token validation - Estimated: 5-10ms per token validation ### Rodauth-OAuth - More columns, but same queries - Optional token hashing (slight overhead) - More features = more options checked - Estimated: 10-20ms per token validation - Can be optimized: disable unused features ## Getting Started (If You Want to Explore) 1. **Review the code** ```bash cd /Users/dkam/Development/clinch/tmp/rodauth-oauth ls -la lib/rodauth/features/ # See all features cat examples/oidc/authentication_server.rb # Full working example ``` 2. **Run the example** ```bash cd /Users/dkam/Development/clinch/tmp/rodauth-oauth/examples ruby oidc/authentication_server.rb # Starts server on http://localhost:9292 ``` 3. **Read the key files** - README.md: Overview - MIGRATION-GUIDE-v1.md: Version migration (shows architecture) - test/migrate/*.rb: Database schema - examples/oidc/*.rb: Complete working implementation ## Next Steps 1. **If keeping your implementation:** - Prioritize refresh token support - Add token revocation endpoint - Consider token hashing 2. **If exploring rodauth-oauth:** - Run the example server - Review the feature files - Check if hybrid approach works for your org 3. **For either path:** - Document your decision - Plan feature roadmap - Set up appropriate monitoring --- **Bottom Line**: Rodauth-OAuth is the "production-grade" option if you need comprehensive OAuth/OIDC. Your implementation is fine if you keep features minimal and have maintenance bandwidth.