CodamAIDocs
Topicdone

The role catalog

What CIAS keeps for every role: key and client, owner module, scope, delegation, display group, retirement.

Variants
PLATFORMTENANTretired

What this is about

Keycloak only knows the name of a role. It does not know what the role is for, who may pass it on, and whether it applies to the whole platform or only in one tenant. CIAS keeps this knowledge in the role catalog: one row per role, with everything CIAS needs to know about it.

A catalog entry

Request
GET /cias/admin/roles/tenant-user?client=cias-backend
Catalog entry
{
  "client": "cias-backend",        ← client in Keycloak, empty = realm
  "key": "tenant-user",            ← name, exactly as in Keycloak
  "module": "cias",                ← which module registered it
  "scope": "TENANT",               ← applies in one tenant
  "displayName": "Tenant member",  ← what people read
  "description": null,             ← explanation for administration
  "group": "tenant",               ← display group in the user interface
  "assignableBy": ["tenant-admin", "platform-admin"],
  "deprecatedAt": null             ← set = retired
}
FieldMeaningCan be changed
client + keythe identity of the role, the same two values as in Keycloakno
modulethe module that registered the role. Empty for roles that nobody registeredno
scopePLATFORM or TENANT, see belowno
displayName, descriptionwhat people readyes
groupunder which heading a user interface shows the roleyes
assignableBywho may grant the role, see belowyes
deprecatedAtsince when the module no longer registers the roleonly by the reconciliation

The identity: client and key

A role is the pair of client and key, for example cdms-backend / model-editor. In Keycloak, a client is an application that requests or checks tokens. The key alone is not enough: two modules may both have a role model-editor, and those are two different permissions.

If the client is missing, it is a realm role: a role that applies to the whole platform in Keycloak. There are only a few of these, see The platform’s realm roles. What the levels mean in the token is described in Realm role, client role, organization role.

The scope: platform or tenant

The scope says how far a grant reaches. It is a security boundary and is set when the role is created.

The two scopes
PLATFORMTENANT
Reacheverywhere, follows the person into every tenantonly in one tenant
Grant names a tenantno, forbiddenyes, required
Who grantsonly a platform administratorplatform administrator, or whoever got the role delegated
How it is granted in Keycloakdirectly on the accountthrough the tenant's organization
Examplesplatform-admin, usertenant-admin, all roles that a module registers

With TENANT, the same person can be an administrator in one tenant and only a reader in another.

The scope cannot be changed. If a tenant role became a platform role, every grant that already exists would suddenly apply everywhere, without anything being visible on a single grant. An attempt ends with 400 cias.authorization.invalid-request.

Every role that a module registers gets the scope TENANT. Platform roles only come from the installation’s configuration. The reason is described in Modules register their roles.

The delegation: who may grant

assignableBy names the roles whose holders may grant this role. In the example above, everyone with tenant-admin may grant the role tenant-user.

  • Empty means: only a platform administrator. An empty list is a lock, not a free pass.
  • The list only names keys, no clients. A caller’s roles arrive in the token as a flat list of names. A client could not be checked there.
  • A platform role is never delegated, no matter what is in the list.

Delegation alone is not enough to grant. Whoever grants must also hold the role themselves. The full check is described in Grant a role.

Retired instead of deleted

If a module no longer registers a role, CIAS does not delete it but retires it: deprecatedAt gets a date and time.

active roleretired role
existing grantsapplystill apply, unchanged
new grantpossible409 cias.authorization.role-deprecated, also for platform administrators
revokepossiblepossible
in the “assignable” listyesno
role in Keycloakexistsstays

The date does not change on later reconciliations. It says when the role was withdrawn, not when CIAS last started. If the module registers the role again, it is active again, and the grants were never gone. More in Reconciliation with Keycloak.

The endpoints

CallWhoEffect
GET /cias/admin/roles (?scope=…)any signed-in personall roles
GET /cias/admin/roles/page?query=…&scope=…&page=…&size=…any signed-in personone page, with the total count
GET /cias/admin/roles/assignableany signed-in personthe roles that you may grant in principle
GET /cias/admin/roles/{key}?client=…any signed-in personone entry, otherwise 404
POST /cias/admin/rolesplatform administratorcreate an entry, 409 if it exists
PUT /cias/admin/roles/{key}platform administratorchange description, group, delegation
DELETE /cias/admin/roles/{key}?client=…platform administratorremove an entry

Creating an entry by hand does not create a role in Keycloak. A typo in the catalog should not create a permanent role in Keycloak. Roles of modules are created in Keycloak through the reconciliation. A role created by hand belongs to no module, so no module ever retires it either.

What the catalog does not know on purpose

  • Composite roles. Keycloak can build a role from other roles. That stays in Keycloak, because Keycloak decides anyway what ends up in the token. A second composition in CIAS would be a second answer, and it would lose.
  • Single permissions. A role does not carry a list of what it may do. Each module decides that itself, in CDMS for example per model and operation.

Pitfalls

Next

Sources in the code and the knowledge base
  • CIAS/cias-authorization – Role (ref, module, scope, displayName, description, group, assignableBy, deprecatedAt, isAssignableBy), RoleRef (client, key, realm), RoleScope (PLATFORM, TENANT)
  • CIAS/cias-authorization – RoleCatalogService (define, redescribe, undefine, list, page, listAssignable), RoleAdminController (/cias/admin/roles…), RoleView
  • CIAS/cias-authorization – V1__cias_authorization.sql, V2__two_part_role_identity.sql, V3__declared_role_group_and_deprecation.sql
  • CIAS/cias-authorization/docs/adr – ADR-018, ADR-023, ADR-027, ADR-031
Search