mod-roles-keycloak

mod-roles-keycloak

Overview

mod-roles-keycloak is a Spring-based module responsible for the following functionality:

  1. Role management

  2. Policy management

  3. Capability and capability set storage

  4. Permissions mapping to capabilities and capability sets

  5. Links management between roles and capability and capability sets

  6. Links management between users and capability and capability sets

  7. Keycloak role, policy management based on entities stored in mod-roles-keycloak

  8. Keycloak permission management based on existing relations between users and roles to capability and capability sets

  9. User folio-permissions for _self request

GitHub repository: https://github.com/folio-org/mod-roles-keycloak

API-Documentation: https://s3.amazonaws.com/foliodocs/api/mod-roles-keycloak/s/mod-roles-keycloak.html

Functionality

Role management

mod-roles-keycloak allows role management:

  1. A user can view, create, edit, and delete roles

  2. A user can assign and unassign roles to/from a user

Policy management

mod-roles-keycloak allows policy management:

  1. A user can view, create, edit, and delete policies for types: time, role, user

In current implementation, policies are created during the capability and capability set assignment to the role or user.

Policies created by users are not used in authorization processes.

A generated name for role policy would look like: Policy for role: {roleId}, for user: Policy for user: {userId}

Capability and capability sets

mod-roles-keycloak receives events with permission data from mgr-tenant-entitlements and transforms permission data into capabilities and capability sets:

Permission-Capability/CapabilitySet mapping algorithm

Reference roles (Loadable roles)

mod-roles-keycloak can store pre-defined roles as reference data and be populated through the Tenant Entitlement process.

Loadable role JSON file has the following format:

{ "roles": [ { "name": "{{role name}}", "description": "{{role description}}", "permissions": [ // list with Folio permission name ] } ] }

Reference data policies

mod-roles-keycloak can create a policy from reference data.

Policies JSON example:

{ "policies": [ { "id": "15f45670-1edf-441e-a247-51f6c000faa3", "name": "Business Hours", "type": "TIME", "source": "USER", "timePolicy": { "start": "2023-07-01T00:00:00", "expires": "2033-07-01T00:00:00", "logic": "POSITIVE", "monthStart": "1", "monthEnd": "12", "hourStart": "8", "hourEnd": "20" } } ] }

Permission migration

mod-roles-keycloak provides an API to migrate existing user permissions from mod-permissions and assign them to newly created roles with unique names, based on SHA1 hash from all contained permissions to this role.

Algorithm is described at User permissions migration.

Core models and entities

Role

Eureka introduces Role-Based Access Control.

Roles are now the main part of FOLIO’s access model after the move to the Eureka platform. Under the old Okapi setup, a user got a long list of individual permissions. Since the Sunflower release, Eureka uses role-based access control.

A role groups many capabilities (single permissions) or capability sets (permission sets) and is then linked to one or more users. All role data lives in Keycloak; the FOLIO side talks to it through mod-roles-keycloak.

 

Key terms

Term

Short definition

Term

Short definition

Capability / Permission

One atomic right, e.g. users.item.get.

Capability Set / Permission Set

Named list of capabilities.

Role

Container that holds capabilities or sets; never other roles.

Loadable role

Role shipped as reference data or role managed by the system and auto-loaded by the platform.

Role types

Type

Who creates it

Properties

Type

Who creates it

Properties

DEFAULT

System

Immutable, loadable, auto-updates when new capabilities appear.

REGULAR

Tenant admins (or any user with role-create)

Fully editable, can be deleted.

CONSORTIUM

Tenant admins (or any user with role-create)

Fully editable. Changes propagate automatically to all tenants. Can be deleted, and deletion will occur automatically across all tenants.

 

DEFAULT roles (system-provided)

  • Immutable – name and membership cannot change through UI or Roles API.

  • Self-updating (Loadable Roles)mod-roles-keycloak keeps each role in sync with its design: when new capabilities appear, it adds them automatically so the role always matches its intended list.

    • Example: a DEFAULT role already contains a permission that is defined in the module descriptor of Module X. If Module X is not yet enabled for the tenant, that permission is missing from the system. Once the Module X is enabled for the tenant, mod-roles-keycloak detects the new capability or capability set and immediately inserts it, bringing the role to its final shape.

     

REGULAR roles (tenant-defined)

  • Created and managed by staff with the role-create capability.

  • Fully mutable: rename, add/remove capability sets, or delete.

  • Keep them broad (e.g. OA Admin, Acquisition Administrator) to avoid many near-duplicate roles.

  • Changes become active immediately; just refresh the page.

 

CONSORTIUM

  • Created and managed by staff with the role-create capability.

  • Fully mutable: rename, add/remove capability sets, or delete(changes are automatically applied in all tenants)

  • Changes propagate asynchronously to all tenants

  • The role ID for the same role can be different across tenants because Keycloak only supports autogenerated IDs

 

A role in Keycloak is a fundamental building block used for access control and authorization within the Keycloak identity and access management system. Roles define a set of permissions or capabilities that can be assigned to users or groups to regulate their access to resources and functionalities within an application or system. By assigning roles, administrators can manage user permissions in a scalable and organized manner, ensuring that users have the appropriate level of access required to perform their duties while maintaining security and compliance.

Property

Type

Description

Property

Type

Description

id

UUID

A unique identifier for this role

name

String

A human-readable name/label for this role

description

String

A free form description of the role

type

String (enum)

Role type

One of DEFAULT, REGULAR, CONSORTIUM

metadata

metadata

System-generated metadata (createdBy, updatedBy, createdDate, updatedDate)

User-Role

Describes a relation between user and role.

Property

Type

Description

Property

Type

Description

userId

UUID

A user identifier

roleId

UUID

A role identifier

metadata

metadata

System-generated metadata (createdBy, updatedBy, createdDate, updatedDate)

Policy

A policy in Keycloak is a set of rules and conditions used to determine whether a user or group is authorized to access a particular resource or perform a specific action within an application or system. Policies are key to Keycloak's authorization services, enabling fine-grained access control by evaluating attributes, roles, and other contextual information to make dynamic access decisions. By defining policies, administrators can implement complex access control mechanisms beyond simple role-based access control (RBAC), incorporating attributes and environmental conditions into the authorization process.

Property

Type

Description

Property

Type

Description

id

UUID

A unique identifier for this policy. System-generated if not provided.

name

String

A human-readable name/label for this policy. Required.

description

String

Free form description of the policy. Optional.

type

String (enum)

The type of policy. Required.

One of USER, TIME, ROLE

source

String

The type of policy. Required.

One of SYSTEM, USER, CONSORTIUM

userPolicy

user_policy

An object containing the details of the user-based policy

timePolicy

time_policy

An object containing the details of the time-based policy

rolePolicy

role_policy

An object containing the details of the role-based policy

metadata

metadata

System-generated metadata (createdBy, updatedBy, createdDate, updatedDate)

Capability

A capability represents a specific functionality or access right within a system that allows users to perform certain actions or access particular resources. Capabilities are derived from permissions in the module descriptor, which define the rights required to execute a given functionality. By encapsulating permissions into capabilities, systems can manage and control user access more effectively, ensuring that only authorized users can perform sensitive operations or access restricted data.

Property

Type

Description

Property

Type

Description

id

UUID

A unique identifier for this capability

name

String

A human-readable name/label for this capability.
Takes the form of {resourceName}.{action}, e.g. item.create or fiscal_year.view

description

String

Free-form description of the capability

resource

String

The resource this capability is associated with
for example item or fiscal_year

action

String (enum)

Еhe action this capability is associated with.
One of the following: View, Edit, Create, Delete, Manage, Execute

type

String (enum)

The type of capability.
One of the following: Settings, Data, Procedural

permission

String

Source folio permission name
for example item.get or fiscal_year.put

applicationId

String

The id of the application which defines the capability
for example app-platform-minimal-1.0.0

moduleId

String

The id of the module which defines the capability
for example mod-roles-keycloak-1.0.0

endpoints

Endpoint[]

List of associated endpoint with.
Endpoint is HTTP method + static path (path pattern or path from RoutingEntry)
for example Endpoint(GET, '/capabilities/{id}

metadata

metadata

System-generated metadata
createdBy, updatedBy, createdDate, updatedDate

Capabilities with type equal to Data usually have the following scopes: View, Edit, Create, Delete, Manage

The name for such capabilities is usually a noun: Fiscal Year, Instance Item, Instance Collection

Capabilities with type Procedural have action Execute

The name for such capabilities is usually more description and can be a verb: Orders-Storage Audit-Outbox Process, UI-Export-Manager Jobs Download-And-Resend

Capability Set

A CapabilitySet is a collection of related capabilities grouped to define a broader range of functionalities or access rights within a system. By uniting multiple capabilities into a single set, a CapabilitySet allows for more efficient and organized user permissions management, making assigning and controlling access based on roles, tasks, or specific use cases easier. This approach simplifies the process of granting users the necessary rights to perform various related actions without having to manage each capability individually.

CapabitySet can only include other capabilities and does not support hierarchical assignment.
During the processing of incoming permissions all permission sets with subpermissions are mapped to the capabilitySets with flattened list of found capabilities by permission names.

An additional table permissions stores source information about permissions (which can duplicates part of data from mod-permissions)

For UI permissions sets, to store a source permission name → an additional technical capability is created to store source permission name and other permissions are flattened and attached to the new CapabilitySet

Property

Type

Description

Property

Type

Description

id

UUID

A unique identifier for this capability

name

String

A human-readable name/label for this capability.
Takes the form of {resourceName}.{action}, e.g. item.create or fiscal_year.view

description

String

Free-form description of the capability

resource

String

The resource this capability is associated with
for example item or fiscal_year

action

String (enum)

Еhe action this capability is associated with.
One of the following: View, Edit, Create, Delete, Manage, Execute

type

String (enum)

The type of capability.
One of the following: Settings, Data, Procedural

permission

String

Source folio permission name
for example item.get or fiscal_year.put

applicationId

String

The id of the application which defines the capability
for example app-platform-minimal-1.0.0

moduleId

String

The id of the module which defines the capability
for example mod-roles-keycloak-1.0.0

capabilities

UUID[]

List with assigned capability ids.

metadata

metadata

System-generated metadata
createdBy, updatedBy, createdDate, updatedDate

Role-Capability

Property

Type

Description

Property

Type

Description

roleId

UUID

Role identifier

capabilityId

UUID

Capability identifier

metadata

metadata

System-generated metadata
createdBy, updatedBy, createdDate, updatedDate

Relation between capability and role.

Creating a relation between capability and role will result in the following permissions will be created in Keycloak:

# mod-roles-keycloak Capability("{{capabilityId}}", "foo.item.view", "/foo/item/{id}") Role("{{roleId}}", "Foo Role") create RoleCapability("{{roleId}}", "{{capabilityId}}") # keycloak (client = {{tenant}}-application) GET access for role '{{roleId}}' to '/foo/item/{id}'

Each permission is stored in an atomic way and each permission unites 3 entities: