-
Notifications
You must be signed in to change notification settings - Fork 0
Home
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:installThe 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
endrails_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
endRequests 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
endThen 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
endRailsIAM 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.