Yes Auth
Authorization principals and Cerbos integration for the Yes event sourcing framework.
Overview
yes-auth provides ActiveRecord-backed authorization principal models and Cerbos principal data builders. It is designed to work with yes-core to provide role-based access control with fine-grained read and write resource access permissions.
Principal Models
- User - represents an authorization principal with roles and resource accesses
- Role - named roles that can be assigned to users and resource accesses
- ReadResourceAccess - links a principal to a role-based read permission scoped by service, scope, and resource type
- WriteResourceAccess - links a principal to a role-based write permission scoped by context and resource type
Cerbos Integration
- WriteResourceAccess::PrincipalData - builds Cerbos principal data from write resource accesses
- ReadResourceAccess::PrincipalData - builds Cerbos principal data from read resource accesses
Installation
Add to your Gemfile:
gem 'yes-auth'
Or if using a monorepo with path references:
gem 'yes-auth', path: 'yes-auth'
Auto-Configuration
When loaded in a Rails application, yes-auth automatically configures the Cerbos principal data builders in yes-core:
config.cerbos_principal_data_builder→Yes::Auth::Cerbos::WriteResourceAccess::PrincipalDataconfig.cerbos_read_principal_data_builder→Yes::Auth::Cerbos::ReadResourceAccess::PrincipalData
This means you don't need to manually configure these in your initializer — just adding yes-auth to your Gemfile is enough.
To override the default builders, set them explicitly in your initializer (after yes-auth's railtie runs):
Yes::Core.configure do |config|
config.cerbos_principal_data_builder = MyCustomPrincipalDataBuilder.method(:call)
end
Environment Variables
| Variable | Default | Description |
|---|---|---|
CERBOS_URL |
cerbos-cluster-ip-service:3593 |
Cerbos server address (set via yes-core config) |
Usage
Principal Models
# Find a user by identity
user = Yes::Auth::Principals::User.find_by(identity_id: 'user-uuid')
# Check roles
user.
user.
user.super_admin?
# Access resource permissions
user.read_resource_accesses
user.write_resource_accesses
Cerbos Principal Data
Build principal data for Cerbos authorization checks:
# For write operations
write_data = Yes::Auth::Cerbos::WriteResourceAccess::PrincipalData.call(
identity_id: 'user-uuid'
)
# => { id: 'identity-id', roles: ['manager'], attributes: { write_resource_access: { ... } } }
# For read operations
read_data = Yes::Auth::Cerbos::ReadResourceAccess::PrincipalData.call(
identity_id: 'user-uuid'
)
# => { id: 'identity-id', roles: ['viewer'], attributes: { read_resource_access: { ... } } }
Configuration
Plug into yes-core's Cerbos authorization by configuring the principal data builder:
# config/initializers/yes.rb
Yes::Core.configure do |config|
config.cerbos_principal_data_builder = Yes::Auth::Cerbos::WriteResourceAccess::PrincipalData
end
For read APIs that need read-scoped authorization:
Yes::Core.configure do |config|
config.cerbos_principal_data_builder = Yes::Auth::Cerbos::ReadResourceAccess::PrincipalData
end
Database Setup
Generate the required auth principal migrations:
rails generate yes:auth:install
This creates migrations for all principal tables. You can also generate them individually:
rails generate yes:auth:principals:user
rails generate yes:auth:principals:role
rails generate yes:auth:principals:user_role
rails generate yes:auth:principals:read_resource_access
rails generate yes:auth:principals:write_resource_access
Then run the migrations:
rails db:migrate
This creates the following tables:
auth_principals_users- stores user principals with identity and auth attributesauth_principals_roles- stores named rolesauth_principals_read_resource_accesses- stores read resource access recordsauth_principals_write_resource_accesses- stores write resource access records- A join table for the users-roles HABTM association with UUID foreign keys
Subscriptions
The auth principal read models are kept in sync via event subscriptions. Register them in your subscription setup (e.g., in a Rake task or initializer):
Yes::Auth::Subscriptions.call(subscriptions)
This subscribes builders for all four principal models to their respective authorization events (e.g., Authorization::PrincipalRoleAdded, Authorization::WriteResourceAccessAttributeChanged, etc.).
Development
cd yes-auth
bundle install
bundle exec rspec
Contributing
See the contributing guide for instructions on how to contribute to the Yes framework.
License
The gem is available as open source under the terms of the MIT License.