No release in over 3 years
Adds OAuth 2.0 provider metadata, client registration, authorization, token, introspection, revocation, and userinfo routes for Better Auth Ruby.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 2.5
~> 5.25
~> 13.2

Runtime

 Project Readme

Better Auth Ruby

The Ruby/Rack port of Better Auth
Learn more about upstream Better Auth

Website · Issues

Gem GitHub stars

About

Better Auth Ruby is a Ruby port of Better Auth, the framework-agnostic authentication and authorization library from the TypeScript ecosystem.

The goal is upstream-compatible HTTP behavior with idiomatic Ruby internals: Rack first, Rails friendly, and tested against the upstream Better Auth source and test suite as the source of truth. This repository keeps the upstream project as a submodule under upstream/ and tracks port status in .docs/features/ and .docs/plans/.

This port is active work. Many server-side flows are implemented, but not every upstream edge case, adapter dialect, or TypeScript-only API has full parity yet.

Packages

Gem Description Install
better_auth Framework-agnostic Rack core. Auth routes, sessions, cookies, adapters, and core plugin shims live here. gem "better_auth"
better_auth-redis-storage External Redis secondary storage package for session payloads, active-session indexes, and secondary-storage-backed rate limiting. gem "better_auth-redis-storage"
better_auth-api-key External API key plugin package with creation, verification, quotas, metadata, permissions, storage modes, and API-key sessions. gem "better_auth-api-key"
better_auth-rails Rails adapter with mounting helpers, ActiveRecord adapter, controller helpers, and generators. gem "better_auth-rails"
better_auth-sinatra Sinatra adapter with Rack mounting, request helpers, and SQL migration Rake tasks. gem "better_auth-sinatra"
better_auth-sso External SSO plugin package with OIDC and SAML SSO route support. gem "better_auth-sso"
better_auth-scim External SCIM v2 provisioning plugin package. gem "better_auth-scim"
better_auth-stripe External Stripe billing plugin package with subscription, checkout, portal, and webhook support. gem "better_auth-stripe"
better_auth-oauth-provider External OAuth 2.0 provider plugin package. gem "better_auth-oauth-provider"

Quick Start

Rails

# Gemfile
gem "better_auth-rails"
bundle install
bin/rails generate better_auth:install
# config/routes.rb
Rails.application.routes.draw do
  better_auth
end

Rack

# Gemfile
gem "better_auth"
require "better_auth"

auth = BetterAuth.auth(
  secret: ENV.fetch("BETTER_AUTH_SECRET"),
  base_url: "http://localhost:3000",
  database: BetterAuth::Adapters::Memory.new
)

run auth

Sinatra

# Gemfile
gem "better_auth-sinatra"
require "sinatra/base"
require "better_auth/sinatra"

class App < Sinatra::Base
  register BetterAuth::Sinatra

  better_auth at: "/api/auth" do |config|
    config.secret = ENV.fetch("BETTER_AUTH_SECRET")
    config.base_url = ENV.fetch("BETTER_AUTH_URL")
    config.database = ->(options) {
      BetterAuth::Adapters::Postgres.new(options, url: ENV.fetch("DATABASE_URL"))
    }
  end
end

Compatibility Status

Legend:

  • Supported: implemented in Ruby with local tests.
  • Not supported: not implemented or intentionally outside the Ruby server scope.
  • Partial: implemented for the main Ruby server path, with documented upstream parity gaps.

Plugin support is tracked against Ruby server parity: TypeScript inference, browser helper packages, and native mobile client behavior are treated as out of scope only when the row says so explicitly.

Core

Area Status Notes
Auth factory and Rack handler [x] Supported BetterAuth.auth(...) returns a Rack-callable auth object with direct server API access.
Endpoint/router/API pipeline Partial Rack routing, direct API calls, hooks, redirects, cookies, origin checks, and rate limiting exist; some upstream edge-case matrices remain future work.
Email/password auth Partial Sign-up, sign-in, password reset, password verify, set/change password, and email verification exist; some upstream edge cases are still being hardened.
Social OAuth flow Partial /sign-in/social, /callback/:providerId, linking, unlinking, token refresh, and account info exist; upstream account-cookie and some linking-rule details are still future polish.
Sessions Partial Signed session cookies, session routes, revocation, cookie cache, secondary storage, Redis secondary-storage package, and sensitive-route lookup exist; full upstream session/cache matrix is not complete.
Cookies Partial Prefixing, signing, chunking, deletion, cache cookies, and advanced attributes exist; filtering and some account-cookie parity gaps are documented.
CSRF/trusted origins Partial Origin checks and trusted origins exist; callback-bearing GET route parity is still being tightened.
Rate limiting Partial Memory/custom/secondary-storage style rate limiting exists; full database-backed upstream matrix remains future work.
Hooks and database hooks [x] Supported Before/after endpoint hooks, plugin hooks, and adapter database hooks are implemented.
Plugin system [x] Supported Ruby plugins can add endpoints, schema, hooks, middleware, rate limits, error codes, and option defaults.
Database schema [x] Supported Core schema plus plugin schema merge, logical Better Auth field names, and SQL/Rails migration generation exist.
Memory adapter [x] Supported Default development/test adapter.
PostgreSQL adapter Partial Direct SQL adapter and DDL generation exist; full upstream adapter contract coverage is still expanding.
MySQL adapter Partial Direct SQL adapter and DDL generation exist; full upstream adapter contract coverage is still expanding.
Rails ActiveRecord adapter Partial ActiveRecord persistence, migrations, mounting, helpers, and generators exist; full adapter contract parity is still expanding.
Sinatra adapter Partial Rack mounting, helpers, SQL migration Rake tasks, and docs exist. ActiveRecord-backed Sinatra migrations are not supported yet.
Secondary storage Partial Session and verification-style storage behavior exists; full edge-case parity remains future work.
Experimental joins Partial experimental: { joins: true } is accepted with adapter fallback behavior; the exhaustive join matrix is not complete.
OpenAPI generation Partial OpenAPI 3.1.1 metadata, route/model inventory, security schemes, servers, default responses, selected upstream request bodies, path params, disabled paths, reference HTML, theme, nonce, and disabled reference handling exist. Exact upstream snapshot parity remains open: upstream has 30 base paths and roughly 25 still need rich request/response schemas.

Social Providers

Upstream Better Auth exposes many provider factories. The Ruby port currently ships the most common factories and the generic OAuth plugin can cover custom providers.

Provider Status Notes
Apple Partial Factory and OAuth profile mapping exist.
Discord Partial Factory and OAuth profile mapping exist.
GitHub Partial Factory, token exchange, and email/profile lookup exist.
GitLab Partial Factory and OAuth profile mapping exist.
Google Partial Factory and OpenID profile mapping exist.
Microsoft Entra ID Partial Factory and OpenID profile mapping exist.
Atlassian, Cognito, Dropbox, Facebook, Figma, Hugging Face, Kakao, Kick, Line, Linear, LinkedIn, Naver, Notion, Paybin, PayPal, Polar, Reddit, Roblox, Salesforce, Slack, Spotify, TikTok, Twitch, Twitter/X, Vercel, VK, Zoom [ ] Not supported as built-in factories Use BetterAuth::Plugins.generic_oauth or add a Ruby provider factory.

Plugins

Plugin Status Notes
Access control [x] Supported Runtime roles, statements, permissions, resource/action connectors, and upstream access checks are implemented; TypeScript inference is outside Ruby scope.
Additional fields [x] Supported Schema extension and route integration exist.
Admin [x] Supported Ruby server parity covers user management, list/search/filter/sort/count, role validation, bans including social callback rejection and expiry cleanup, impersonation/admin-session restoration, session administration, password setting, destructive endpoints, and permission checks.
Anonymous [x] Supported Anonymous sign-in/delete, generator fallbacks, repeat-session rejection, and email/social link cleanup are implemented.
API key [x] Supported External package: install better_auth-api-key. Creation, verification, hashing, expiration bounds, usage/refill/rate limits, metadata migration, permissions, storage modes, deferred updates, and API-key sessions are implemented.
Bearer [x] Supported Bearer session resolution, signed-token exposure, unsigned-token fallback, signature requirement, list-session auth, and valid-cookie fallback are implemented.
Captcha [x] Supported reCAPTCHA, hCaptcha, Turnstile, CaptchaFox, protected endpoint checks, provider payloads, score checks, and failure responses are implemented.
Custom session [x] Supported Custom /get-session shaping with parsed/filtered payloads, unauthenticated nil responses, Set-Cookie preservation, OpenAPI metadata, and optional multi-session list mutation are implemented.
Device authorization [x] Supported Device/user code issuance, option validation, client validation, OAuth error responses, polling/slow-down, approval/denial, token exchange hooks, expiry, schema overrides, and verification URI behavior are implemented.
Email OTP [x] Supported Send/check/verify/sign-in/password-reset/change-email flows, attempts, latest/reused OTP, no-enumeration sends, override hooks, token storage modes, additional sign-up fields, and plugin rate limits are implemented. Client aliases are outside Ruby server scope.
Generic OAuth [x] Supported Custom OAuth sign-in/callback/link flows, DB and cookie state strategies with mismatch cleanup, dynamic authorization params, response mode, issuer checks, sign-up controls, custom token/user-info callables, standard HTTP token/userinfo exchange, provider helper factories, account-info/refresh integration, encrypted OAuth tokens, account cookies, and account linking are implemented.
Have I Been Pwned [x] Supported SHA-1 k-anonymity range lookup, default password-route protection, custom paths/messages, and injectable lookup tests are implemented.
JWT/JWKS [x] Supported EdDSA default signing, RS256/PS256/ES256/ES512 key generation, JWKS publication/custom path, key rotation/grace periods, kid selection, token expiry, remote JWKS verification, API-only sign/verify helpers, and set-auth-jwt are implemented. Symmetric client-secret algorithms such as HS256 are intentionally outside the JWKS server surface.
Last login method [x] Supported Successful email, SIWE, social OAuth, and generic OAuth logins update the readable cookie and optional lastLoginMethod user field; failed auth is suppressed and custom cookie names/prefixes/cross-origin attributes are covered.
Magic link [x] Supported Send/verify, redirects/errors, new-user signup, existing-user verification, latest-token verification, callback origin validation, and token storage modes are implemented.
MCP [x] Supported OAuth/protected-resource metadata, registration, authorization-code PKCE, token refresh, userinfo, JWKS publication, login-prompt cookie restoration, and helper challenge headers are implemented.
Multi-session [x] Supported Device sessions, active switching, same-user replacement, active-session authorization, revocation, sign-out cleanup, and invalid-token errors are implemented.
OAuth proxy [x] Supported Callback rewriting, same-origin unwrap, encrypted cross-origin cookie forwarding, timestamp/trusted-callback validation, malformed payload handling, stateless state-cookie package restoration, and DB-less provider callback flow are implemented.
OAuth provider Partial External package: install better_auth-oauth-provider. OAuth/OIDC metadata, client registration, consent, authorization-code/client-credentials tokens, introspection, revocation, and userinfo exist; organization reference, logout, encrypted client-secret, and rate-limit matrices remain.
OIDC provider [x] Supported Metadata, prompt/max-age handling, dynamic registration, consent-page and HTML consent flows, auth-code/refresh/revoke/introspection token handling, userinfo including custom claims, RP logout, client-secret storage modes, and JWT plugin ID-token signing are implemented.
One tap [x] Supported Google ID-token callback, account reuse/linking, trusted/verified account linking, disabled signup, client ID handling, invalid-token handling, and session cookies are implemented. Browser/FedCM helpers are outside Ruby server scope.
One-time token [x] Supported Generate/verify, single-use, expiration, expired-session rejection, cookie behavior, storage modes, server-only generation, and set-ott session headers are implemented.
OpenAPI Partial OpenAPI 3.1.1 metadata, route/model inventory, security schemes, servers, default responses, selected upstream request bodies, path params, disabled paths, reference HTML, theme, nonce, and disabled reference handling exist. Exact upstream snapshot parity remains open: upstream has 30 base paths and roughly 25 still need rich request/response schemas.
Organization [x] Supported Organization/member CRUD, invitations including multi-team acceptance, team flows, active org/team session fields, dynamic role CRUD safeguards, hooks, additional fields, permissions, and SQL/Rails plugin schema migrations are implemented. Browser client hooks and TypeScript inference are outside Ruby server scope.
Passkey [x] Supported External package: install better_auth-passkey. WebAuthn registration/authentication, passkey-first registration, WebAuthn extensions, verification callbacks, upstream option shapes, challenge expiration, allow/exclude credential transports, array origins, not-found delete behavior, management routes, session creation, and SQL/Rails schema output are implemented through the package-owned webauthn dependency. Browser client package aliases are outside Ruby server scope.
Phone number [x] Supported OTP send/verify, sign-in/sign-up, phone updates, password reset safety, attempt limits, uniqueness, additional fields, custom validation, and custom OTP verification are implemented.
SIWE [x] Supported Nonce, wallet sign-in, callback verification, ENS hook, account/session creation, EIP-55 checksum casing, duplicate wallet reuse, multi-chain wallets, and custom schema merging are implemented.
SSO [x] Supported External package: install better_auth-sso. Supports provider CRUD/access, OIDC discovery/callback, SAML ACS/callback/metadata, RelayState safety, replay protection, domain verification, organization assignment, and real SAML XML validation through the package-owned ruby-saml dependency.
SCIM [x] Supported External package: install better_auth-scim. Supports token envelopes, token storage modes, Bearer middleware, metadata, user CRUD, provider/org scoping, mappings, filters, PATCH operations, and organization enforcement.
Stripe [x] Supported External package: install better_auth-stripe. Fully supported for Ruby server parity after direct upstream Stripe source/test review: official stripe gem client support, injected-client checkout/portal flows, reference authorization, plan/seat/trial abuse protection, trial-start callbacks, billing event webhooks, subscription state transitions, organization subscriptions, metadata helpers, customer callbacks, checkout params/options, lookup keys, and webhook construction.
Two-factor [x] Supported TOTP, OTP, backup codes, trusted devices, cookie max-age options, disable/recovery flows, rememberMe: false preservation, and post-login verification are implemented.
Username [x] Supported Username sign-up/sign-in, availability, normalization, display username, validation order, duplicate/update behavior, and leak-prevention behavior are implemented.
Expo server integration [x] Supported Ruby server parity covers authorization proxy cookies, optional OAuth state cookie, expo-origin override/preservation, disabled override, development-only trusted exp://, wildcard trusted origins, and full trusted deep-link cookie transfer. Native Expo secure storage, cookie cache, focus/online managers, browser-opening flow, and React Native behavior tests are client-only.

Development

Clone And Verify

git clone --recursive https://github.com/sebasxsala/better-auth.git
cd better-auth
make install
make ci

One Package

cd packages/better_auth
bundle install
bundle exec rake test

External Plugin Package Tests

cd packages/better_auth-sso
rbenv exec bundle exec rake

cd ../better_auth-api-key
rbenv exec bundle exec rake

cd ../better_auth-scim
rbenv exec bundle exec rake

cd ../better_auth-stripe
rbenv exec bundle exec rake

cd ../better_auth-oauth-provider
rbenv exec bundle exec rake

Documentation

The upstream docs app has been copied into docs/ and is being adapted for Ruby/Rack/Rails. Pages that still contain upstream TypeScript examples include a warning callout at the top.

Ruby-first starter pages are available under docs/content/docs/introduction.mdx, docs/content/docs/installation.mdx, docs/content/docs/basic-usage.mdx, docs/content/docs/concepts/database.mdx, docs/content/docs/integrations/rack.mdx, docs/content/docs/integrations/rails.mdx, and docs/content/docs/integrations/sinatra.mdx.

Monorepo Layout

better-auth/
├── upstream/                   # Submodule: upstream TypeScript Better Auth
├── docs/                       # Adapted upstream docs app
├── packages/
│   ├── better_auth/            # Core gem, Minitest
│   ├── better_auth-api-key/    # External API key plugin gem
│   ├── better_auth-rails/      # Rails adapter, RSpec
│   ├── better_auth-sinatra/    # Sinatra adapter, RSpec
│   ├── better_auth-sso/        # External SSO plugin gem
│   ├── better_auth-scim/       # External SCIM plugin gem
│   ├── better_auth-stripe/     # External Stripe plugin gem
│   └── better_auth-oauth-provider/ # External OAuth provider plugin gem
├── .docs/
│   ├── features/               # Feature parity notes
│   └── plans/                  # Port implementation plans
├── Gemfile
├── Rakefile
└── Makefile

Git Workflow

  • canary: day-to-day development; open PRs here.
  • main: stable line; releases and CI publish run from here when versions bump.
  • upstream/: git submodule and reference only.
git checkout canary
git pull origin canary
git checkout -b feat/my-change
# ... commit ...
git push -u origin feat/my-change
# Open PR to canary

Release

Releases are automated with GitHub Actions on push to main when version.rb changes. The Rails adapter is published as both better_auth-rails and better_auth_rails as a compatibility alias; the Sinatra adapter publishes as better_auth-sinatra.

Details: RELEASING.md.

Dry-run locally:

make release-check

Contributing

  1. Fork the repo.
  2. Branch from canary.
  3. Read AGENTS.md and the relevant package instructions.
  4. Run make ci before pushing.
  5. Open a PR to canary.

Security

Report vulnerabilities to security@openparcel.dev. See SECURITY.md.

License

MIT License