class

KemalIdentity::Authz::RoleCatalog

Inherits Reference < Object

The roles this application defines, checked against the permissions it declares.

Roles are code; only assignments are data

The catalog is built at boot from literals in the application, and the database holds only who has which role. It would have been easy to put the role-to-permission mapping in a table too, and every general-purpose RBAC library does. This one does not, for two reasons.

A role definition in a table is a privilege-escalation surface. An UPDATE — through an injection, an over-permissive admin screen, a restored backup from before a permission was tightened — silently rewrites what everybody holding that role can do, and nothing about the application changed. In code the same change is a diff somebody reviews.

A missing permission becomes a boot failure instead of a mystery. Renaming invoices.refund and forgetting one role definition raises here, on the machine of whoever made the change, rather than denying an action in production for a month.

An application that genuinely needs roles administered at runtime is not blocked: it implements Authorizer directly against its own tables. What it does not get is this shard pretending that a mutable table of grants is the same security property as a reviewed one.

Constructors

new(registry : PermissionRegistry, roles : Enumerable(Role))
Source

Instance methods

[]?(name : String) : Role | Nil
Source
defined?(name : String) : Bool
Source
grants?(role_names : Enumerable(String), permission : String) : String | Nil

Whether any of role_names grants permission.

A name with no matching role contributes nothing. That is not an oversight: assignments outlive the code that defined the role — somebody deletes beta_tester from the catalog and the rows stay — and the safe reading of a role nobody defines is that it grants nothing. #undefined_roles exists so an application can find those rows and clean them up, rather than discovering them by their absence.

Source
names
Source
registry
Source
undefined_roles(role_names : Enumerable(String)) : Array(String)

The names in role_names this catalog does not define. For a boot-time or nightly check that assignments still refer to roles that exist.

Source