Skip to content

cocoonventures/pangea-auth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

pangea-auth

Authentication engine for Pangea Alliance Rails applications. UUID-based auth with CAS server/client, SuperTokens SSO, invitation-only registration, and Rails generators.

Installation

Add to your Gemfile:

# From GitHub Packages (when published):
# gem "pangea-auth", source: "https://rubygems.pkg.github.com/cocoonventures"

# From local path (monorepo):
gem "pangea-auth", path: "gems/pangea-auth"

Then:

bundle install

Quick Start

1. Generate core auth

rails generate pangea:auth:install
rails db:migrate

This creates:

  • Migrations: users, sessions, invitations (all UUID PKs)
  • Models: User (with Authenticatable concern), Session, Invitation (with Invitable concern), Current
  • Controllers: SessionsController, PasswordsController, InvitationsController
  • Views: Sign-in, password reset, invitation acceptance forms
  • Initializer: config/initializers/pangea_auth.rb with configuration DSL
  • Routes: session, password, invitation endpoints

2. Add CAS server (optional)

If this app should act as a CAS identity provider:

rails generate pangea:auth:cas
rails db:migrate

This adds:

  • CasServiceTicket model: short-lived SSO tickets (5-min expiry, single-use)
  • CasRegisteredService model: service whitelist with glob URL patterns
  • CasController: CAS 1.0/2.0/3.0 endpoints (login, validate, serviceValidate, logout)
  • Shared sign-in form: DRY partial used by both local login and CAS login
  • Routes: /cas/login, /cas/validate, /cas/serviceValidate, /cas/p3/serviceValidate, /cas/logout

3. Add SuperTokens (optional)

For OAuth (Google, LinkedIn, Apple), passwordless (magic link), and MFA:

rails generate pangea:auth:supertokens

This adds:

  • SuperTokensClient: REST API wrapper for the SuperTokens core service
  • Inflection: ensures SuperTokensClient class name works with Zeitwerk

Then add credentials:

bin/rails credentials:edit
supertokens:
  connection_uri: https://your-supertokens-instance.com
  api_key: your-api-key

Configuration

# config/initializers/pangea_auth.rb
Pangea::Auth.configure do |config|
  # Core
  config.uuid_primary_keys    = true       # UUID PKs on all auth tables
  config.session_expiry       = 30.days    # Session lifetime
  config.invitation_expiry    = 14.days    # Invitation token lifetime
  config.invitation_required  = true       # No public signup

  # CAS (uncomment after running cas generator)
  # config.cas_enabled        = true
  # config.cas_mode           = :server    # :server or :client

  # SuperTokens (uncomment after running supertokens generator)
  # config.supertokens_enabled        = true
  # config.supertokens_connection_uri = Rails.application.credentials.dig(:supertokens, :connection_uri)
  # config.supertokens_api_key        = Rails.application.credentials.dig(:supertokens, :api_key)
  # config.supertokens_providers      = [:google, :linkedin, :apple]

  # Callbacks
  # config.after_sign_in = ->(user, session) { }
  # config.after_invitation_accepted = ->(user, invitation) { }
end

Generated Models

User

The generated User model includes the Pangea::Auth::Authenticatable concern:

class User < ApplicationRecord
  include Pangea::Auth::Authenticatable
  # Provides: has_secure_password, role enum (observer→super_admin),
  # email validation/normalization, default role callback
end

Role tiers: observer (0), analyst (1), member (2), admin (3), super_admin (4)

Invitation

The generated Invitation model includes the Pangea::Auth::Invitable concern:

class Invitation < ApplicationRecord
  include Pangea::Auth::Invitable
  # Provides: token generation, expiry, status enum, accept! method
end

CAS Server Features

When running as a CAS server, the app provides:

Endpoint Protocol Description
GET /cas/login 1.0 Login form or SSO redirect
POST /cas/login 1.0 Authenticate + issue ticket
GET /cas/validate 1.0 Text validation (yes/no)
GET /cas/serviceValidate 2.0 XML validation + attributes
GET /cas/p3/serviceValidate 3.0 XML validation + attributes
GET /cas/logout 1.0 Destroy session + redirect

Protocol parameters:

  • renew=true — force re-authentication (bypass SSO)
  • gateway=true — silent SSO check (redirect without prompting)
  • format=JSON — JSON response on serviceValidate

Service registry:

  • When CasRegisteredService records exist, only registered services can authenticate
  • When empty, all services are allowed (open mode for development)
  • Uses glob URL patterns: https://myapp.com/**

Register a service:

CasRegisteredService.create!(
  name: "My Client App",
  service_url_pattern: "https://myapp.example.com/**",
  enabled: true
)

CAS Client Setup

For apps that delegate auth to an external CAS server (e.g., ally.vc):

# Gemfile
gem "rack-cas"

# config/initializers/rack_cas.rb
Rails.application.config.rack_cas.server_url = "https://ally.vc/cas"

The CAS server returns user attributes in the serviceValidate response. Use these to find-or-create local user records:

# In your CAS callback controller:
user = User.find_or_create_by!(email: cas_user.email) do |u|
  u.first_name = cas_user.extra_attributes["firstName"]
  u.last_name  = cas_user.extra_attributes["lastName"]
  u.role       = cas_user.extra_attributes["role"]
  u.verified   = true
end

Testing

The gem uses Minitest. When installed in an app:

# Run auth-related tests
bin/rails test test/models/user_test.rb
bin/rails test test/controllers/sessions_controller_test.rb

# Run generator tests
bin/rails test test/generators/

Requirements

  • Ruby >= 3.2
  • Rails >= 8.0
  • PostgreSQL (for UUID primary keys)
  • bcrypt (for has_secure_password)

License

MIT License. Copyright Pangea Alliance.

About

Reusable authentication engine for Pangea Alliance Rails applications

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors