https://github.com/aserto-dev/aserto-ruby
Ruby Rack Middleware for Aserto
https://github.com/aserto-dev/aserto-ruby
Last synced: about 1 year ago
JSON representation
Ruby Rack Middleware for Aserto
- Host: GitHub
- URL: https://github.com/aserto-dev/aserto-ruby
- Owner: aserto-dev
- License: apache-2.0
- Created: 2022-06-30T11:49:51.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2024-03-25T09:37:22.000Z (about 2 years ago)
- Last Synced: 2024-04-28T02:04:18.694Z (about 2 years ago)
- Language: Ruby
- Homepage:
- Size: 139 KB
- Stars: 3
- Watchers: 5
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Aserto Ruby SDK
[](https://badge.fury.io/rb/aserto)
[](https://github.com/aserto-dev/aserto-ruby/actions/workflows/ci.yaml)
[](https://asertocommunity.slack.com
)
## Installation
Add to your application Gemfile:
```ruby
gem "aserto"
```
And then execute:
```bash
bundle install
```
Or install it yourself as:
```bash
gem install aserto
```
## Directory
The Directory APIs can be used to get or set object instances and relation instances. They can also be used to check whether a user has permission or relation on an object instance.
### Directory Client
You can initialize a directory client as follows:
```ruby
require 'aserto/directory/client'
directory_client = Aserto::Directory::V3::Client.new(
url: "directory.eng.aserto.com:8443",
tenant_id: "aserto-tenant-id",
api_key: "basic directory api key",
)
```
- `url`: hostname:port of directory service (_required_)
- `api_key`: API key for directory service (_required_ if using hosted directory)
- `tenant_id`: Aserto tenant ID (_required_ if using hosted directory)
- `cert_path`: Path to the grpc service certificate when connecting to the local topaz instance.
See [Aserto::Directory::V3::Client](https://rubydoc.info/gems/aserto/Aserto/Directory/V3/Client) for full documentation
## Authorizer
`Aserto::Authorization` is a middleware that allows Ruby applications to use Aserto as the Authorization provider.
### Prerequisites
* [Ruby](https://www.ruby-lang.org/en/downloads/) 3.0 or newer.
* An [Aserto](https://console.aserto.com) account.
### Configuration
The following configuration settings are required for the authorization middleware:
- policy_root
These settings can be retrieved from the [Policy Settings](https://console.aserto.com/ui/policies) page of your Aserto account.
The middleware accepts the following optional parameters:
| Parameter name | Default value | Description |
| -------------- | ------------- | ----------- |
| enabled | true | Enables or disables Aserto Authorization |
| policy_name | `""` | The Aserto policy name. |
| instance_label | `""` | The label of the active policy runtime. |
| authorizer_api_key | "" | The authorizer API Key |
| tenant_id | "" | The Aserto Tenant ID |
| service_url | `"localhost:8282"` | Sets the URL for the authorizer endpoint. |
| cert_path | `""` | Path to the grpc service certificate when connecting to local topaz instance. |
| decision | `"allowed"` | The decision that will be used by the middleware when creating an authorizer request. |
| logger | `STDOUT` | The logger to be used by the middleware. |
| identity_mapping | `{ type: :none }` | The strategy for retrieving the identity, possible values: `:jwt, :sub, :manual, :none` |
| disabled_for | `[{}]` | Which path and actions to skip the authorization for. |
| on_unauthorized | `-> { return [403, {}, ["Forbidden"]] }`| A lambda that is executed when the authorization fails. |
### Identity
To determine the identity of the user, the middleware can be configured to use a JWT token or a claim using the `identity_mapping` config.
```ruby
# configure the middleware to use a JWT token from the `my-auth-header` header.
config.identity_mapping = {
type: :jwt,
from: "my-auth-header",
}
```
```ruby
# configure the middleware to use a claim from the JWT token.
# This will decode the JWT token and extract the `sub` field from the payload.
config.identity_mapping = {
type: :sub,
from: :sub,
}
```
```ruby
# configure the middleware to use a manual identity.
config.identity_mapping = {
type: :manual,
value: "my-identity",
}
```
The whole identity resolution can be overwritten by providing a custom function.
```ruby
# 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, the middleware:
* 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 lowercase
This behaviour can be overwritten by providing a custom function:
```ruby
# 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 the authorization policy uses to evaluate decisions. By default, middleware does not include a resource in authorization calls.
This behaviour can be overwritten by providing a custom function:
```ruby
# config/initializers/aserto.rb
# must return a Hash
Aserto.with_resource_mapper do |request|
{ resource: request.path_info }
end
```
### Disable authorization for specific paths
The middleware exposes a `disable_for` configuration option that
accepts an array of hashes with the following keys:
- path - the path to disable authorization for
- actions - an array of actions to disable authorization for
#### Rails
You can find the paths and actions using `bundle exec rails routes`
```bash
bundle exec rails routes
Prefix Verb URI Pattern Controller#Action
api_v1_users GET /api/users(.:format) api/v1/users#index {:format=>:json}
POST /api/users(.:format) api/v1/users#create {:format=>:json}
api_v1_user GET /api/users/:id(.:format) api/v1/users#show {:format=>:json}
```
```ruby
# disables get user by id
config.disabled_for = [
{
path: '/api/users/:id'
actions: [:GET]
}
]
```
### Examples
#### Rails
```ruby
# config/initializers/aserto.rb
Rails.application.config.middleware.use Aserto::Authorization do |config|
config.enabled = true
config.policy_name = "my-policy-name"
config.instance_label = "my-instance"
config.authorizer_api_key = Rails.application.credentials.aserto[:authorizer_api_key]
config.policy_root = "peoplefinder"
config.service_url = "localhost:8282"
config.cert_path = "/path/to/topaz/cert.crt"
config.decision = "allowed"
config.logger = Rails.logger
config.identity_mapping = {
type: :sub,
from: :sub
}
config.disabled_for = [
{
path: "/api/users",
actions: %i[GET POST]
},
{
path: "/api/authentication",
actions: %i[POST]
}
]
config.on_unauthorized = lambda do |env|
puts env
return [403, {}, ["Forbidden"]]
end
end
```
#### Sinatra
```ruby
# server.rb
# aserto middleware
use Aserto::Authorization do |config|
config.enabled = true
config.policy_name = "my-policy-name"
config.authorizer_api_key = ENV['authorizer_api_key']
config.policy_root = "peoplefinder"
config.instance_label = "my-instance"
config.service_url = "localhost:8282"
config.cert_path = "/path/to/topaz/cert.crt"
config.decision = "allowed"
config.disabled_for = [
{
path: "/api/users/:id",
actions: %i[GET]
},
{
path: "/",
actions: %i[GET]
}
]
end
```
## Development
Prerequisites:
- Ruby >= 3.0 to run the code
Run `bundle install` to install dependencies. Then, run `bundle exec rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
## Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/aserto-dev/aserto-ruby. This project is intended to be a safe, welcoming space for collaboration.
## License
The gem is available as open source under the terms of the [Apache-2.0 License](https://www.apache.org/licenses/LICENSE-2.0).