Skip to content
Salman Mahmud edited this page Aug 5, 2026 · 6 revisions

RailsIAM supports Rails 7.0 and newer. It ships with JWT based authentication out of the box. If your application already has an authentication system (such as Devise or a custom solution), RailsIAM can integrate with it as long as it has access to the authenticated user.

Add rails_iam to your gemfile and install the dependencies.

gem "rails_iam"

Next, you need to run the generator:

rails generate rails_iam:install

The installer generates config/initializers/rails_iam.rb and a migration under db/migrate. The primary key type is automatically inferred from your application.

If your application already have authentication, update the RailsIAM configuration before running rails db:migrate. This allows RailsIAM to associate roles and permissions with your existing user model instead of generating its own user table.

After running rails db:migrate, RailsIAM creates all required tables and exposes the corresponding Active Record models.

Before authorization can work, create some roles and permissions (e.g., from the Rails console). In production applications you'll typically expose administrative endpoints to manage roles and permissions with top level permission using the models provided by RailsIam. Building those management endpoints is intentionally outside the scope of this gem.

Now enable rails_iam in you application or base controller as follows:

class BaseController < ApplicationController
  rails_iam :authentication, :authorization

end

rails_iam :authentication will expose 3 endpoints for login (/auth/sign_in), logout(/auth/sign_out) and refresh token. (/auth/refresh). You can rename the route path from the configuration.

rails_iam :authorization enables declarative endpoint authorization through the authorize or authorize_resource macro.

class ProductsController < ApplicationController

  authorize permissions: "product:show", only: :show

  def show; end
end

Requests made by users with the required permission will receive 200 OK. Otherwise RailsIAM will throw 403 Forbidden.

By default, authorization failures return a JSON response with status 403 Forbidden. For traditional server-rendered Rails applications, override render_rails_iam_authorization_error to render an HTML response instead. See the Configuration section for details.

Integrate with existing auth solution:

If you already have devise, rails default authentication or your own implementation with jwt, before running migration command you need to tell the RailsIam which model you are using to authenticate user. Based on that configuration, RailsIam will map the association.

config.user_class = 'User' # or 'Account' or 'Member'

config.current_user_method = :current_user # or :current_account

# only if you use devise
config.authorization.config.authorization.excluded_controller_patterns = [ /\ADevise::/ ]

Then, you have to tell your authentication model to act as RailsIam user. Add following line in your auth model:

  class User < ApplicationRecord

    acts_as_rails_iam_user

  end

Then run your rails db:migrate command and restart your server.

You should also remove :authentication from your base controller

class BaseController < ActionController::Base
  rails_iam :authorization
end

RailsIAM exposes the following Active Record models

Model Purpose
RailsIam::User Used only when you use the built-in Rails IAM authentication system. If your application already has a auth model to authenticate user, this table is unnecessary and can safely be removed from the generated migration.
RailsIam::Role Stores roles with a unique name and optional description.
RailsIam::Permission Stores permissions with a unique code and optional description. The description can document the endpoint or feature the permission protects, making permissions easier to manage over time.
RailsIam::UserRole Join table that associates users with roles. A user may belong to one or more roles.
RailsIam::RolePermission Join table that associates roles with permissions. A role may have one or more permissions.
RailsIam::UserPermission Grants permissions directly to an individual user, independent of their assigned roles.
RailsIam::UserDeniedPermission Explicitly revokes a permission from an individual user, even if it is inherited through one of their roles. Denied permissions always take precedence.
RailsIam::RefreshToken Stores refresh tokens together with metadata such as token_digest, jti, expires_at, revoked_at, last_used_at, user_agent, and ip_address. The jti can be used to implement token rotation, revocation, or blacklisting strategies.

All the models has created_by updated_by deleted_at and deleted_by column to track audit.

Wildcard Permissions

A permission ending with :* (e.g., users:*) grants access to every permission within that namespace.

Similarly if a user is given * permission, he will have access to every endpoint based on your authorization rules.

Permission resolution

Permission sources are evaluated in this order: Role permissions, Direct user permissions and User denied permissions

Effective permission = (Role permission + Direct User permission) - Denied permission

Authorization Flow

HTTP Request
      │
      ▼
before_action
      │
      ▼
run_authorization!
      │
      ├── Skip authorization?
               │
               ▼
      ┌────────└── Yes → 200, Controller Action
      │
      ▼
      No
      │
      ├── Resolve authenticated user
               │
               ▼
      ┌────────└── No → Throw 401 Exception
      │
      ▼
     Yes
      │
      ├── Find matching authorization rules
      │        │
      │        ├── authorize(...)
      │        └── authorize_resource
      │
      ├── Evaluate rules (OR)
      │        │
      │        └── First successful rule wins
      │
      ▼
    Authorizer
      │
      ├── DeniedPermissionChecker
      │        │
      │        ├── Explicit deny found? ──► 403 Forbidden
      │        ▼
      │       No
      │
      ├── RoleChecker
      │
      └── PermissionChecker
               │
               ▼
        PermissionResolver
               │
      ┌────────┼────────┐
      │        │        │
      ▼        ▼        ▼
RolePermission UserPermission UserDeniedPermission
     Source        Source          Source
      └────────────┬────────────┘
                   ▼
      Build Effective Permission Set
             (cached per user)
                   │
         ┌─────────┴─────────┐
         ▼                   ▼
   Rule Satisfied      Rule Failed
         │                   │
         ▼                   ▼
 Controller Action     403 Forbidden

RailsIAM uses Rails cache storage to cache user permissions and authorization data.

The cache store and TTL are configurable through the RailsIAM configuration file. The default TTL is 15 minutes. Cached permissions are invalidated automatically when role or permission assignments change.

Clone this wiki locally