Better Auth Ruby
The most comprehensive authentication framework for Ruby
Learn more »
Discord
·
Website
·
Issues
About the Project
Better Auth Ruby is a comprehensive authentication and authorization library for Ruby. It provides a complete set of features out of the box and includes a plugin ecosystem that simplifies adding advanced functionalities with minimal code.
Features
- Framework Agnostic Core: Works with any Rack-based application
- Rails Integration: First-class Rails support with middleware and helpers
- Session Management: Secure session handling
- Multiple Authentication Methods: Email/password, OAuth, JWT, and more
- Two-Factor Authentication: TOTP and WebAuthn support
- Plugin System: Extensible architecture for custom features
Installation
Add this line to your application's Gemfile:
gem 'better_auth'
And then execute:
bundle install
Or install it yourself as:
gem install better_auth
Usage
Basic Setup
require 'better_auth'
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
database: :memory
)
Password Hashing
Better Auth Ruby uses upstream-compatible scrypt password hashes by default through Ruby's OpenSSL::KDF.scrypt, so no extra password-hashing gem is required for the default setup.
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
password_hasher: :scrypt # default
)
Applications that prefer Ruby's familiar BCrypt ecosystem can opt in by adding gem "bcrypt" and configuring:
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
password_hasher: :bcrypt
)
Custom Better Auth-style password callbacks are still supported through email_and_password[:password][:hash] and [:verify].
Database Adapters
The core gem ships framework-agnostic adapters for memory, PostgreSQL, MySQL, SQLite, MongoDB, and MSSQL. Driver gems are loaded only when their adapter is instantiated.
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
database: BetterAuth::Adapters::SQLite.new(path: "storage/auth.sqlite3")
)
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
database: BetterAuth::Adapters::MongoDB.new(
database: mongo_client.database,
client: mongo_client,
transaction: false
)
)
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
database: BetterAuth::Adapters::MSSQL.new(url: ENV.fetch("DATABASE_URL"))
)
Social Providers
require "better_auth"
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
social_providers: {
google: BetterAuth::SocialProviders.google(
client_id: ENV.fetch("GOOGLE_CLIENT_ID"),
client_secret: ENV.fetch("GOOGLE_CLIENT_SECRET")
),
github: BetterAuth::SocialProviders.github(
client_id: ENV.fetch("GITHUB_CLIENT_ID"),
client_secret: ENV.fetch("GITHUB_CLIENT_SECRET")
)
}
)
JavaScript Client
Ruby Better Auth exposes the same HTTP route surface. Frontend apps should use the upstream Better Auth JavaScript client and point it at the Ruby server:
import { createAuthClient } from "better-auth/client";
export const authClient = createAuthClient({
baseURL: "http://localhost:3000",
basePath: "/api/auth",
});
Rails Integration
Add to your Gemfile:
gem 'better_auth', require: 'better_auth/rails'
Then in your ApplicationController:
class ApplicationController < ActionController::Base
include BetterAuth::Rails::ControllerHelpers
end
Now you have access to current_user and authentication methods:
class PostsController < ApplicationController
before_action :authenticate_user!
def index
@posts = current_user.posts
end
end
Development
Full documentation is being adapted in the root docs/ app. Start with the Ruby-first installation, basic usage, Rack, Rails, PostgreSQL, and MySQL pages there; pages with a Ruby port warning still contain upstream TypeScript examples for reference.
Quick Start
# 1. Clone the repository
git clone https://github.com/sebasxsala/better-auth.git
cd better-auth/packages/better_auth
# 2. Install dependencies
make install
# or: bundle install
# 3. Run tests to verify everything works
make ci
Common Make Commands
We use a Makefile to simplify commands. All have explanatory comments:
# View all available commands with description
make help
# Development
make console # Interactive console with gem loaded
make lint # Check code style
make lint-fix # Auto-fix style issues
# Testing
make test # Run all tests
make test-core # Only core tests (Minitest)
make test-coverage # Tests with coverage
make ci # Full CI (lint + test)
# Databases for testing
make db-up # Start PostgreSQL, MySQL, MongoDB, MSSQL, Redis
make db-down # Stop containers
Branch Workflow
This project uses a branch model similar to the upstream:
Main Branches:
main: Stable code, ready for productioncanary: Development/integration branch (like "development" but specific name)- "Canary" comes from "canary in a coal mine" - where changes are tested before production
- Feature PRs go to
canary - When
canaryis stable, merge tomainfor release
Typical workflow:
# 1. Create your feature branch from canary
git checkout canary
git pull origin canary
git checkout -b feat/new-feature
# 2. Make your changes and commits
# ... code ...
git add .
git commit -m "feat(core): add support for X"
# 3. Push and create PR towards canary
git push origin feat/new-feature
# Create PR on GitHub towards canary
# 4. Once merged to canary and tested,
# merge canary → main for release
Why canary instead of development?
- Common name in projects with frequent releases
- Suggests it's an "experimental" version that might break
- Allows multiple levels: feature → canary → main
How CI/CD Works
Pull Requests:
- Each PR runs: lint + tests on Ruby 3.2 and 3.3
- Everything must pass before merging
Automatic Release (GitHub Actions):
Release is triggered by package-prefixed tags so each gem can ship independently.
# STEP 1: Update the target package version file
# Example: VERSION = "0.1.1"
# STEP 2: Commit and push to main
git add lib/better_auth/version.rb
git commit -m "chore: bump version to 0.1.1"
git push origin main
# STEP 3: Create the tag for the gem you want to publish
git tag better_auth-v0.1.1
git push origin better_auth-v0.1.1
# STEP 4: GitHub Actions automatically:
# - Runs tests
# - Builds the gem
# - Publishes to RubyGems (if version is new)
# - Creates GitHub Release
Use better_auth-vX.Y.Z for the core gem, better_auth-rails-vX.Y.Z for Rails, better_auth-sinatra-vX.Y.Z for Sinatra, and better_auth-hanami-vX.Y.Z for Hanami.
Required GitHub Configuration:
- In RubyGems, configure Trusted Publishing for each gem that should publish from CI.
- Use this repository and workflow file:
.github/workflows/release.yml. - The workflow exchanges GitHub's OIDC token for short-lived RubyGems credentials when the matching package tag is pushed.
Dry-run options:
# Local packaging dry-run
make release-check
# CI dry-run from GitHub Actions
# Actions -> Release -> Run workflow -> dry_run=true
Manual Release (without GitHub Actions)
Only if you need to do a manual release:
# 1. Update version.rb
# 2. Build the gem
gem build better_auth.gemspec
# 3. Publish (you need to be logged into RubyGems)
gem push better_auth-*.gem
# 4. Create and push the tag
git tag -a better_auth-v0.1.1 -m "Release better_auth v0.1.1"
git push origin better_auth-v0.1.1
Project Structure
lib/
better_auth.rb # Entry point
better_auth/
version.rb # Gem version
core.rb # Core loader
core/ # Core logic (framework-agnostic)
test/ # Core tests (Minitest)
Conventions:
- Core: Framework-agnostic, uses Minitest
- All code goes through StandardRB (Ruby style guide)
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/sebasxsala/better-auth. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
License
The gem is available as open source under the terms of the MIT License.
Security
If you discover a security vulnerability within Better Auth Ruby, please send an e-mail to security@openparcel.dev.
All reports will be promptly addressed, and you'll be credited accordingly.