A mountable Rails engine that gives any app configurable roles and module-wise permissions — actors can hold any number of roles — plus a unified, immutable audit log of every role assignment/revocation and every permission granted/revoked, with ready-made, paginated HTML admin screens.
Most Rails apps end up building the same three things by hand: a Role/Permission
table, something that checks them in a controller, and — eventually, usually after an
incident — a log of who changed what. Argus::Trail ships all three as one mountable engine:
plain ActiveRecord models, an admin UI to manage them, a rake task that generates permissions
straight from your routes, and a one-line controller concern to enforce them. No hardcoded
role/permission names, no fixed actor class, no required auth library.
# Gemfile
gem "argus-trail"
bundle install
bin/rails generate argus:trail:install
bin/rails db:migrate
bin/rails argus_trail:fetch_permissions
That last command scans your app's routes and creates a Permission for every
controller/action it finds — module_name: "admin/accounts", action: "read" — so
you're assigning real permissions to roles within minutes, not hand-typing them one at a time.
Gate your own controllers with the same convention, no further code:
class AccountsController < ApplicationController
include Argus::Trail::Authorizable
end
Argus::Trail::Role/Permission); an actor can hold any number of
roles (0..N), tracked in the engine's own polymorphic join table — no schema change to your
actor/user table at all.module_name + action
(e.g. "admin/accounts" / "read") alongside plain named permissions
for anything that isn't controller-shaped. bin/rails argus_trail:fetch_permissions
generates these from your routes and is safe to rerun as your app grows; fetch_permissions:prune
removes ones whose route is gone and aren't granted to any role.include Argus::Trail::Authorizable in
any controller derives the required permission from the controller + action automatically
and checks it against the signed-in actor's roles.AuditEntry, via
Actor#sync_roles!/Role#sync_permissions! — not a single generic
"updated" row, one entry per actual change, with who made it.ApplicationController automatically; the admin screens work out of the box
(any signed-in actor) and tighten with a Pundit policy or config.authorize_with
whenever you're ready.Pundit and CanCanCan are authorization libraries — they check "can this user do X," but ship no persisted role/permission model, no admin UI, and no audit trail; you bring your own. rolify persists roles, but not permissions, and has no built-in enforcement or audit log. Argus::Trail auto-integrates with Pundit if it's already in your Gemfile, rather than competing with it.
| Capability | Argus::Trail | Pundit | CanCanCan | rolify |
|---|---|---|---|---|
| Persisted role/permission model | ✅ | ❌ | Partial | Roles only |
| Module-wise (controller×action) permissions | ✅ | ❌ | ❌ | ❌ |
| Generates permissions from your routes | ✅ | ❌ | ❌ | ❌ |
| One-line controller enforcement | ✅ | Per-policy | ✅ | ❌ |
| Audit log of role/permission changes | ✅ | ❌ | ❌ | ❌ |
| Admin UI included | ✅ | ❌ | ❌ | ❌ |
| Works with zero auth library installed | ✅ | — | — | ✅ |
| Auto-integrates with Pundit if present | ✅ | — | ❌ | ❌ |