CodamAIDocs
Topicdone

What a group is

A bundle of realm roles and client roles with members, managed by CIAS, kept in Keycloak as a marked copy.

Variants
realm roles in the groupclient roles of several modules in the groupgroup without rolesdefault group

What this is about

Imagine every new colleague in support needs the same ten roles, spread across CDMS, CRMS and the realm. You could grant each role one by one, for every person, and revoke each one again when they leave. Or you create the group support once, give it the ten roles, and make the colleague a member.

So a group is a bundle of roles with members. Whoever is a member gets all roles of the group. Whoever leaves the group loses them again.

The picture

flowchart LR
    subgraph C["CIAS (manages the group)"]
      direction TB
      G["Group support<br/>name, description<br/>default group: no"]
      R["Roles<br/>realm: user<br/>cdms-backend: customer-read, order-edit<br/>crms-backend: ticket-edit"]
      M["Members<br/>Anna, Ben, Chris …"]
      G --> R
      G --> M
    end
    subgraph K["Keycloak (holds the copy)"]
      KG["Group support in the realm<br/>cias-managed = true<br/>role mappings, members"]
    end
    C -- "writes the copy" --> K
    K -- "roles of the group" --> T["Token of every member"]

Read it like this: a group bundles roles and has members. CIAS writes both to Keycloak. Keycloak puts the roles of the group into the token of every member, exactly as if the person had received them one by one.

What belongs to a group

PartMeaning
keythe key, for example support. It never changes. In Keycloak the group has exactly this name. At most 128 characters
namewhat people read, for example “Support 1st Level”. If it is missing, CIAS uses the key. Only in CIAS; Keycloak shows the key
descriptionwhat the group is for. In Keycloak it is stored in the attribute description
rolesthe roles the group grants: realm roles and client roles of any number of modules. Each must be in the role catalog
membersthe people, by the ID of their user record in CIAS
defaultGroupwhether every new account automatically becomes a member, see The default group
syncStatewhether the copy in Keycloak matches the state in CIAS: SYNCHRONIZED or PENDING, see Reconciliation with Keycloak

Inside a group, a role is always named by client plus key, because the same key can be two different permissions on two clients. An empty client means: realm role. More on this in Realm role, client role, organization role.

The variants

What a group can carry

When: The group carries roles without a client, such as user or allowed-tenant-context-switch.

Realm roles end up in the token under realm_access.roles. They apply in every tenant, whatever its kind.

Result: works everywhere

When: The group carries cdms-backend: customer-read and crms-backend: ticket-edit.

This is exactly what groups are for: a job in a company does not stop at module boundaries. A composite role could not do this, it always lives on one client or in the realm. Client roles from a group end up under resource_access.<client>.roles.

Result: works as long as the tenant of the request carries no roles of its own, see Group roles under dynamic tenants

When: The group is created, the roles come later.

This is allowed. A group without roles gives nobody anything, even if it already has members.

Result: valid, grants nothing

When: defaultGroup is true.

Every account created from now on becomes a member. Anyone who already has an account stays as they are.

Result: see The default group

Platform wide and flat

A group has no tenant. It applies across the whole platform. Anna from nordbau and Ben from suedlogistik can be in the same group. Both get the same roles, but each uses them only on the data of their own tenant. The group does not connect the two. See Tenant, organization, group.

A group also has no subgroups. Every group stands on its own, and a person can be in several groups. If a person has a role through two paths, they simply have it, not twice.

Group, individual grant, grant in the tenant

Group
bundle with members
  • many roles at once, across modules
  • applies globally, without a tenant
  • no end date, no reason per person
  • managed only by the platform administrator
  • Whoever leaves the group loses all its roles
Individual global grant
one role, one person
  • a role with scope PLATFORM
  • with end date and reason
  • visible as a grant in CIAS
  • managed by the platform administrator
Grant in the tenant
one role in one tenant
  • a role with scope TENANT
  • applies only in this tenant
  • with end date and reason
  • a tenant administrator with delegation may do it too

Individual grants are covered in Grant a role.

Group or individual grant?
Do several people need the same bundle of roles?Should it apply in only one tenant?Does it need an end date per person?Use
–yes–a grant in the tenant, no group
–noyesan individual grant with validUntil
yesnonoa group
nononoan individual grant; a group is not worth it

Two systems, one fixed order

Every change to a group writes twice: to the CIAS database and to Keycloak. There is no shared transaction. That is why one fixed rule applies:

What happensOrderIf it breaks off in between …
giving something: create a group, add a role, add a memberCIAS first, then Keycloak… it is in CIAS but not yet in the token. The group is PENDING
taking something: remove a role, remove a member, delete a groupKeycloak first, then CIAS… the permission is already gone, the record is still there

So after an interruption there is always less permission left, never more. How a leftover PENDING gets caught up is described in Reconciliation with Keycloak.

Pitfalls

Next

Sources in the code and the knowledge base
  • CIAS/cias-authorization – Group, RoleRef, GroupSyncState, GroupView, GroupRoleView, GroupService
  • CIAS/cias-authorization – db/migration V4__cias_group.sql, V5__cias_group_default.sql
  • CIAS/cias-iam-api – GroupManagementPort; CIAS/cias-iam-keycloak – KeycloakGroupAdapter (attributes cias-managed, description)
  • CIAS/cias-authorization/docs/adr – ADR-017, ADR-031, ADR-034
Search