Legion::Rbac

Role-based access control for LegionIO, following Vault-style flat policy patterns.

Version: 0.3.2

Features

  • Flat policy model: deny-always-wins, no role inheritance
  • Glob pattern matching for resources (* any segments, + single segment)
  • Four built-in roles: worker, supervisor, admin, governance-observer
  • Team scoping with cross-team as explicit privilege
  • Two-layer enforcement: Rack middleware for API routes + authorize_execution! for all execution sources
  • Dual-mode store: DB-backed via Sequel or static fallback
  • Entra ID claims mapping (roles and groups to Legion roles)
  • Kerberos claims mapping (AD group DNs to Legion roles, with Entra fallback)
  • Rich identity profile from AD/LDAP (name, email, title, department, company, location)
  • Fully optional: guarded by if defined?(Legion::Rbac) in LegionIO

Installation

Add to your Gemfile:

gem 'legion-rbac'

Usage

Setup

require 'legion/rbac'
Legion::Rbac.setup

Authorization Check

principal = Legion::Rbac::Principal.new(id: 'user-1', roles: [:worker], team: 'team-a')
Legion::Rbac.authorize!(principal: principal, action: :execute, resource: 'runners/lex-http/request/get')

# Kerberos principals carry full AD profile
principal.first_name    # => "Jane"
principal.title         # => "Senior Engineer"
principal.department    # => "Platform Engineering"
principal.profile       # => { first_name: "Jane", last_name: "Doe", ... }

Execution Authorization

Legion::Rbac.authorize_execution!(principal: principal, runner_class: 'Legion::Extensions::LexHttp::Runners::Request', function: :get)

Capability Audit (Extension Security)

Audit an extension's source code for dangerous patterns and enforce capability declarations:

result = Legion::Rbac.audit_extension(
  extension_name: 'lex-codegen',
  source_path: '/path/to/lex-codegen/lib',
  declared_capabilities: [:shell_execute, :filesystem_write]
)
result.blocked?               # => false (all capabilities declared)
result.detected_capabilities  # => [:shell_execute, :filesystem_write]

# Query the capability registry
Legion::Rbac::CapabilityRegistry.for_extension('lex-codegen')
# => [:filesystem_write, :shell_execute]

Legion::Rbac::CapabilityRegistry.extensions_with(:shell_execute)
# => ["lex-codegen", "lex-exec"]

Capability Authorization

Check if a principal's role allows a specific capability:

Legion::Rbac.authorize_capability!(principal: principal, capability: :shell_execute, extension_name: 'lex-codegen')
# Raises AccessDenied if the principal's role denies shell_execute

Dry-Run Check

result = Legion::Rbac::PolicyEngine.evaluate(principal: principal, action: :read, resource: 'runners/*', enforce: false)
# => { allowed: true, reason: "...", would_deny: false }

CLI

legion rbac roles              # list role definitions
legion rbac show admin         # show role permissions
legion rbac assignments        # list role assignments from DB
legion rbac assign user-1 worker --team team-a
legion rbac check user-1 runners/lex-http/* --action execute --roles worker

Configuration

Default roles are defined in settings under rbac.roles. Custom roles can be added via settings merge or config files.

Requirements

  • Ruby >= 3.4
  • legion-json >= 1.2
  • legion-settings >= 1.3

License

Apache-2.0