# Pundit — Minimal Authorization Library for Ruby > A lightweight, object-oriented authorization library for Ruby on Rails that uses plain Ruby classes and methods to define access policies, keeping authorization logic simple and testable. ## Install Save as a script file and run: # Pundit — Minimal Authorization Library for Ruby ## Quick Use ```bash gem 'pundit' bundle install rails generate pundit:install ``` ```ruby # app/policies/post_policy.rb class PostPolicy < ApplicationPolicy def update? user.admin? || record.author == user end end # In a controller class PostsController < ApplicationController include Pundit::Authorization def update @post = Post.find(params[:id]) authorize @post # proceeds only if PostPolicy#update? returns true end end ``` ## Introduction Pundit provides a minimal authorization system for Ruby on Rails built around plain Ruby policy classes. Instead of defining abilities in a centralized DSL, Pundit encourages one policy class per model, each containing methods that return true or false for specific actions. This approach keeps authorization logic explicit, easy to test, and close to the domain objects it protects. ## What Pundit Does - Maps controller actions to policy methods that determine whether a user can perform a given operation - Provides scoping via policy scopes that filter database queries to return only records the user is allowed to see - Raises a clear error when authorization is missing, ensuring no controller action accidentally skips access checks - Generates policy and spec files from the command line to maintain consistent structure - Works with any authentication system including Devise, Clearance, or custom solutions ## Architecture Overview Pundit relies on naming conventions: for a `Post` model, it looks up `PostPolicy`. Each policy class receives the current user and the record being authorized. Action methods like `create?`, `update?`, and `destroy?` return booleans. Scopes are inner classes that receive the user and a base relation, returning a filtered ActiveRecord scope. The `authorize` helper in controllers instantiates the correct policy, calls the matching method, and raises `Pundit::NotAuthorizedError` if it returns false. A verify_authorized callback can be added to ensure every action calls authorize. ## Self-Hosting & Configuration - Install the gem and run the generator to create `app/policies/application_policy.rb` as the base class - Include `Pundit::Authorization` in ApplicationController or specific controllers - Create one policy file per model under `app/policies/` with methods matching controller actions - Use `after_action :verify_authorized` to catch actions that forget to call authorize - Define policy scopes as inner `Scope` classes for index actions and relation-based filtering ## Key Features - Pure Ruby classes with no DSL magic, making policies easy to read, test, and debug - One policy per model keeps authorization logic organized and predictable - Policy scopes integrate with ActiveRecord to filter queries at the database level - Framework-agnostic core that works with Rails, Sinatra, or any Ruby application - Built-in helpers for view-layer authorization checks via the `policy` helper method ## Comparison with Similar Tools - **CanCanCan** — centralized Ability class with a DSL; Pundit distributes logic across individual policy classes for better maintainability - **Action Policy** — inspired by Pundit with additional features like caching and scoping; Pundit is simpler and more widely adopted - **Rolify** — role management library; complements Pundit by providing roles that policies can check against - **Casbin** — policy engine with model-based access control; Pundit is Ruby-specific and uses plain code instead of policy languages - **Authorizr (Go)** — similar concept for Go; Pundit serves the Ruby ecosystem with tight Rails integration ## FAQ **Q: How do I handle different user roles?** A: Check role attributes directly in policy methods (e.g., `user.admin?` or `user.role == :editor`). Combine with Rolify for more complex role hierarchies. **Q: Can I use Pundit outside of Rails?** A: Yes. Pundit works with any Ruby application. You need to provide the current user and call `authorize` manually without the Rails controller integration. **Q: How do I test Pundit policies?** A: Pundit policies are plain Ruby objects. Instantiate them in tests with a user and record, then assert the return values of action methods directly. **Q: What happens if I forget to authorize an action?** A: Adding `after_action :verify_authorized` raises `Pundit::AuthorizationNotPerformedError` for any action that did not call `authorize`, preventing accidental open access. ## Sources - https://github.com/varvet/pundit - https://www.rubydoc.info/gems/pundit --- Source: https://tokrepo.com/en/workflows/asset-2cefc35b Author: Script Depot