thoughtbot/clearance
Rails authentication with email & password.
Healthy across the board
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 3d ago
- ✓27+ active contributors
- ✓Distributed ownership (top contributor 36% of recent commits)
Show 3 more →Show less
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/thoughtbot/clearance)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/thoughtbot/clearance on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: thoughtbot/clearance
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/thoughtbot/clearance shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 3d ago
- 27+ active contributors
- Distributed ownership (top contributor 36% of recent commits)
- MIT licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live thoughtbot/clearance
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/thoughtbot/clearance.
What it runs against: a local clone of thoughtbot/clearance — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in thoughtbot/clearance | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 33 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of thoughtbot/clearance. If you don't
# have one yet, run these first:
#
# git clone https://github.com/thoughtbot/clearance.git
# cd clearance
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of thoughtbot/clearance and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "thoughtbot/clearance(\\.git)?\\b" \\
&& ok "origin remote is thoughtbot/clearance" \\
|| miss "origin remote is not thoughtbot/clearance (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "lib/clearance.rb" \\
&& ok "lib/clearance.rb" \\
|| miss "missing critical file: lib/clearance.rb"
test -f "lib/clearance/engine.rb" \\
&& ok "lib/clearance/engine.rb" \\
|| miss "missing critical file: lib/clearance/engine.rb"
test -f "lib/clearance/authentication.rb" \\
&& ok "lib/clearance/authentication.rb" \\
|| miss "missing critical file: lib/clearance/authentication.rb"
test -f "app/controllers/clearance/base_controller.rb" \\
&& ok "app/controllers/clearance/base_controller.rb" \\
|| miss "missing critical file: app/controllers/clearance/base_controller.rb"
test -f "lib/clearance/user.rb" \\
&& ok "lib/clearance/user.rb" \\
|| miss "missing critical file: lib/clearance/user.rb"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 33 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~3d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/thoughtbot/clearance"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Clearance is a minimal Rails authentication engine providing email/password sign-up, sign-in, and password reset flows. It handles user session management via remember tokens, integrates directly into Rails controllers and mailers, and is tested against Rails 7.2+ and Ruby 3.3.11+. It solves the problem of building custom authentication without reinventing password hashing, session tokens, and email confirmation workflows. Rails engine structure: app/ contains controllers (sessions, passwords, users), mailers, and views as engine defaults; lib/ holds the core logic (inferred from standard Rails engine layout); config/locales/ provides i18n strings; config/routes.rb defines engine routes. Tests and fixtures not visible in file list but critical given the emphasis on 'well-tested.' Single-gem distribution, not a monorepo.
👥Who it's for
Rails developers building applications that need production-grade email/password authentication without the complexity of Devise or other heavy gems. Specifically for teams who want a small, testable, opinionated-but-overridable auth system they can easily customize or debug.
🌱Maturity & risk
Production-ready and actively maintained. The repo shows strong CI/CD setup (GitHub Actions for tests, CodeQL, StandardRB linting), comprehensive test coverage indicated by the 171KB of Ruby code, and regular maintenance workflows. However, the file structure suggests moderate scope—it's intentionally lean rather than feature-complete, which is by design per the README's philosophy of being 'small, simple, and well-tested.'
Low risk for a well-established gem, but consider: (1) single maintainer model (thoughtbot maintains it primarily) creates potential bus-factor risk; (2) the gem must stay compatible across Rails 7.2–8.1 (see gemfiles/ directory), which requires proactive testing; (3) security-sensitive code (password hashing, session tokens) demands careful review of changes. Check SECURITY.md and recent commits for security patches.
Active areas of work
Based on file structure, active maintenance targets Rails 8.1 compatibility (gemfiles/rails_8.1.gemfile exists), CodeQL security scanning is enabled, and the repo uses Appraisals for multi-version testing. The presence of .github/workflows/dynamic-*.yml suggests automated README and security docs generation. No specific PR/issue data visible, but the test workflow is clearly active.
🚀Get running
git clone https://github.com/thoughtbot/clearance.git
cd clearance
bundle install
bin/setup
bundle exec rspec # run tests
Daily commands:
bundle exec rake # runs full test suite
bundle exec rspec # runs RSpec tests
bin/appraisal install # sets up Appraisals for multi-version testing
bundle exec appraisal rails_8.1 rspec # test against specific Rails version
🗺️Map of the codebase
lib/clearance.rb— Main entry point that loads the engine and exposes the public API; required reading for understanding the gem's structurelib/clearance/engine.rb— Rails engine configuration that registers controllers, routes, and generators; essential for understanding how Clearance integrates with Railslib/clearance/authentication.rb— Core authentication logic that defines session behavior and user signing in/out; critical for security and auth flowapp/controllers/clearance/base_controller.rb— Base controller providing authorization helpers used by all Clearance controllers; foundational for access controllib/clearance/user.rb— User model mixin providing password hashing, token generation, and validation; defines the primary domain modellib/clearance/configuration.rb— Gem configuration system allowing customization of password strategy, mailer, and behavior; essential for extension pointsconfig/routes.rb— Route definitions for sign in, sign up, password reset, and session management endpoints
🛠️How to make changes
Add Custom Sign-In Guard (Multi-Factor Auth, IP Blocking, etc.)
- Create a sign-in guard class inheriting from Clearance::SignInGuard in your app/lib directory (
lib/my_sign_in_guard.rb (new file)) - Implement the call method to return success or failure based on custom logic (
lib/my_sign_in_guard.rb) - Register it in the Clearance initializer (
config/initializers/clearance.rb) - Example in initializer: Clearance.configure { |config| config.sign_in_guards += [MySignInGuard] } (
config/initializers/clearance.rb)
Switch Password Hashing Strategy (Bcrypt → Argon2)
- Add gem 'argon2-kdf' to Gemfile (
Gemfile) - Set password_strategy in Clearance initializer (
config/initializers/clearance.rb) - Example: Clearance.configure { |config| config.password_strategy = Clearance::PasswordStrategies::Argon2 } (
config/initializers/clearance.rb) - Existing passwords will be rehashed on next login via update_password method in User model (
lib/clearance/user.rb)
Customize Authentication Flow (Email Verification, Custom Redirect, etc.)
- Override sessions_controller methods (create, destroy) in your app/controllers/sessions_controller.rb (
app/controllers/sessions_controller.rb (new file)) - Call super then add custom logic (e.g., sign_in uses Clearance::Authentication#sign_in) (
app/controllers/sessions_controller.rb) - To customize mailer, override app/mailers/clearance_mailer.rb (
app/mailers/clearance_mailer.rb (override)) - Set mailer_class in initializer: config.mailer_class = CustomMailer (
config/initializers/clearance.rb)
Add Additional User Fields or Validation
- Create a migration to add columns to users table (
db/migrate/[timestamp]_add_fields_to_users.rb (new file)) - Update the User model with validates and associations (
app/models/user.rb (already includes Clearance::User mixin)) - Update sign-up form to accept new fields (
app/views/users/_form.html.erb (override)) - Permit new params in users_controller via strong parameters override (
app/controllers/users_controller.rb (override))
🪤Traps & gotchas
(1) Cookie domain & path: config.cookie_domain and config.cookie_path must match your app's deployment domain or remember tokens won't persist across requests. (2) CSRF rotation: config.rotate_csrf_on_sign_in = true (default) changes CSRF tokens on login; if your front-end caches tokens, it will fail POST requests. (3) Mailer sender required: config.mailer_sender must be set or password reset emails won't send. (4) Password strategy immutability: changing password_strategy in production breaks existing user hashes; migrations are not automatic. (5) Routes not auto-mounted: set config.routes = true or manually mount Clearance::Engine in config/routes.rb or auth won't be accessible.
🏗️Architecture
💡Concepts to learn
- Remember Token / Persistent Session — Clearance uses remember tokens (config.cookie_name, config.cookie_expiration) to maintain long-lived sessions without storing user state on the server; understanding token rotation and expiry is key to debugging session issues
- Password Hashing Strategy Pattern — Clearance abstracts password hashing behind Clearance::PasswordStrategies (BCrypt by default); this pattern allows swapping strategies without changing controller logic, critical for upgrading hashing algorithms safely
- Rails Engine — Clearance is a Rails engine (lib/clearance mounted via config/routes.rb), meaning it provides pre-built models, controllers, and views to the host app; understanding engine isolation and override patterns is essential for customization
- CSRF Token Rotation — config.rotate_csrf_on_sign_in refreshes the CSRF token on every sign-in to prevent token fixation attacks; misunderstanding this can break form submissions or API calls if tokens are cached client-side
- Routing Constraints — Clearance::Constraints::SignedIn allows restricting routes to authenticated users at the routing layer (not just in controllers); understanding constraint blocks helps with fine-grained access control (e.g., admin-only routes)
- Secure Cookie Attributes (HttpOnly, SameSite, Secure) — Clearance config exposes httponly, same_site, and secure_cookie settings that prevent XSS/CSRF attacks; these must align with your app's TLS/SSL setup (secure_cookie defaults to Rails.configuration.force_ssl)
- Before Action Filters / Access Control — require_login is a before_action filter that gates controller actions; understanding the filter chain and how to chain multiple guards (sign_in_guards) is fundamental to building protected endpoints
🔗Related repos
heartcombo/devise— Heavy-weight alternative providing auth + multi-strategy (LDAP, OAuth) support; used when Clearance is too minimalrails/rails— Parent framework; Clearance extends ActionController::Base and Rails::Engine; track Rails versions for compatibilitythoughtbot/shoulda-matchers— Same maintainer (thoughtbot); commonly paired with Clearance for clean auth spec testing (e.g., require_login assertions)josevalim/responders— Companion gem for Rails controller response handling; often used with Clearance to standardize JSON responses in sign-in/sign-outbcrypt-ruby/bcrypt-ruby— Dependency backing Clearance::PasswordStrategies::BCrypt; critical for password security
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive integration tests for password reset flow with email delivery
The repo has app/mailers/clearance_mailer.rb and app/controllers/clearance/passwords_controller.rb but the spec directory structure isn't shown. Password reset is a critical auth flow that needs robust testing across mailer delivery, token generation, and controller actions. This would catch edge cases like expired tokens, invalid emails, and concurrent reset attempts.
- [ ] Create
spec/mailers/clearance_mailer_spec.rbwith tests forchange_passwordemail generation and delivery - [ ] Add integration tests in
spec/features/password_reset_spec.rbcovering: requesting reset, receiving email, clicking link, resetting with valid/invalid tokens - [ ] Add edge case tests for token expiration timing and concurrent reset requests
- [ ] Verify all locales in
config/locales/clearance.en.ymlare used in mailer templates
Add GitHub Actions workflow for testing against Ruby 3.3.11 explicitly
The README states 'Ruby >= 3.3.11' as minimum, but .github/workflows/tests.yml likely tests a range of versions. Adding an explicit CI job that pins to exactly 3.3.11 ensures the minimum supported version claim is validated in every PR, preventing accidental breaking changes.
- [ ] Review current
.github/workflows/tests.ymlto identify Ruby version matrix - [ ] Add a dedicated job that explicitly tests against Ruby 3.3.11 with the earliest supported Rails 7.2.x version
- [ ] Ensure this job runs on every PR and main branch push
- [ ] Document the minimum version testing requirement in
CONTRIBUTING.md
Add documentation and tests for custom password strategies integration
The repo has lib/clearance/password_strategies/argon2.rb and lib/clearance/password_strategies/bcrypt.rb but no visible guide showing how users can implement their own custom strategy. This is a power-user feature that needs clear examples in CONTRIBUTING.md or a new doc/password_strategies.md file with corresponding integration tests.
- [ ] Create
doc/password_strategies.mddocumenting the interface that custom strategies must implement (e.g., required methods, signature) - [ ] Add example implementation showing how to create a custom strategy (e.g., scrypt-based)
- [ ] Create
spec/lib/clearance/password_strategies_spec.rbwith tests for strategy loading and fallback behavior - [ ] Add an integration test showing a user can swap password strategies in
config/initializers/clearance.rb
🌿Good first issues
- Add test coverage for edge cases in Clearance::Constraints::SignedIn—write specs in spec/clearance/constraints/ for scenarios like anonymous users, expired tokens, and concurrent requests (constraint logic not visible in file list but is likely undertested).
- Document password reset workflow with a step-by-step guide in CONTRIBUTING.md or a new doc/password-reset.md, including how custom mailers override defaults and how to test password emails in specs.
- Extract view templates (app/views/users/_form.html.erb, app/views/sessions/_form.html.erb) into separate partials for better reusability and add i18n keys for all form labels currently hardcoded—map to config/locales/clearance.en.yml.
⭐Top contributors
Click to expand
Top contributors
- @dependabot[bot] — 36 commits
- [@Sara Jackson](https://github.com/Sara Jackson) — 18 commits
- @FerPerales — 9 commits
- @github-actions[bot] — 5 commits
- @sej3506 — 3 commits
📝Recent commits
Click to expand
Recent commits
fd775ce— Bump version to 2.12.0 (#1106) (FerPerales)1aa665c— Bump argon2 from 2.3.2 to 2.3.3 (#1102) (dependabot[bot])78d0957— Bump timecop from 0.9.10 to 0.9.11 (#1105) (dependabot[bot])c1f9f7e— Bump ffi from 1.17.2 to 1.17.4 (#1103) (dependabot[bot])4750d0c— Bump sqlite3 from 2.8.1 to 2.9.2 (#1104) (dependabot[bot])6f31366— Bump rspec-rails from 8.0.2 to 8.0.4 (#1101) (dependabot[bot])ab6e323— Add missing permissions to GitHub Actions jobs (#1100) (FerPerales)662562d— Bump standard from 1.52.0 to 1.54.0 (#1093) (dependabot[bot])9566162— Bump shoulda-matchers from 6.5.0 to 7.0.1 (#1095) (dependabot[bot])3ff0b72— Bump pry from 0.15.2 to 0.16.0 (#1094) (dependabot[bot])
🔒Security observations
Clearance is a well-structured Rails authentication gem with generally good security practices. The main concerns are around configuration and implementation details that require code review: session management, sign-in guard logic, token comparison methods, and development backdoor mechanisms. No critical hardcoded secrets were identified in the file structure. The security policy could be improved by supporting multiple versions with security patches. Overall, the gem follows Rails security best practices but requires careful configuration and extension by integrating applications.
- Medium · Incomplete Security Policy Documentation —
SECURITY.md. The SECURITY.md file indicates support only for the latest version with no security patches for older versions. This could leave users on older versions vulnerable to known security issues without guidance on remediation paths. Fix: Define a clear security support window (e.g., last 2-3 versions) and establish a process for backporting critical security fixes. Document this explicitly in SECURITY.md. - Medium · Password Strategy Implementation Review Needed —
lib/clearance/password_strategies/. Multiple password hashing strategies (bcrypt and argon2) are supported. The codebase should ensure proper migration paths and configuration to prevent users from accidentally using weaker hashing algorithms. Fix: Review password strategy selection logic in configuration. Ensure argon2 is the default recommendation, and provide clear migration guidance in documentation. Validate that outdated strategies can be deprecated with proper warnings. - Medium · Session Management Configuration —
lib/clearance/session.rb, lib/clearance/rack_session.rb, lib/clearance/session_status.rb. The presence of RackSession, Session, and SessionStatus modules suggests custom session handling. Without reviewing the actual implementation, there's potential for session fixation, CSRF, or improper session invalidation issues. Fix: Conduct a thorough code review of session management to ensure: (1) Secure session tokens are generated with sufficient entropy, (2) Session fixation attacks are prevented, (3) Sessions are properly invalidated on logout, (4) CSRF protection is enabled. - Medium · Sign-in Guard Implementation —
lib/clearance/default_sign_in_guard.rb, lib/clearance/sign_in_guard.rb. The presence of DefaultSignInGuard and SignInGuard modules suggests extensible authentication logic. Weak default implementations or improper extension points could allow bypassing security checks. Fix: Review the sign-in guard implementation to ensure it properly validates all authentication factors and cannot be easily bypassed through improper extension or configuration. - Low · Potential Timing Attack in Token Comparison —
lib/clearance/token.rb. The Token module in lib/clearance/token.rb may be vulnerable to timing attacks if string comparison is not constant-time when validating tokens. Fix: Ensure that all token comparison operations use constant-time string comparison (e.g., ActiveSupport::SecurityUtils.secure_compare in Rails). - Low · Back Door Authentication Mechanism —
lib/clearance/back_door.rb. The presence of lib/clearance/back_door.rb suggests a development/testing authentication bypass mechanism. If accidentally enabled in production, this could be a critical vulnerability. Fix: Verify that back_door authentication is only enabled in development/test environments. Add explicit guards and environment checks to prevent production usage. Document this prominently. - Low · Email-Based Authentication —
app/controllers/clearance/users_controller.rb, app/controllers/clearance/passwords_controller.rb. The gem uses email as the primary authentication identifier. While common, email enumeration attacks are possible during signup and password reset flows. Fix: Review password reset and user creation endpoints to ensure they don't leak information about whether an email exists in the system. Consider implementing rate limiting on these endpoints.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.