verify_authorized

It’s easy to forget to add authorize! to a controller action. Action Policy provides a safety net: verify_authorized.

The Problem

Imagine you add a new action and forget to authorize it:

def special_action
@products = Product.where(special: true)
# Oops! Forgot authorize!
end

This action is now unprotected. Anyone can access it!

The Solution: verify_authorized

Add verify_authorized to your ApplicationController:

class ApplicationController < ActionController::Base
verify_authorized
rescue_from ActionPolicy::Unauthorized do |exception|
redirect_to root_path, alert: "You are not authorized to perform this action."
end
end

Now, if any action completes without calling authorize!, Rails raises ActionPolicy::UnauthorizedAction.

How It Works

After every action, Action Policy checks whether authorize! was called:

  • If called: Action proceeds normally
  • If not called: Raises ActionPolicy::UnauthorizedAction

This ensures you never accidentally ship an unprotected action.

Skipping Verification

Some actions legitimately don’t need authorization (like public landing pages). You can skip the check:

class PagesController < ApplicationController
skip_verify_authorized only: [:home, :about]
def home
# No authorization needed for public pages
end
def about
end
end

Or skip dynamically within an action:

def public_action
skip_verify_authorized!
# Action logic...
end

Filtering by Action Type

You can limit verification to specific actions:

class ApplicationController < ActionController::Base
# Only verify write operations
verify_authorized except: [:index, :show]
end

Try It Out

Let’s test this safety net:

  1. First, make sure verify_authorized is in your ApplicationController

  2. Let’s temporarily remove authorization from the index action in ProductsController:

def index
@products = Product.all
authorize! @products
end
  1. Try visiting the products page in the Preview

You should see an error because we forgot to authorize!

  1. Add the authorize! call back:
def index
@products = Product.all
authorize! @products
end

Best Practice

Always add verify_authorized to your ApplicationController. It’s a simple safeguard that prevents security holes.

class ApplicationController < ActionController::Base
verify_authorized
rescue_from ActionPolicy::Unauthorized do |ex|
redirect_to root_path, alert: "You are not authorized."
end
rescue_from ActionPolicy::UnauthorizedAction do |ex|
# This should never happen in production!
# It means a developer forgot to add authorization.
raise ex if Rails.env.development?
redirect_to root_path, alert: "An error occurred."
end
end

Now we have a solid foundation for authorization. In the next section, we’ll explore advanced policy features!

Powered by WebContainers
Files
Preparing Environment
  • Preparing Ruby runtime
  • Prepare development database
  • Starting Rails server