From e288fcad7c0db7477cf519d1a5f9f929207376c6 Mon Sep 17 00:00:00 2001 From: Dan Milne Date: Thu, 1 Jan 2026 21:04:26 +1100 Subject: [PATCH] Remove old docs --- docs/README_RODAUTH_ANALYSIS.md | 275 -------- docs/RODAUTH_DECISION_GUIDE.md | 426 ------------ docs/rodauth-oauth-analysis.md | 913 -------------------------- docs/rodauth-oauth-quick-reference.md | 418 ------------ 4 files changed, 2032 deletions(-) delete mode 100644 docs/README_RODAUTH_ANALYSIS.md delete mode 100644 docs/RODAUTH_DECISION_GUIDE.md delete mode 100644 docs/rodauth-oauth-analysis.md delete mode 100644 docs/rodauth-oauth-quick-reference.md diff --git a/docs/README_RODAUTH_ANALYSIS.md b/docs/README_RODAUTH_ANALYSIS.md deleted file mode 100644 index e041667..0000000 --- a/docs/README_RODAUTH_ANALYSIS.md +++ /dev/null @@ -1,275 +0,0 @@ -# Rodauth-OAuth Analysis Documents - -This directory contains a comprehensive analysis of rodauth-oauth and how it compares to your custom OIDC implementation in Clinch. - -## Start Here - -### 1. **RODAUTH_DECISION_GUIDE.md** (15-minute read) -**Purpose:** Help you make a decision about your OAuth/OIDC implementation - -**Contains:** -- TL;DR of three options -- Decision flowchart -- Feature roadmap scenarios -- Effort estimates for each path -- Security comparison -- Real-world questions to ask your team -- Next actions for each option - -**Best for:** Deciding whether to keep your implementation, migrate, or use a hybrid approach - ---- - -### 2. **rodauth-oauth-quick-reference.md** (20-minute read) -**Purpose:** Quick lookup guide and architecture overview - -**Contains:** -- What Rodauth-OAuth is (concise) -- Key statistics and certifications -- Feature advantages & disadvantages -- Architecture diagrams (text-based) -- Database schema comparison -- Feature matrix with implementation effort -- Performance considerations -- Getting started guide -- Code examples (minimal setup) - -**Best for:** Understanding what you're looking at, quick decision support - ---- - -### 3. **rodauth-oauth-analysis.md** (45-minute deep-dive) -**Purpose:** Comprehensive technical analysis for decision-making - -**Contains:** -- Complete architecture breakdown (12 sections) -- All 34 features detailed and explained -- Full database schema documentation -- Request flow diagrams -- Feature dependency graphs -- Integration paths with Rails -- Security analysis -- Migration procedures -- Code comparisons -- Performance metrics - -**Best for:** Deep understanding before making technical decisions, planning migrations - ---- - -## How to Use These Documents - -### Scenario 1: "I have 15 minutes" -1. Read: RODAUTH_DECISION_GUIDE.md (sections: TL;DR + Decision Matrix) -2. Go to: Next Actions for your chosen option -3. Done: You have a direction - -### Scenario 2: "I have 45 minutes" -1. Read: RODAUTH_DECISION_GUIDE.md (complete) -2. Skim: rodauth-oauth-quick-reference.md (focus on code examples) -3. Decide: Which path interests you most -4. Plan: Team discussion using decision matrix - -### Scenario 3: "I'm doing technical deep-dive" -1. Read: RODAUTH_DECISION_GUIDE.md (complete) -2. Read: rodauth-oauth-quick-reference.md (complete) -3. Read: rodauth-oauth-analysis.md (sections 1-6) -4. Reference: rodauth-oauth-analysis.md (sections 7-12 as needed) - -### Scenario 4: "I'm planning a migration" -1. Read: RODAUTH_DECISION_GUIDE.md (effort estimates section) -2. Read: rodauth-oauth-analysis.md (migration path section) -3. Reference: rodauth-oauth-analysis.md (database schema section) -4. Plan: Detailed migration steps - ---- - -## Three Options Explained (Very Brief) - -### Option A: Keep Your Implementation -- **Time:** Ongoing (add features incrementally) -- **Effort:** 4-6 months to reach feature parity -- **Maintenance:** 8-10 hours/month -- **Best if:** Auth Code + PKCE is sufficient forever - -### Option B: Switch to Rodauth-OAuth -- **Time:** 5-9 weeks (one-time migration) -- **Learning:** 1-2 weeks (Roda framework) -- **Maintenance:** 1-2 hours/month -- **Best if:** Need enterprise features, want low maintenance - -### Option C: Hybrid Approach (Microservices) -- **Time:** 3-5 weeks (independent setup) -- **Learning:** Low (Roda is isolated) -- **Maintenance:** 2-3 hours/month -- **Best if:** Want Option B benefits without full Rails→Roda migration - ---- - -## Key Findings - -**What Rodauth-OAuth Provides That You Don't Have:** -- Refresh tokens -- Token revocation (RFC 7009) -- Token introspection (RFC 7662) -- Client Credentials grant (machine-to-machine) -- Device Code flow (IoT/smart TV) -- JWT Access Tokens (stateless) -- Session Management -- Front & Back-Channel Logout -- Token hashing (bcrypt security) -- DPoP support (token binding) -- TLS mutual authentication -- Dynamic Client Registration -- 20+ more optional features - -**Security Differences:** -- Your impl: Tokens stored in plaintext (DB breach = token theft) -- Rodauth: Tokens hashed with bcrypt (secure even if DB breached) - -**Maintenance Burden:** -- Your impl: YOU maintain everything -- Rodauth: Community maintains, you maintain config only - ---- - -## Document Structure - -### RODAUTH_DECISION_GUIDE.md Sections: -``` -1. TL;DR - Three options -2. Decision Matrix - Flowchart -3. Feature Roadmap Comparison -4. Architecture Diagrams (visual) -5. Effort Estimates -6. Real-World Questions -7. Security Comparison -8. Cost-Benefit Summary -9. Decision Scorecard -10. Next Actions -``` - -### rodauth-oauth-quick-reference.md Sections: -``` -1. What Is It? (overview) -2. Key Stats -3. Why Consider It? (advantages) -4. Architecture Overview (your impl vs rodauth) -5. Database Schema Comparison -6. Feature Comparison Matrix -7. Code Examples -8. Integration Paths -9. Getting Started -10. Next Steps -``` - -### rodauth-oauth-analysis.md Sections: -``` -1. Executive Summary -2. What Rodauth-OAuth Is -3. File Structure & Organization -4. OIDC/OAuth Features -5. Architecture: How It Works -6. Database Schema Requirements -7. Integration with Rails -8. Architectural Comparison -9. Feature Matrix -10. Integration Complexity -11. Key Findings & Recommendations -12. Migration Path & Code Examples -``` - ---- - -## For Your Team - -### Sharing with Stakeholders -- **Non-technical:** Use RODAUTH_DECISION_GUIDE.md (TL;DR section) -- **Technical leads:** Use rodauth-oauth-quick-reference.md -- **Engineers:** Use rodauth-oauth-analysis.md (sections 1-6) -- **Security team:** Use rodauth-oauth-analysis.md (security sections) - -### Team Discussion -Print out the decision matrix from RODAUTH_DECISION_GUIDE.md and: -1. Walk through each option -2. Discuss team comfort with framework learning -3. Check against feature roadmap -4. Decide on maintenance philosophy -5. Vote on preferred option - ---- - -## Next Steps After Reading - -### If Choosing Option A (Keep Custom): -- [ ] Plan feature roadmap (refresh tokens first) -- [ ] Allocate team capacity -- [ ] Add token hashing security -- [ ] Set up security monitoring - -### If Choosing Option B (Full Migration): -- [ ] Assign team member to learn Roda/Rodauth -- [ ] Run examples from `/tmp/rodauth-oauth/examples` -- [ ] Plan database migration -- [ ] Prepare rollback plan -- [ ] Schedule migration window - -### If Choosing Option C (Hybrid): -- [ ] Evaluate microservices capability -- [ ] Review service communication plan -- [ ] Set up service infrastructure -- [ ] Plan gradual deployment - ---- - -## Bonus: Running the Example - -Rodauth-OAuth includes a working OIDC server example you can run: - -```bash -cd /Users/dkam/Development/clinch/tmp/rodauth-oauth/examples/oidc -ruby authentication_server.rb - -# Then visit: http://localhost:9292 -# Login with: foo@bar.com / password -# See: Full OIDC provider in action -``` - ---- - -## Questions? - -These documents should answer: -- What is rodauth-oauth? -- How does it compare to my implementation? -- What features would we gain? -- What would we lose? -- How much effort is a migration? -- Should we switch? - -If questions remain, reference the specific section in the analysis documents. - ---- - -## Document Generation Info - -**Generated:** November 12, 2025 -**Analysis Duration:** Complete codebase exploration of rodauth-oauth gem -**Sources Analyzed:** -- 34 feature files (10,000+ lines of code) -- 7 database migrations -- 6 complete example applications -- Comprehensive test suite -- README and migration guides - -**Analysis Includes:** -- Line-by-line code structure review -- Database schema comparison -- Feature cross-reference analysis -- Integration complexity assessment -- Security analysis -- Effort estimation models - ---- - -**Start with RODAUTH_DECISION_GUIDE.md and go from there!** diff --git a/docs/RODAUTH_DECISION_GUIDE.md b/docs/RODAUTH_DECISION_GUIDE.md deleted file mode 100644 index f3717d9..0000000 --- a/docs/RODAUTH_DECISION_GUIDE.md +++ /dev/null @@ -1,426 +0,0 @@ -# Rodauth-OAuth Decision Guide - -## TL;DR - Make Your Choice Here - -### Option A: Keep Your Rails Implementation -**Best if:** Authorization Code + PKCE is all you need, forever -- Keep your current 450 lines of OIDC controller code -- Maintain incrementally as needs change -- Stay 100% in Rails ecosystem -- Time investment: Ongoing (2-3 months to feature parity) -- Learning curve: None (already know Rails) - -### Option B: Switch to Rodauth-OAuth -**Best if:** You need enterprise features, standards compliance, low maintenance -- Replace 450 lines with plugin config -- Get 34 optional features on demand -- OpenID Certified, production-hardened -- Time investment: 4-8 weeks (one-time) -- Learning curve: Medium (learn Roda/Rodauth) - -### Option C: Hybrid (Recommended if Option B appeals you) -**Best if:** You want rodauth-oauth benefits without framework change -- Run Rodauth-OAuth as separate microservice -- Keep your Rails app unchanged -- Services talk via HTTP APIs -- Time investment: 2-3 weeks (independent services) -- Learning curve: Low (Roda is isolated) - ---- - -## Decision Matrix - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ Do you need features beyond Authorization Code + PKCE? │ -├─────────────────────────────────────────────────────────────────┤ -│ YES ─→ Go to Question 2 │ -│ NO ─→ KEEP YOUR IMPLEMENTATION │ -└─────────────────────────────────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────────────────────────────────┐ -│ Can your team learn Roda (different from Rails)? │ -├─────────────────────────────────────────────────────────────────┤ -│ YES ─→ SWITCH TO RODAUTH-OAUTH │ -│ NO ─→ Go to Question 3 │ -└─────────────────────────────────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────────────────────────────────┐ -│ Can you run separate services (microservices)? │ -├─────────────────────────────────────────────────────────────────┤ -│ YES ─→ USE HYBRID APPROACH │ -│ NO ─→ KEEP YOUR IMPLEMENTATION │ -└─────────────────────────────────────────────────────────────────┘ -``` - ---- - -## Feature Roadmap Comparison - -### Scenario 1: You Need Refresh Tokens (Common) - -**Option A (Keep Custom):** -- Implement refresh token endpoints -- Add refresh_token columns to DB -- Token rotation logic -- Estimate: 1-2 weeks of work -- Ongoing: Maintain refresh token security - -**Option B (Rodauth-OAuth):** -- Already built and tested -- Just enable: `:oauth_authorization_code_grant` (includes refresh) -- Token rotation: Configurable options -- Estimate: Already included -- Ongoing: Community maintains - -**Option C (Hybrid):** -- Rodauth-OAuth handles it -- Your app unchanged -- Same as Option B for this feature - -### Scenario 2: You Need Token Revocation - -**Option A (Keep Custom):** -- Build `/oauth/revoke` endpoint -- Implement token blacklist or DB update -- Handle race conditions -- Estimate: 1-2 weeks -- Ongoing: Monitor revocation leaks - -**Option B (Rodauth-OAuth):** -- Enable `:oauth_token_revocation` feature -- RFC 7009 compliant out of the box -- Estimate: Already included -- Ongoing: Community handles RFC updates - -**Option C (Hybrid):** -- Same as Option B - -### Scenario 3: You Need Client Credentials Grant - -**Option A (Keep Custom):** -- New endpoint logic -- Client authentication (different from user auth) -- Token generation for apps without users -- Estimate: 2-3 weeks -- Ongoing: Test with external clients - -**Option B (Rodauth-OAuth):** -- Enable `:oauth_client_credentials_grant` feature -- All edge cases handled -- Estimate: Already included -- Ongoing: Community maintains - -**Option C (Hybrid):** -- Same as Option B - ---- - -## Architecture Diagrams - -### Current Setup (Your Implementation) -``` -┌─────────────────────────────┐ -│ Your Rails Application │ -├─────────────────────────────┤ -│ app/controllers/ │ -│ oidc_controller.rb │ ← 450 lines of OAuth logic -│ │ -│ app/models/ │ -│ OidcAuthorizationCode │ -│ OidcAccessToken │ -│ OidcUserConsent │ -│ │ -│ app/services/ │ -│ OidcJwtService │ -├─────────────────────────────┤ -│ Rails ActiveRecord │ -├─────────────────────────────┤ -│ PostgreSQL Database │ -│ - oidc_authorization_codes -│ - oidc_access_tokens -│ - oidc_user_consents -│ - applications -└─────────────────────────────┘ -``` - -### Option B: Full Migration -``` -┌──────────────────────────────┐ -│ Roda + Rodauth-OAuth App │ -├──────────────────────────────┤ -│ lib/rodauth_app.rb │ ← Config (not code!) -│ enable :oidc, │ -│ enable :oauth_pkce, │ -│ enable :oauth_token_... │ -│ │ -│ [Routes auto-mounted] │ -│ /.well-known/config │ -│ /oauth/authorize │ -│ /oauth/token │ -│ /oauth/userinfo │ -│ /oauth/revoke │ -│ /oauth/introspect │ -├──────────────────────────────┤ -│ Sequel ORM │ -├──────────────────────────────┤ -│ PostgreSQL Database │ -│ - accounts (rodauth) -│ - oauth_applications -│ - oauth_grants (unified!) -│ - optional feature tables -└──────────────────────────────┘ -``` - -### Option C: Microservices Architecture (Hybrid) -``` -┌──────────────────────────┐ ┌──────────────────────────┐ -│ Your Rails App │ │ Rodauth-OAuth Service │ -├──────────────────────────┤ ├──────────────────────────┤ -│ Normal Rails Controllers │ │ lib/rodauth_app.rb │ -│ & Business Logic │ │ [OAuth Features] │ -│ │ │ │ -│ HTTP Calls to →──────────┼─────→ /.well-known/config │ -│ OAuth Service OAuth │ │ /oauth/authorize │ -│ HTTP API │ │ /oauth/token │ -│ │ │ /oauth/userinfo │ -│ Verify Tokens via →──────┼─────→ /oauth/introspect │ -│ /oauth/introspect │ │ │ -├──────────────────────────┤ ├──────────────────────────┤ -│ Rails ActiveRecord │ │ Sequel ORM │ -├──────────────────────────┤ ├──────────────────────────┤ -│ PostgreSQL │ │ PostgreSQL │ -│ [business tables] │ │ [oauth tables] │ -└──────────────────────────┘ └──────────────────────────┘ -``` - ---- - -## Effort Estimates - -### Option A: Keep & Enhance Custom Implementation -``` -Refresh Tokens: 1-2 weeks -Token Revocation: 1-2 weeks -Token Introspection: 1-2 weeks -Client Credentials: 2-3 weeks -Device Code: 3-4 weeks -JWT Access Tokens: 1-2 weeks -Session Management: 2-3 weeks -Front-Channel Logout: 1-2 weeks -Back-Channel Logout: 2-3 weeks -───────────────────────────────── -TOTAL FOR PARITY: 15-25 weeks -(4-6 months of work) - -ONGOING MAINTENANCE: ~8-10 hours/month -(security updates, RFC changes, bug fixes) -``` - -### Option B: Migrate to Rodauth-OAuth -``` -Learn Roda/Rodauth: 1-2 weeks -Migrate Database Schema: 1-2 weeks -Replace OIDC Code: 1-2 weeks -Test & Validation: 2-3 weeks -───────────────────────────────── -ONE-TIME EFFORT: 5-9 weeks -(1-2 months) - -ONGOING MAINTENANCE: ~1-2 hours/month -(dependency updates, config tweaks) -``` - -### Option C: Hybrid Approach -``` -Set up Rodauth service: 1-2 weeks -Configure integration: 1-2 weeks -Test both services: 1 week -───────────────────────────────── -ONE-TIME EFFORT: 3-5 weeks -(less than Option B) - -ONGOING MAINTENANCE: ~2-3 hours/month -(maintain two services, but Roda handles OAuth) -``` - ---- - -## Real-World Questions to Ask Your Team - -### Question 1: Feature Needs -- "Do we need refresh tokens?" -- "Will clients ask for token revocation?" -- "Do we support service-to-service auth (client credentials)?" -- "Will we ever need device code flow (IoT)?" - -If YES to any: **Option B or C makes sense** - -### Question 2: Maintenance Philosophy -- "Do we want to own the OAuth code?" -- "Can we afford to maintain OAuth compliance?" -- "Do we have experts in OAuth/OIDC?" - -If NO to all: **Option B or C is better** - -### Question 3: Framework Flexibility -- "Is Rails non-negotiable for this company?" -- "Can our team learn a new framework?" -- "Can we run microservices?" - -If Rails is required: **Option C (hybrid)** - -### Question 4: Time Constraints -- "Do we have 4-8 weeks for a migration?" -- "Can we maintain OAuth for years?" -- "What if specs change?" - -If time-constrained: **Option B is fastest path to full features** - ---- - -## Security Comparison - -### Your Implementation -- ✓ PKCE support -- ✓ JWT signing -- ✓ HTTPS recommended -- ✗ Token hashing (stores tokens in plaintext) -- ✗ Token rotation -- ✗ DPoP (token binding) -- ✗ Automatic spec compliance -- Risk: Token theft if DB compromised - -### Rodauth-OAuth -- ✓ PKCE support -- ✓ JWT signing -- ✓ Token hashing (bcrypt by default) -- ✓ Token rotation policies -- ✓ DPoP support (RFC 9449) -- ✓ TLS mutual authentication -- ✓ Automatic spec updates -- ✓ Certified compliance -- Risk: Minimal (industry-standard) - ---- - -## Cost-Benefit Summary - -### Keep Your Implementation -``` -Costs: - - 15-25 weeks to feature parity - - Ongoing security monitoring - - Spec compliance tracking - - Bug fixes & edge cases - -Benefits: - - No framework learning - - Full code understanding - - Rails-native patterns - - Minimal dependencies -``` - -### Switch to Rodauth-OAuth -``` -Costs: - - 5-9 weeks migration effort - - Learn Roda/Rodauth - - Database schema changes - - Test all flows - -Benefits: - - Get 34 features immediately - - Certified compliance - - Community-maintained - - Security best practices - - Ongoing support -``` - -### Hybrid Approach -``` -Costs: - - 3-5 weeks setup - - Learn Roda basics - - Operate two services - - Service communication - -Benefits: - - All Rodauth-OAuth features - - Rails app unchanged - - Independent scaling - - Clear separation of concerns -``` - ---- - -## Decision Scorecard - -| Factor | Option A | Option B | Option C | -|--------|----------|----------|----------| -| Initial Time | Low | Medium | Medium-Low | -| Ongoing Effort | High | Low | Medium | -| Feature Completeness | Low | High | High | -| Framework Learning | None | Medium | Low | -| Standards Compliance | Manual | Auto | Auto | -| Deployment Complexity | Simple | Simple | Complex | -| Team Preference | ??? | ??? | ??? | - ---- - -## Next Actions - -### For Option A (Keep Custom): -1. Plan feature roadmap (refresh tokens first) -2. Allocate team capacity for implementation -3. Document OAuth decisions -4. Set up security monitoring - -### For Option B (Full Migration): -1. Assign someone to learn Roda/Rodauth -2. Run rodauth-oauth examples -3. Plan database migration -4. Schedule migration window -5. Prepare rollback plan - -### For Option C (Hybrid): -1. Evaluate microservices capability -2. Run Rodauth-OAuth example -3. Plan service boundaries -4. Set up service communication -5. Plan infrastructure for two services - ---- - -## Still Can't Decide? - -Ask these questions: -1. **Will you add features beyond Auth Code + PKCE in next 12 months?** - - YES → Option B or C - - NO → Option A - -2. **Do you have maintenance bandwidth?** - - YES → Option A - - NO → Option B or C - -3. **Can you run multiple services?** - - YES → Option C (best of both) - - NO → Option B (if framework is OK) or Option A (stay Rails) - ---- - -## Document Files - -You now have three documents: -1. **rodauth-oauth-analysis.md** - Deep technical analysis (12 sections) -2. **rodauth-oauth-quick-reference.md** - Quick lookup guide -3. **RODAUTH_DECISION_GUIDE.md** - This decision framework - -Read in this order: -1. This guide (make a decision) -2. Quick reference (understand architecture) -3. Analysis (deep dive on your choice) - ---- - -**Made Your Decision?** Create an issue/commit to document your choice and next steps! diff --git a/docs/rodauth-oauth-analysis.md b/docs/rodauth-oauth-analysis.md deleted file mode 100644 index cc6f336..0000000 --- a/docs/rodauth-oauth-analysis.md +++ /dev/null @@ -1,913 +0,0 @@ -# Rodauth-OAuth Analysis: Comprehensive Comparison with Clinch's Custom Implementation - -## Executive Summary - -**Rodauth-OAuth** is a production-ready Ruby gem that implements the OAuth 2.0 framework and OpenID Connect on top of the `rodauth` authentication library. It's architected as a modular feature-based system that integrates with Roda (a routing library) and provides extensive OAuth/OIDC capabilities. - -Your current Clinch implementation is a **custom, minimalist Rails-based OIDC provider** focusing on the authorization code grant with PKCE support. Switching to rodauth-oauth would provide significantly more features and standards compliance but requires architectural changes. - ---- - -## 1. What Rodauth-OAuth Is - -### Core Identity -- **Type**: Ruby gem providing OAuth 2.0 & OpenID Connect implementation -- **Framework**: Built on top of `rodauth` (a dedicated authentication library) -- **Web Framework**: Designed for Roda framework (lightweight, routing-focused) -- **Rails Support**: Available via `rodauth-rails` wrapper -- **Maturity**: Production-ready, OpenID-Certified for multiple profiles -- **Author**: Tiago Cardoso (tiago.cardoso@gmail.com) -- **License**: Apache 2.0 - -### Architecture Philosophy -- **Feature-based**: Modular "features" that can be enabled/disabled -- **Database-agnostic**: Uses Sequel ORM, works with any SQL database -- **Highly configurable**: Override methods to customize behavior -- **Standards-focused**: Implements RFCs and OpenID specs strictly - ---- - -## 2. File Structure and Organization - -### Directory Layout in `/tmp/rodauth-oauth` - -``` -rodauth-oauth/ -├── lib/ -│ └── rodauth/ -│ ├── oauth.rb # Main module entry point -│ ├── oauth/ -│ │ ├── version.rb -│ │ ├── database_extensions.rb -│ │ ├── http_extensions.rb -│ │ ├── jwe_extensions.rb -│ │ └── ttl_store.rb -│ └── features/ # 34 feature files! -│ ├── oauth_base.rb # Foundation -│ ├── oauth_authorization_code_grant.rb -│ ├── oauth_pkce.rb -│ ├── oauth_jwt*.rb # JWT support (5 files) -│ ├── oidc.rb # OpenID Core -│ ├── oidc_*logout.rb # Logout flows (3 files) -│ ├── oauth_client_credentials_grant.rb -│ ├── oauth_device_code_grant.rb -│ ├── oauth_token_revocation.rb -│ ├── oauth_token_introspection.rb -│ ├── oauth_dynamic_client_registration.rb -│ ├── oauth_dpop.rb # DPoP support -│ ├── oauth_tls_client_auth.rb -│ ├── oauth_pushed_authorization_request.rb -│ ├── oauth_assertion_base.rb -│ └── ... (more features) -├── test/ -│ ├── migrate/ # Database migrations -│ │ ├── 001_accounts.rb -│ │ ├── 003_oauth_applications.rb -│ │ ├── 004_oauth_grants.rb -│ │ ├── 005_pushed_requests.rb -│ │ ├── 006_saml_settings.rb -│ │ └── 007_dpop_proofs.rb -│ └── [multiple test directories with hundreds of tests] -├── examples/ # Full working examples -│ ├── authorization_server/ -│ ├── oidc/ -│ ├── jwt/ -│ ├── device_grant/ -│ ├── saml_assertion/ -│ └── mtls/ -├── templates/ # HTML/ERB templates -├── locales/ # i18n translations -├── doc/ -└── [Gemfile, README, MIGRATION-GUIDE, etc.] -``` - -### Feature Count: 34 Features! - -The gem is completely modular. Each feature can be independently enabled: - -**Core OAuth Features:** -- `oauth_base` - Foundation -- `oauth_authorization_code_grant` - Authorization Code Flow -- `oauth_implicit_grant` - Implicit Flow -- `oauth_client_credentials_grant` - Client Credentials Flow -- `oauth_device_code_grant` - Device Code Flow - -**Token Management:** -- `oauth_token_revocation` - RFC 7009 -- `oauth_token_introspection` - RFC 7662 -- `oauth_refresh_token` - Refresh tokens - -**Security & Advanced:** -- `oauth_pkce` - RFC 7636 (what Clinch is using!) -- `oauth_jwt` - JWT Access Tokens -- `oauth_jwt_bearer_grant` - RFC 7523 -- `oauth_saml_bearer_grant` - RFC 7522 -- `oauth_tls_client_auth` - Mutual TLS -- `oauth_dpop` - Demonstrating Proof-of-Possession -- `oauth_jwt_secured_authorization_request` - Request Objects -- `oauth_resource_indicators` - RFC 8707 -- `oauth_pushed_authorization_request` - RFC 9126 - -**OpenID Connect:** -- `oidc` - Core OpenID Connect -- `oidc_session_management` - Session Management -- `oidc_rp_initiated_logout` - RP-Initiated Logout -- `oidc_frontchannel_logout` - Front-Channel Logout -- `oidc_backchannel_logout` - Back-Channel Logout -- `oidc_dynamic_client_registration` - Dynamic Registration -- `oidc_self_issued` - Self-Issued Provider - -**Management & Discovery:** -- `oauth_application_management` - Client app dashboard -- `oauth_grant_management` - Grant management dashboard -- `oauth_dynamic_client_registration` - RFC 7591/7592 -- `oauth_jwt_jwks` - JWKS endpoint - ---- - -## 3. OIDC/OAuth Features Provided - -### Grant Types Supported (15 types!) - -| Grant Type | Status | RFC/Spec | -|-----------|--------|----------| -| Authorization Code | Yes | RFC 6749 | -| Implicit | Optional | RFC 6749 | -| Client Credentials | Optional | RFC 6749 | -| Device Code | Optional | RFC 8628 | -| Refresh Token | Yes | RFC 6749 | -| JWT Bearer | Optional | RFC 7523 | -| SAML Bearer | Optional | RFC 7522 | - -### Response Types & Modes - -**Response Types:** -- `code` (Authorization Code) - Default -- `id_token` (OIDC Implicit) - Optional -- `token` (Implicit) - Optional -- `id_token token` (Hybrid) - Optional -- `code id_token` (Hybrid) - Optional -- `code token` (Hybrid) - Optional -- `code id_token token` (Hybrid) - Optional - -**Response Modes:** -- `query` (URL parameters) -- `fragment` (URL fragment) -- `form_post` (HTML form) -- `jwt` (JWT-based response) - -### OpenID Connect Features - -✓ **Certified for:** -- Basic OP (OpenID Provider) -- Implicit OP -- Hybrid OP -- Config OP (Discovery) -- Dynamic OP (Dynamic Client Registration) -- Form Post OP -- 3rd Party-Init OP -- Session Management OP -- RP-Initiated Logout OP -- Front-Channel Logout OP -- Back-Channel Logout OP - -✓ **Standard Claims Support:** -- `openid`, `email`, `profile`, `address`, `phone` scopes -- Automatic claim mapping per OpenID spec -- Custom claims via extension - -✓ **Token Features:** -- JWT ID Tokens -- JWT Access Tokens -- Encrypted JWTs (JWE support) -- HMAC-SHA256 signing -- RSA/EC signing -- Custom token formats - -### Security Features - -| Feature | Details | -|---------|---------| -| PKCE | RFC 7636 - Proof Key for Public Clients | -| Token Hashing | Bcrypt-based token storage (plain text optional) | -| DPoP | RFC 9449 - Demonstrating Proof-of-Possession | -| TLS Client Auth | RFC 8705 - Mutual TLS authentication | -| Request Objects | JWT-signed/encrypted authorization requests | -| Pushed Auth Requests | RFC 9126 - Pushed Authorization Requests | -| Token Introspection | RFC 7662 - Token validation without DB lookup | -| Token Revocation | RFC 7009 - Revoke tokens on demand | - -### Scopes & Authorization - -- Configurable scope list per application -- Offline access support (refresh tokens) -- Scope-based access control -- Custom scope handlers -- Consent UI for user authorization - ---- - -## 4. Architecture: How It Works - -### As a Plugin System - -Rodauth-OAuth integrates with Roda as a **plugin**: - -```ruby -# This is how you configure it -class AuthServer < Roda - plugin :rodauth do - db database_connection - - # Enable features - enable :login, :logout, :create_account, :oidc, :oidc_session_management, - :oauth_pkce, :oauth_authorization_code_grant - - # Configure - oauth_application_scopes %w[openid email profile] - oauth_require_pkce true - hmac_secret "SECRET" - - # Customize with blocks - oauth_jwt_keys("RS256" => [private_key]) - oauth_jwt_public_keys("RS256" => [public_key]) - end -end -``` - -### Request Flow Architecture - -``` -1. Authorization Request - ↓ - rodauth validates params - ↓ - (if not auth'd) user logs in via rodauth - ↓ - (if first use) consent page rendered - ↓ - create oauth_grant (code, nonce, PKCE challenge, etc.) - ↓ - redirect with auth code - -2. Token Exchange - ↓ - rodauth validates client (Basic/POST auth) - ↓ - validates code, redirect_uri, PKCE verifier - ↓ - creates access token (plain or JWT) - ↓ - creates refresh token - ↓ - returns JSON with tokens - -3. UserInfo - ↓ - validate access token - ↓ - lookup grant/account - ↓ - return claims as JSON -``` - -### Feature Composition - -Features depend on each other. For example: -- `oidc` depends on: `active_sessions`, `oauth_jwt`, `oauth_jwt_jwks`, `oauth_authorization_code_grant`, `oauth_implicit_grant` -- `oauth_pkce` depends on: `oauth_authorization_code_grant` -- `oidc_rp_initiated_logout` depends on: `oidc` - -This is a **strong dependency injection pattern**. - ---- - -## 5. Database Schema Requirements - -### Rodauth-OAuth Tables - -#### `accounts` table (from rodauth) -```sql -CREATE TABLE accounts ( - id INTEGER PRIMARY KEY, - status_id INTEGER DEFAULT 1, -- unverified/verified/closed - email VARCHAR UNIQUE NOT NULL, - -- password-related columns (added by rodauth features) - password_hash VARCHAR, - -- other rodauth-managed columns -); -``` - -#### `oauth_applications` table (75+ columns!) -```sql -CREATE TABLE oauth_applications ( - id INTEGER PRIMARY KEY, - account_id INTEGER FOREIGN KEY, - - -- Basic info - name VARCHAR NOT NULL, - description VARCHAR, - homepage_url VARCHAR, - logo_uri VARCHAR, - tos_uri VARCHAR, - policy_uri VARCHAR, - - -- OAuth credentials - client_id VARCHAR UNIQUE NOT NULL, - client_secret VARCHAR UNIQUE NOT NULL, - registration_access_token VARCHAR, - - -- OAuth config - redirect_uri VARCHAR NOT NULL, - scopes VARCHAR NOT NULL, - token_endpoint_auth_method VARCHAR, - grant_types VARCHAR, - response_types VARCHAR, - response_modes VARCHAR, - - -- JWT/JWKS - jwks_uri VARCHAR, - jwks TEXT, - jwt_public_key TEXT, - - -- OIDC-specific - sector_identifier_uri VARCHAR, - application_type VARCHAR, - initiate_login_uri VARCHAR, - subject_type VARCHAR, - - -- Token encryption algorithms - id_token_signed_response_alg VARCHAR, - id_token_encrypted_response_alg VARCHAR, - id_token_encrypted_response_enc VARCHAR, - userinfo_signed_response_alg VARCHAR, - userinfo_encrypted_response_alg VARCHAR, - userinfo_encrypted_response_enc VARCHAR, - - -- Request object handling - request_object_signing_alg VARCHAR, - request_object_encryption_alg VARCHAR, - request_object_encryption_enc VARCHAR, - request_uris VARCHAR, - require_signed_request_object BOOLEAN, - - -- PAR (Pushed Auth Requests) - require_pushed_authorization_requests BOOLEAN DEFAULT FALSE, - - -- DPoP - dpop_bound_access_tokens BOOLEAN DEFAULT FALSE, - - -- TLS Client Auth - tls_client_auth_subject_dn VARCHAR, - tls_client_auth_san_dns VARCHAR, - tls_client_auth_san_uri VARCHAR, - tls_client_auth_san_ip VARCHAR, - tls_client_auth_san_email VARCHAR, - tls_client_certificate_bound_access_tokens BOOLEAN DEFAULT FALSE, - - -- Logout URIs - post_logout_redirect_uris VARCHAR, - frontchannel_logout_uri VARCHAR, - frontchannel_logout_session_required BOOLEAN DEFAULT FALSE, - backchannel_logout_uri VARCHAR, - backchannel_logout_session_required BOOLEAN DEFAULT FALSE, - - -- Response encryption - authorization_signed_response_alg VARCHAR, - authorization_encrypted_response_alg VARCHAR, - authorization_encrypted_response_enc VARCHAR, - - contact_info VARCHAR, - software_id VARCHAR, - software_version VARCHAR -); -``` - -#### `oauth_grants` table (everything in one table!) -```sql -CREATE TABLE oauth_grants ( - id INTEGER PRIMARY KEY, - account_id INTEGER FOREIGN KEY, -- nullable for client credentials - oauth_application_id INTEGER FOREIGN KEY, - sub_account_id INTEGER, -- for context-based ownership - - type VARCHAR, -- 'authorization_code', 'refresh_token', etc. - - -- Authorization code flow - code VARCHAR UNIQUE (per app), - redirect_uri VARCHAR, - - -- Tokens (stored hashed or plain) - token VARCHAR UNIQUE, - token_hash VARCHAR UNIQUE, - refresh_token VARCHAR UNIQUE, - refresh_token_hash VARCHAR UNIQUE, - - -- Expiry - expires_in TIMESTAMP NOT NULL, - revoked_at TIMESTAMP, - - -- Scopes - scopes VARCHAR NOT NULL, - access_type VARCHAR DEFAULT 'offline', -- 'offline' or 'online' - - -- PKCE - code_challenge VARCHAR, - code_challenge_method VARCHAR, -- 'plain' or 'S256' - - -- Device Code Grant - user_code VARCHAR UNIQUE, - last_polled_at TIMESTAMP, - - -- TLS Client Auth - certificate_thumbprint VARCHAR, - - -- Resource Indicators - resource VARCHAR, - - -- OpenID Connect - nonce VARCHAR, - acr VARCHAR, -- Authentication Context Class - claims_locales VARCHAR, - claims VARCHAR, -- custom OIDC claims - - -- DPoP - dpop_jkt VARCHAR -- DPoP key thumbprint -); -``` - -#### Optional Tables for Advanced Features - -```sql --- For Pushed Authorization Requests -CREATE TABLE oauth_pushed_requests ( - request_uri VARCHAR UNIQUE PRIMARY KEY, - oauth_application_id INTEGER FOREIGN KEY, - params TEXT, -- JSON params - created_at TIMESTAMP -); - --- For SAML Assertion Grant -CREATE TABLE oauth_saml_settings ( - id INTEGER PRIMARY KEY, - oauth_application_id INTEGER FOREIGN KEY, - idp_url VARCHAR, - certificate TEXT, - -- ... -); - --- For DPoP -CREATE TABLE oauth_dpop_proofs ( - id INTEGER PRIMARY KEY, - oauth_grant_id INTEGER FOREIGN KEY, - jti VARCHAR UNIQUE, - created_at TIMESTAMP -); -``` - -### Key Differences from Your Implementation - -| Aspect | Your Implementation | Rodauth-OAuth | -|--------|-------------------|----------------| -| Authorization Codes | Separate table | In oauth_grants | -| Access Tokens | Separate table | In oauth_grants | -| Refresh Tokens | Not implemented | In oauth_grants | -| Token Hashing | Not done | Bcrypt (default) | -| Applications | Basic (name, client_id, secret) | 75+ columns for full spec | -| PKCE | Simple columns | Built-in feature | -| Account Data | In users table | In accounts table | -| Session Management | Session model | Rodauth's account_active_session_keys | -| User Consent | OidcUserConsent table | In memory or via hooks | - ---- - -## 6. Integration Points with Rails - -### Via Rodauth-Rails Wrapper - -Rodauth-OAuth can be used in Rails through the `rodauth-rails` gem: - -```bash -# Install generator -gem 'rodauth-rails' -bundle install -rails generate rodauth:install -rails generate rodauth:oauth:install # Generates OIDC tables/migrations -rails generate rodauth:oauth:views # Generates templates -``` - -### Generated Components - -1. **Migration**: `db/migrate/*_create_rodauth_oauth.rb` - - Creates all OAuth tables - - Customizable column names via config - -2. **Models**: `app/models/` - - `RodauthApp` (configuration) - - `OauthApplication` (client app) - - `OauthGrant` (grants/tokens) - - Customizable! - -3. **Views**: `app/views/rodauth/` - - Authorization consent form - - Application management dashboard - - Grant management dashboard - -4. **Lib**: `lib/rodauth_app.rb` - - Main rodauth configuration - -### Rails Controller Integration - -```ruby -class BooksController < ApplicationController - before_action :require_oauth_authorization, only: %i[create update] - before_action :require_oauth_authorization_scopes, only: %i[create update] - - private - - def require_oauth_authorization(scope = "books.read") - rodauth.require_oauth_authorization(scope) - end -end -``` - -Or for route protection: - -```ruby -# config/routes.rb -namespace :api do - resources :books, only: [:index] # protected by rodauth -end -``` - ---- - -## 7. Architectural Comparison - -### Your Custom Implementation - -**Pros:** -- Simple, easy to understand -- Minimal dependencies (just JWT, OpenSSL) -- Lightweight database (small tables) -- Direct Rails integration -- Minimal features = less surface area - -**Cons:** -- Only supports Authorization Code + PKCE -- No refresh tokens -- No token revocation/introspection -- No client credentials grant -- No JWT access tokens -- Manual consent management -- Not standards-compliant (missing many OIDC features) -- Will need continuous custom development - -**Architecture:** -``` -Rails Controller - ↓ -OidcController (450 lines) - ↓ -OidcAuthorizationCode Model -OidcAccessToken Model -OidcUserConsent Model - ↓ -Database -``` - -### Rodauth-OAuth Implementation - -**Pros:** -- 34 built-in features -- OpenID-Certified -- Production-tested -- Highly configurable -- Comprehensive token management -- Standards-compliant (RFCs & OpenID specs) -- Strong test coverage (hundreds of tests) -- Active maintenance - -**Cons:** -- More complex (needs Roda/Rodauth knowledge) -- Larger codebase to learn -- Rails integration via wrapper (extra layer) -- Different paradigm (Roda vs Rails) -- More database columns to manage - -**Architecture:** -``` -Roda App - ↓ -Rodauth Plugin (configurable) - ├── oauth_base (foundation) - ├── oauth_authorization_code_grant - ├── oauth_pkce - ├── oauth_jwt - ├── oidc (all OpenID features) - ├── [other optional features] - ↓ -Sequel ORM - ↓ -Database (flexible schema) -``` - ---- - -## 8. Feature Comparison Matrix - -| Feature | Your Impl | Rodauth-OAuth | Notes | -|---------|-----------|---------------|-------| -| **Authorization Code** | ✓ | ✓ | Both support | -| **PKCE** | ✓ | ✓ | Both support | -| **Refresh Tokens** | ✗ | ✓ | You'd need to add | -| **Implicit Flow** | ✗ | ✓ Optional | Legacy, not recommended | -| **Client Credentials** | ✗ | ✓ Optional | Machine-to-machine | -| **Device Code** | ✗ | ✓ Optional | IoT devices | -| **JWT Bearer Grant** | ✗ | ✓ Optional | Service accounts | -| **SAML Bearer Grant** | ✗ | ✓ Optional | Enterprise SAML | -| **JWT Access Tokens** | ✗ | ✓ Optional | Stateless tokens | -| **Token Revocation** | ✗ | ✓ | RFC 7009 | -| **Token Introspection** | ✗ | ✓ | RFC 7662 | -| **Pushed Auth Requests** | ✗ | ✓ Optional | RFC 9126 | -| **DPoP** | ✗ | ✓ Optional | RFC 9449 | -| **TLS Client Auth** | ✗ | ✓ Optional | RFC 8705 | -| **OpenID Connect** | ✓ Basic | ✓ Full | Yours is minimal | -| **ID Tokens** | ✓ | ✓ | Both support | -| **UserInfo Endpoint** | ✓ | ✓ | Both support | -| **Discovery** | ✓ | ✓ | Both support | -| **Session Management** | ✗ | ✓ Optional | Check session iframe | -| **RP-Init Logout** | ✓ | ✓ | Both support | -| **Front-Channel Logout** | ✗ | ✓ | Iframe-based | -| **Back-Channel Logout** | ✗ | ✓ | Server-to-server | -| **Dynamic Client Reg** | ✗ | ✓ Optional | RFC 7591/7592 | -| **Token Hashing** | ✗ | ✓ | Security best practice | -| **Scopes** | ✓ | ✓ | Both support | -| **Custom Claims** | ✓ Manual | ✓ Built-in | Yours via JWT service | -| **Consent UI** | ✓ | ✓ | Both support | -| **Client App Dashboard** | ✗ | ✓ Optional | Built-in | -| **Grant Management Dashboard** | ✗ | ✓ Optional | Built-in | - ---- - -## 9. Integration Complexity Analysis - -### Switching to Rodauth-OAuth - -#### Medium Complexity (Not Trivial, but Doable) - -**What you'd need to do:** - -1. **Learn Roda + Rodauth** - - Move from pure Rails to Roda-based architecture - - Understand rodauth feature system - - Time: 1-2 weeks for Rails developers - -2. **Migrate Database Schema** - - Consolidate tables: authorization codes + access tokens → oauth_grants - - Rename columns to match rodauth conventions - - Add many new columns for feature support - - Migration script needed: ~100-300 lines - - Time: 1 week development + testing - -3. **Replace Your OIDC Code** - - Replace your 450-line OidcController - - Remove your 3 model files - - Keep your OidcJwtService (mostly compatible) - - Add rodauth configuration - - Time: 1-2 weeks - -4. **Update Application/Client Model** - - Expand `Application` model properties - - Support all OAuth scopes, grant types, response types - - Time: 3-5 days - -5. **Create Migrations from Template** - - Use rodauth-oauth migration templates - - Customize for your database - - Time: 2-3 days - -6. **Testing** - - Write integration tests - - Verify all OAuth flows still work - - Check token validation logic - - Time: 2-3 weeks - -**Total Effort:** 4-8 weeks for experienced team - -### Keeping Your Implementation (Custom Path) - -#### What You'd Need to Add - -To reach feature parity with rodauth-oauth (for common use cases): - -1. **Refresh Token Support** (1-2 weeks) - - Database schema - - Token refresh endpoint - - Token validation logic - -2. **Token Revocation** (1 week) - - Revocation endpoint - - Token blacklist/invalidation - -3. **Token Introspection** (1 week) - - Introspection endpoint - - Token validation without DB lookup - -4. **Client Credentials Grant** (2 weeks) - - Endpoint logic - - Client authentication - - Token generation for apps - -5. **Improved Security** (ongoing) - - Token hashing (bcrypt) - - Rate limiting - - Additional validation - -6. **Advanced OIDC Features** - - Session Management - - Logout endpoints (front/back-channel) - - Dynamic client registration - - Device code flow - -**Total Effort:** 2-3 months ongoing - ---- - -## 10. Key Findings & Recommendations - -### What Rodauth-OAuth Does Better - -1. **Standards Compliance** - - Certified for 11 OpenID Connect profiles - - Implements 20+ RFCs and specs - - Regular spec updates - -2. **Security** - - Token hashing by default - - DPoP support (token binding) - - TLS client auth - - Proper scope enforcement - -3. **Features** - - 34 optional features (you get what you need) - - No bloat - only enable what you use - - Mature refresh token handling - -4. **Production Readiness** - - Thousands of test cases - - Open source (auditable) - - Active maintenance - - Real-world deployments - -5. **Flexibility** - - Works with any SQL database - - Highly configurable column names - - Custom behavior via overrides - - Multiple app types support - -### What Your Implementation Does Better - -1. **Simplicity** - - Fewer dependencies - - Smaller codebase - - Easier to reason about - -2. **Rails Integration** - - Direct Rails ActiveRecord - - No Roda learning curve - - Familiar patterns - -3. **Control** - - Full control of every line - - No surprises - - Easy to debug - -### Recommendation - -**Use Rodauth-OAuth IF:** -- You need a production OIDC/OAuth provider -- You want standards compliance -- You plan to support multiple grant types -- You need token revocation/introspection -- You want a maintained codebase - -**Keep Your Custom Implementation IF:** -- Authorization Code + PKCE only is sufficient -- You're avoiding Roda/Rodauth learning curve -- Your org standardizes on Rails patterns -- You have time to add features incrementally -- You need maximum control and simplicity - -**Hybrid Approach:** -- Use rodauth-oauth for OIDC/OAuth server components -- Keep your Rails app for other features -- They can coexist (separate services) - ---- - -## 11. Migration Path (If You Decide to Switch) - -### Phase 1: Preparation (Week 1-2) -- Set up separate Roda app with rodauth-oauth -- Run alongside your existing service -- Parallel user testing - -### Phase 2: Data Migration (Week 2-3) -- Create migration script for oauth_grants table -- Backfill existing auth codes and tokens -- Verify data integrity - -### Phase 3: Gradual Cutover (Week 4-6) -- Direct some OAuth clients to new server -- Monitor for issues -- Swap over when confident - -### Phase 4: Cleanup (Week 6+) -- Remove custom OIDC code -- Decommission old tables -- Document new architecture - ---- - -## 12. Code Examples - -### Rodauth-OAuth: Minimal Setup - -```ruby -# Gemfile -gem 'roda' -gem 'rodauth-oauth' -gem 'sequel' - -# lib/auth_server.rb -class AuthServer < Roda - plugin :render, views: 'views' - plugin :sessions, secret: 'SECRET' - - plugin :rodauth do - db DB - enable :login, :logout, :create_account, :oidc, :oauth_pkce, - :oauth_authorization_code_grant, :oauth_token_introspection - - oauth_application_scopes %w[openid email profile] - oauth_require_pkce true - hmac_secret 'HMAC_SECRET' - - oauth_jwt_keys('RS256' => [private_key]) - end - - route do |r| - r.rodauth # All OAuth routes automatically mounted - - # Your custom routes - r.get 'api' do - rodauth.require_oauth_authorization('api.read') - # return data - end - end -end -``` - -### Your Current Approach: Manual - -```ruby -# app/controllers/oidc_controller.rb -def authorize - validate_params - find_application - check_authentication - handle_consent - generate_code - redirect_with_code -end - -def token - extract_client_credentials - find_application - validate_code - check_pkce - generate_tokens - return_json -end -``` - ---- - -## Summary Table - -| Aspect | Your Implementation | Rodauth-OAuth | -|--------|-------------------|----------------| -| **Framework** | Rails | Roda | -| **Database ORM** | ActiveRecord | Sequel | -| **Grant Types** | 1 (Auth Code) | 7+ options | -| **Token Types** | Opaque | Opaque or JWT | -| **Security Features** | Basic | Advanced (DPoP, MTLS, etc.) | -| **OIDC Compliance** | Partial | Full (Certified) | -| **Lines of Code** | ~1000 | ~10,000+ | -| **Features** | 2-3 | 34 optional | -| **Maintenance Burden** | High | Low (OSS) | -| **Learning Curve** | Low | Medium (Roda) | -| **Production Ready** | Yes | Yes | -| **Community** | Just you | Active | - diff --git a/docs/rodauth-oauth-quick-reference.md b/docs/rodauth-oauth-quick-reference.md deleted file mode 100644 index 774b928..0000000 --- a/docs/rodauth-oauth-quick-reference.md +++ /dev/null @@ -1,418 +0,0 @@ -# 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.