What this is about
When people talk about “the permission matrix”, they often mean two different tables. They answer different questions, and only one of them lives in CIAS.
- Matrix A says how a permission is carried: is it a realm role, a client role, a role in a tenant, a group or an attribute? Where is it in the token? Who may grant it? That is CIAS.
- Matrix B says what a permission allows: may this role read this model, go through this field into another model, see this row? That is the application, in CodamAI usually CDMS.
The two matrices side by side
- Which roles exist, on which client?
- Does the grant apply globally or in one tenant?
- Where is the permission in the token?
- Who may grant it?
- Since when, until when?
- Which role does
employeeneed for reading? - Which role does the path through
employee.companyneed? - Which attribute narrows down which rows?
- What about own data?
Matrix A: how a permission is carried
A permission can be attached to a person in five ways. Each way ends up in a different place in the token.
| What is granted | Carrier | Place in the token | Applies | Who may grant |
|---|---|---|---|---|
| Platform administration, context switch | realm role | realm_access.roles | everywhere, in all modules | only a platform administrator |
| A module’s permission, in the whole installation | client role, granted globally | resource_access.<client>.roles | in all tenants without their own roles | only a platform administrator |
| A module’s permission, in exactly one tenant | client role, granted in the organization | organization.<alias>.resource_access.<client>.roles | only in this tenant | whoever the delegation allows, in their own tenant |
| Bundle across modules | group | at the places of the roles it contains | platform wide | platform administrator |
| Reach over rows | attribute | its own claim, such as projects | per person or per person and tenant | per tenant: whoever the attribute’s delegation allows. On the person: platform administrator |
A few terms:
- A realm role applies in the whole Keycloak realm, so to all modules at once. That is why realm roles are reserved for what spans modules, such as
platform-adminand the two context switch roles. A module never registers a realm role. - A client role belongs to the client of a deployment, such as
cdms-backend. So every role has a two-part name:cdms-backend/hr-employee-read. - Delegation is a list in the role catalog: whoever has one of these roles may pass the role on. Without delegation, only a platform administrator grants it.
Global or in the tenant
The interesting row is the third one. If a request runs under a dynamic tenant, and the person has roles of their own there, those roles replace the globally granted client roles. They are not added.
| Request's tenant dynamic? | Roles in the tenant present? | Effective client roles |
|---|---|---|
| no | – | the globally granted ones from resource_access.<client>.roles |
| yes | no | the globally granted ones |
| yes | yes | only the ones from the tenant, and of those only the ones of the own client. The global ones are dropped |
Realm roles are never affected. They always apply.
So that a globally granted client role does not silently do nothing, CIAS refuses it if the person’s home tenant is a dynamic tenant. The role then has to be granted in the tenant. The flow in detail is shown in Effective roles: global or in the tenant.
Attributes are permissions too
An attribute does not look like a permission, but it acts like one. projects = alpha, beta on the account means in CDMS: this person only sees rows of the projects alpha and beta. One more value is more reach, and * turns the filter off. That is why attributes belong in matrix A: CIAS keeps who may write them, and checks the ceiling on writing.
Matrix B: what a permission allows
Matrix B lives in the application’s model. For CDMS it is modeled in the hub and generated into the code.
| Question | Answered by | More |
|---|---|---|
May hr-employee-read read the model employee? | CDMS, model role | Model roles |
May the person go through the field employee.company into the company? | CDMS, field role | Field roles |
Which rows does someone with projects = alpha see? | CDMS, attribute filter | Attribute filter |
| Does someone see only their own data? | CDMS, owner filter | Own data |
CDMS only reads the token for this. It does not ask CIAS whether a role “should” have been granted.
Who answers which question?
-
CIASRole catalogDoes
cdms-backend/hr-employee-readexist? Who may grant it? -
CIASTokenIs the token valid? Which roles apply for this client and tenant?↳ no 401
-
CDMSModelDoes
hr-employee-readallow readingemployee?↳ no 403 - Data is delivered
Why CIAS has no model-operation matrix
You might think it would be handy if CIAS also knew that hr-employee-read may read the model employee. Then a CIAS screen could show everything at a glance. CIAS still deliberately does not keep this table:
- It would be a copy of every application’s permission model. Copies drift apart.
- On every difference the token would win, because CDMS checks the token and not CIAS. The CIAS screen would then show a wrong answer.
- Only the application knows what its roles mean. That is why it registers its roles with CIAS instead of CIAS inventing them.
Next
- Realm role, client role, organization role
- How a role gets from the code into the token
- The three levels at a glance: matrix B from CDMS’s point of view