Skip to main content

Aserto Rails

Aserto authorization library for Ruby and Ruby on Rails.

Built on top of aserto and ruby-authorizer.

Prerequisites

Installation

Add to your application Gemfile:

gem "aserto-rails"

And then execute:

bundle install

Or install it yourself as:

gem install aserto-rails

Configuration

The following configuration settings are required for authorization:

  • policy_id
  • tenant_id
  • authorizer_api_key
  • policy_root

These settings can be retrieved from the Policy Settings page of your Aserto account.

Optional parameters:

Parameter nameDefault valueDescription
service_url"authorizer.prod.aserto.com:8443"Sets the URL for the authorizer endpoint.
decision"allowed"The decision that will be used when executing an authorizer request.
loggerSTDOUTThe logger to be used.
identity_mapping{ type: :none }The strategy for retrieveing the identity, possible values: :jwt, :sub, :none

Identity

To determine the identity of the user, the gem can be configured to use a JWT token or a claim using the identity_mapping config.

# configure the gem to use a JWT token form the `my-auth-header` header.
config.identity_mapping = {
type: :jwt,
from: "my-auth-header",
}
# configure the gem to use a claim from the JWT token.
# This will decode the JWT token and extract the `sub` field from payload.
config.identity_mapping = {
type: :sub,
from: :sub,
}

The whole identity resolution can be overwritten by providing a custom function.

# config/initializers/aserto.rb

# needs to return a hash with the identity having `type` and `identity` keys.
# supported types: `:jwt, :sub, :none`
Aserto.with_identity_mapper do |request|
{
type: :sub,
identity: "my custom identity",
}
end

URL path to policy mapping

By default, when computing the policy path:

  • converts all slashes to dots
  • converts any character that is not alpha, digit, dot or underscore to underscore
  • converts uppercase characters in the URL path to lowercases

This behavior can be overwritten by providing a custom function:

# config/initializers/aserto.rb

# must return a String
Aserto.with_policy_path_mapper do |policy_root, request|
method = request.request_method
path = request.path_info

"custom: #{policy_root}.#{method}.#{path}"
end

Resource

A resource can be any structured data that the authorization policy uses to evaluate decisions. By default, gem do not include a resource in authorization calls.

This behavior can be overwritten by providing a custom function:

# config/initializers/aserto.rb

# must return a Hash
Aserto.with_resource_mapper do |request|
{ resource: request.path_info }
end

Examples

# config/initializers/aserto.rb
require "aserto/rails"

Aserto.configure do |config|
config.enabled = true
config.policy_id = "my-policy-id"
config.tenant_id = "my-tenant-id"
config.authorizer_api_key = Rails.application.credentials.aserto[:authorizer_api_key]
config.policy_root = "peoplefinder"
config.service_url = "authorizer.prod.aserto.com:8443"
config.decision = "allowed"
config.logger = Rails.logger
config.identity_mapping = {
type: :sub,
from: :sub
}
end

Controller helpers

The aserto_authorize! method in the controller will raise an exception if the user is not able to perform the given action.

def show
aserto_authorize!
@post = Post.find(params[:id])
end

Setting this for every action can be tedious, therefore the aserto_authorize_resource method is provided to automatically authorize all actions in a RESTful style resource controller. It will use a before action to load the resource into an instance variable and authorize it for every action.

class PostsController < ApplicationController
aserto_authorize_resource
# aserto_authorize_resource only: %i[show]
# aserto_authorize_resource except: %i[index]

def show
# getting a single post authorized
end

def index
# getting all posts is authorized
end
end

Check Permissions

The current user's permissions can then be checked using the allowed?, visible? and enabled? methods in views and controllers.

<% if allowed? :get, "/posts/:id", @post %>
<%= link_to "View", @post %>
<% end %>