RolifyCommunity/rolify
Role management library with resource scoping
Healthy across all four use cases
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 4mo ago
- ✓34+ active contributors
- ✓Distributed ownership (top contributor 28% of recent commits)
Show 4 more →Show less
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
- ⚠Slowing — last commit 4mo ago
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/rolifycommunity/rolify)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/rolifycommunity/rolify on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: RolifyCommunity/rolify
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/RolifyCommunity/rolify 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 all four use cases
- Last commit 4mo ago
- 34+ active contributors
- Distributed ownership (top contributor 28% of recent commits)
- MIT licensed
- CI configured
- Tests present
- ⚠ Slowing — last commit 4mo ago
<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 RolifyCommunity/rolify
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/RolifyCommunity/rolify.
What it runs against: a local clone of RolifyCommunity/rolify — 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 RolifyCommunity/rolify | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 135 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of RolifyCommunity/rolify. If you don't
# have one yet, run these first:
#
# git clone https://github.com/RolifyCommunity/rolify.git
# cd rolify
#
# 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 RolifyCommunity/rolify and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "RolifyCommunity/rolify(\\.git)?\\b" \\
&& ok "origin remote is RolifyCommunity/rolify" \\
|| miss "origin remote is not RolifyCommunity/rolify (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 master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "lib/rolify.rb" \\
&& ok "lib/rolify.rb" \\
|| miss "missing critical file: lib/rolify.rb"
test -f "lib/rolify/role.rb" \\
&& ok "lib/rolify/role.rb" \\
|| miss "missing critical file: lib/rolify/role.rb"
test -f "lib/rolify/adapters/base.rb" \\
&& ok "lib/rolify/adapters/base.rb" \\
|| miss "missing critical file: lib/rolify/adapters/base.rb"
test -f "lib/rolify/adapters/active_record/role_adapter.rb" \\
&& ok "lib/rolify/adapters/active_record/role_adapter.rb" \\
|| miss "missing critical file: lib/rolify/adapters/active_record/role_adapter.rb"
test -f "lib/rolify/adapters/mongoid/role_adapter.rb" \\
&& ok "lib/rolify/adapters/mongoid/role_adapter.rb" \\
|| miss "missing critical file: lib/rolify/adapters/mongoid/role_adapter.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 135 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~105d)"
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/RolifyCommunity/rolify"
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
Rolify is a lightweight Ruby on Rails role management library that assigns roles to users with optional resource scoping, allowing fine-grained permission checks like user.has_role?(:moderator, @forum). It supports both ActiveRecord and Mongoid ORMs and integrates cleanly with authorization gems like CanCanCan and Pundit without enforcing any particular authorization strategy. Modular architecture with lib/rolify/adapters/ housing ORM-specific logic (active_record/ and mongoid/ subdirectories with role_adapter.rb, resource_adapter.rb, and scopes.rb). Core role assignment lives in lib/rolify/role.rb, finders in lib/rolify/finders.rb, and generators in lib/generators/ create user-side mixins and migrations per ORM.
👥Who it's for
Rails developers building multi-tenant or resource-scoped permission systems who need to assign and query user roles (e.g., 'moderator of this forum' vs 'admin globally') without implementing role management from scratch.
🌱Maturity & risk
Production-ready and actively maintained. The codebase shows 160KB of Ruby code with dual ORM support (ActiveRecord ≥4.2, Mongoid ≥4.0), comprehensive generators, and CI workflows for both ORMs across Rails 6–7. The CHANGELOG and UPGRADE docs indicate steady evolution; however, commit recency is not visible in the provided data.
Low-to-moderate risk: the gem has broad ORM support which increases complexity and surface area for bugs. Single-maintainer open-source risk is typical for this size project. Dependency on aging Rails/Ruby versions (Rails 4.2 support) suggests maintenance burden, though no high-risk CVEs are indicated in the file list. Upgrade documentation exists, suggesting breaking changes have occurred.
Active areas of work
The repo uses Appraisals (in Appraisals file) to test against multiple ActiveRecord (6–7) and Mongoid (5–7) versions via GitHub Actions workflows (.github/workflows/). Dependabot is configured for dependency updates. No specific milestone or active PR data is visible, suggesting steady maintenance mode rather than rapid feature development.
🚀Get running
git clone https://github.com/RolifyCommunity/rolify.git
cd rolify
bundle install
rake test
Daily commands:
Run tests with rake test (default Rakefile target). For specific ORM: bundle exec appraisal activerecord_7 rake test or bundle exec appraisal mongoid_6 rake test. No dev server—this is a library, not an application.
🗺️Map of the codebase
lib/rolify.rb— Main entry point that loads the entire rolify library and sets up the gem configuration.lib/rolify/role.rb— Core Role model definition; all role functionality depends on this abstraction.lib/rolify/adapters/base.rb— Abstract base adapter defining the interface that both ActiveRecord and Mongoid adapters must implement.lib/rolify/adapters/active_record/role_adapter.rb— ActiveRecord-specific role persistence and querying; critical for Rails app integration.lib/rolify/adapters/mongoid/role_adapter.rb— Mongoid-specific role persistence and querying; enables non-relational database support.lib/rolify/finders.rb— Core finder methods for role queries and scope-based lookups; used by all role checking logic.lib/rolify/configure.rb— Configuration setup that initializes adapters and defines the scoping model; must be read before integration.
🧩Components & responsibilities
- Role Model (ActiveRecord or Mongoid) — Stores role name, associated user/resource IDs, and resource type; primary data container.
- Failure mode: Missing or corrupt role records lead to failed authorization checks or false negatives.
- Adapter Layer (ActiveRecord::Base, Mongoid::Document) — Abstracts database operations (find_roles, add_role, remove_role) behind a consistent interface.
- Failure mode: Adapter bugs cause queries to miss roles or write invalid data; breaks across ORM versions.
- Finders Module (Adapter interface, Enumerable) — Implements has_role?, has_all_roles, has_any_role, and other query DSL methods.
- Failure mode: Logic errors cause false positives/negatives in role assertions, exposing security gaps.
- Resource Scoping (Polymorphic associations) — Associates roles with specific resource instances (forums, projects) to enable fine-grained permissions.
- Failure mode: Incorrect scope binding allows users to inherit roles across unrelated resources.
🔀Data flow
User/Application Code→Rolify DSL (lib/rolify/finders.rb)— Application calls has_role?(:moderator, @forum) or add_role(:admin).Rolify DSL→Adapter (ActiveRecord or Mongoid)— Finders delegate to adapter.find_roles() or adapter.add_role() based on ORM.Adapter→Database— undefined
🛠️How to make changes
Add a new role-checking method to user models
- Add
resourcifyto your User model to enable role assignment (lib/rolify/resource.rb) - Use
user.has_role?(:admin, @resource)in your code; method defined in (lib/rolify/finders.rb) - To customize role logic, override methods or add callbacks via (
lib/rolify/dynamic.rb)
Add support for a new database adapter (e.g., Sequel)
- Create new adapter directory mirroring active_record or mongoid structure (
lib/rolify/adapters/base.rb) - Implement role_adapter.rb inheriting from base and implementing find_roles, add_role, remove_role (
lib/rolify/adapters/base.rb) - Implement resource_adapter.rb with scope-based query methods (
lib/rolify/adapters/base.rb) - Register adapter in configure.rb DSL and update railtie.rb for auto-detection (
lib/rolify/configure.rb)
Customize role scoping behavior for a resource type
- Call
Rolify.configurein an initializer to set the scoping model (lib/rolify/configure.rb) - Add
:resource_finderor:role_validatorcallbacks in the Role model (lib/rolify/role.rb) - Override finder methods in lib/rolify/adapters/[adapter]/role_adapter.rb to customize queries (
lib/rolify/finders.rb)
🔧Why these technologies
- Adapter Pattern (ActiveRecord + Mongoid) — Allows same DSL to work with relational (PostgreSQL/MySQL) and document (MongoDB) databases without changing user code.
- Dynamic Role Creation — Roles don't need to be pre-defined in the database; any string becomes a valid role at runtime, enabling flexible authorization models.
- Resource Scoping — Enables fine-grained permissions like 'user is moderator of forum X but not forum Y' without separate RBAC tables.
- Rails Generators — Automates boilerplate migration and model setup, reducing integration friction for new projects.
⚖️Trade-offs already made
-
Library only handles role assignment/checking, not authorization enforcement
- Why: Keeps rolify lightweight and composable with dedicated authorization libraries (CanCanCan, Pundit).
- Consequence: Users must manually implement permission logic; no built-in access control.
-
Separate adapter implementations for ActiveRecord and Mongoid
- Why: Optimizes queries for each ORM (e.g., Mongoid uses aggregation pipelines, AR uses joins).
- Consequence: Adding new database support requires full adapter implementation; more code duplication.
-
Roles are stored as polymorphic records with optional resource scoping
- Why: Avoids schema explosion and handles both global and resource-scoped roles uniformly.
- Consequence: Complex queries for role enumeration; filtering requires explicit resource_type/resource_id checks.
🚫Non-goals (don't propose these)
- Does not enforce authorization; provides only role assignment and checking.
- Does not handle authentication (login/logout); integrates with auth gems via User model.
- Does not provide UI/admin panels for role management.
- Does not include role hierarchies or inheritance (e.g., admin inherits moderator).
- Not a real-time permission engine; role changes require database queries.
🪤Traps & gotchas
Migration naming: generators create dated migrations; ensure db:migrate runs before db:rollback or you'll hit FK constraint errors. Mongoid vs ActiveRecord path divergence: some features (callbacks, inverse_of option) behave subtly differently; test thoroughly in both ORMs if adding features. Role name uniqueness not enforced in schema: duplicate role names are possible without application-level validation, causing unexpected query results. requires_resource flag: roles can be marked as resource-required; querying without a resource on a required role silently returns false—easy to miss in tests.
🏗️Architecture
💡Concepts to learn
- ORM Adapter Pattern — Rolify abstracts ActiveRecord and Mongoid behind a common interface (lib/rolify/adapters/base.rb); understanding how adapters work is essential to extend Rolify to new ORMs or fix ORM-specific bugs
- Resource-Scoped Authorization — The core feature—roles are tied to specific resource instances (forums, projects) not just globally; critical to understand how join tables (role_users, role_resources) enforce this constraint
- Rails Generators — Rolify uses lib/generators/ heavily to scaffold Role models, migrations, and User mixins; new contributors must understand Thor DSL and how generators hook into Rails app setup
- Polymorphic Associations — Rolify uses polymorphic belongs_to on the role_resources table to allow any model to be a role scope (Forum, Project, etc.); understanding polymorphic FKs is key to grasping resource scoping
- ActiveRecord Callbacks vs Mongoid Callbacks — Rolify supports before_add, after_add, before_remove, after_remove hooks; these behave subtly differently between ORMs, and bugs often lurk in callback timing or exception handling
- Appraisal Gem Testing — Rolify uses Appraisals to test against multiple Rails/ORM versions simultaneously (gemfiles/activerecord_6.gemfile, etc.); critical for maintaining cross-version compatibility without manual environment juggling
- Scope Methods in Rails Queries — lib/rolify/adapters/*/scopes.rb define chainable query methods (e.g., roles.with_resource(:admin).where(...)); understanding how scopes compose is essential for adding new query patterns
🔗Related repos
CanCanCommunity/cancancan— Authorization gem that integrates with rolify for permission enforcement; rolify provides roles, CanCanCan uses them to gate actionsvarvet/pundit— Policy-based authorization library; complementary to rolify for implementing complex permission rules on top of role assignmentsplataformatec/devise— Authentication gem mentioned in README; rolify pairs with Devise for a complete authentication + role management stackrolifycommunity/rolify-ruby— Predecessor or sister project; check for architectural insights or migration paths between gemsmongodb/mongoid— ODM that rolify must support; understanding Mongoid internals is critical for debugging adapter code
🪄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 test coverage for Mongoid adapters with MongoDB 6.0+ compatibility
The repo has parallel ActiveRecord and Mongoid adapters (lib/rolify/adapters/mongoid/*), but spec/rolify/ appears to lack dedicated Mongoid integration tests. The gemfiles include mongoid_5.gemfile through mongoid_7.gemfile, suggesting support for multiple versions, but test coverage for adapter-specific scoping behavior is missing. This is critical since resource scoping is the library's core feature and must work reliably across both ORMs.
- [ ] Create spec/rolify/mongoid_adapters_spec.rb to test Mongoid resource_adapter.rb and role_adapter.rb
- [ ] Add tests for scopes.rb Mongoid-specific query generation (lib/rolify/adapters/mongoid/scopes.rb)
- [ ] Add MongoDB-specific tests for dynamic role assignment and querying across mongoid_5/6/7 versions
- [ ] Verify Gemfile workflows in .github/workflows/mongoid.yml actually run these tests
Add integration tests for ActiveRecord 6 & 7 resource scoping edge cases
While gemfiles/activerecord_6.gemfile and activerecord_7.gemfile exist and CI workflows reference them, spec/rolify/ lacks explicit ActiveRecord version-specific scoping tests. The lib/rolify/adapters/active_record/scopes.rb file implements critical query logic that may behave differently across AR versions due to changes in Arel and scope composition. Missing tests for STI models, polymorphic resources, and complex scoping chains.
- [ ] Create spec/rolify/activerecord_scopes_spec.rb with tests for lib/rolify/adapters/active_record/scopes.rb
- [ ] Add test cases for polymorphic resource scoping (e.g., user.has_role?(:admin, resource) with different resource types)
- [ ] Test edge cases: STI models, soft-deleted resources, and chained scopes across AR 6 & 7
- [ ] Add appraisal-specific test runs to .github/workflows/activerecord.yml if not present
Add missing RSpec matchers tests and extend matcher coverage for resource-scoped roles
spec/rolify/matchers_spec.rb exists but appears minimal given that lib/rolify/matchers.rb is a core feature. RSpec matchers for roles with resource scoping (e.g., user.should have_role(:editor, @post)) are underdocumented and undertested. The matcher implementation should support complex assertions across both ActiveRecord and Mongoid, but there's no evidence of comprehensive test coverage.
- [ ] Expand spec/rolify/matchers_spec.rb to cover all matchers in lib/rolify/matchers.rb with resource-scoped role assertions
- [ ] Add tests for negative matchers (e.g.,
should_not have_role) - [ ] Test matchers with polymorphic resources and nil resources (global roles)
- [ ] Add examples to lib/generators/rolify/templates/README documenting RSpec matcher usage with scopes
🌿Good first issues
- Add comprehensive test coverage for
lib/rolify/matchers.rb; the file exists but is not referenced in major test workflows, suggesting incomplete test harness for custom Rspec matchers - Write integration tests for edge case: assigning the same role to a user on multiple resources, then querying with has_role?(role, resource) to ensure no cross-resource leakage
- Expand README.md with concrete example of resource-scoped roles in a real scenario (e.g., 'User is admin of Forum A, moderator of Forum B') showing all four role callback hooks in action
⭐Top contributors
Click to expand
Top contributors
- @wldcordeiro — 28 commits
- @lorefnon — 14 commits
- @thomas-mcdonald — 10 commits
- @olleolleolle — 6 commits
- @EppO — 4 commits
📝Recent commits
Click to expand
Recent commits
3d5234d— Let rails figure out which fields to select (#580) (Taeir)9e5b8ea— fix CI matrix (#605) (thomas-mcdonald)55261dc— prepare 6.0.1 release (#589) (thomas-mcdonald)daad1cd— Adds Ruby 3.2 to the CI matrix (#588) (petergoldstein)584d329— Bump actions/checkout from 2 to 3 (#585) (dependabot[bot])03cd9d6— Add Dependabot for GitHub Actions (#582) (petergoldstein)0c883f4— Fix with_role with :any resource (#575) (v-kumar)e07e69f— Add Ruby 3.1 and ActiveRecord 7 to CI (#574) (petergoldstein)bb295d9— run CI onpull_request(#573) (thomas-mcdonald)c0f9d36— bump to version 6.0 (thomas-mcdonald)
🔒Security observations
The rolify gem appears to be a well-structured role management library with reasonable security practices overall. However, there are potential risks related to dynamic query building in both ActiveRecord and Mongoid adapters that require careful implementation to prevent SQL/NoSQL injection attacks. The library's use of dynamic code evaluation (dynamic.rb) and metaprogramming should be thoroughly reviewed to ensure it doesn't process untrusted input. The project would benefit from enhanced security documentation, a formal vulnerability disclosure policy, and comprehensive input validation guidelines. The moderate security score reflects the need for these improvements, particularly around query parameterization and dynamic feature safety.
- Medium · Potential SQL Injection in Dynamic Query Building —
lib/rolify/adapters/active_record/scopes.rb, lib/rolify/adapters/active_record/role_adapter.rb. The codebase includes adapters for ActiveRecord (lib/rolify/adapters/active_record/) that build database queries. Without reviewing the actual implementation of scopes.rb and role_adapter.rb, there's a risk of SQL injection if user input is directly interpolated into queries rather than using parameterized queries. Fix: Ensure all database queries use parameterized statements or ActiveRecord's built-in query methods. Avoid string interpolation with user-supplied values. Review implementations of dynamic query building in adapter files. - Medium · Potential NoSQL Injection in Mongoid Adapter —
lib/rolify/adapters/mongoid/scopes.rb, lib/rolify/adapters/mongoid/role_adapter.rb. The Mongoid adapter (lib/rolify/adapters/mongoid/) may be vulnerable to NoSQL injection if role names, resources, or scope identifiers are not properly sanitized before being used in database queries. Fix: Validate and sanitize all input parameters before using them in Mongoid queries. Use Mongoid's built-in query methods rather than building queries with string interpolation. Implement strict type checking for role names and resource identifiers. - Medium · Dynamic Code Evaluation Risk —
lib/rolify/dynamic.rb. The lib/rolify/dynamic.rb file suggests dynamic role or method generation. Dynamic evaluation of code (eval, instance_eval, class_eval) could be exploited if it processes untrusted input, potentially leading to arbitrary code execution. Fix: Avoid using eval() or similar dynamic code evaluation with user-supplied data. Use explicit method definitions or whitelisting approaches. If dynamic behavior is necessary, implement strict input validation and use safe metaprogramming patterns. - Low · Missing or Incomplete Security Configuration —
Repository root. The .hakiri.yml file suggests security scanning is configured, but there's no visible evidence of comprehensive security policies in the repository (no SECURITY.md file, no security headers configuration documented). Fix: Add a SECURITY.md file outlining the security policy, vulnerability disclosure process, and supported versions for security patches. Implement dependency scanning with tools like Bundler Audit or Dependabot as part of CI/CD. - Low · Lack of Input Validation Documentation —
lib/rolify/role.rb, lib/rolify/resource.rb, lib/rolify/finders.rb. The library handles role names, resource scoping, and namespace parameters. Without explicit input validation, there's potential for unexpected behavior or security issues if the library is used with untrusted input. Fix: Implement explicit input validation for role names, resource identifiers, and namespaces. Document expected input formats and constraints. Validate data types and length limits to prevent abuse.
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.