What this is about
Every request to CDMS has to pass several questions before any data flows. The questions sit on three levels:
| Level | Question | How CDMS answers it |
|---|---|---|
| Model | May you run this operation on this model? | with a role in the token, e.g. hr-employee-read |
| Relation | May you go through this field into another model? | with the role of the other model or a field role on the relation |
| Row | May you see or change exactly this object? | with filters: own data, attribute filters, custom filters of the project |
A role is a name like hr-employee-read that is in the person’s token. A filter is a condition that CDMS invisibly adds to every query, for example “only rows of this person”.
The funnel
Before the three levels comes the tenant. It is not a check inside CDMS. It decides which database CDMS searches in the first place.
flowchart TB
T["Token and tenant<br/>CIAS checks the token, picks the tenant"] --> M
M["Model<br/>role for the operation?"] --> B
B["Relation<br/>role of the target model or field role?"] --> Z
Z["Row<br/>own data, attribute filters, custom filters"] --> D["Data"]
T -. "no token or invalid token" .-> E1["401 / 403"]
M -. "role missing" .-> E2["403"]
B -. "role missing" .-> E3["403"]
Z -. "row invisible" .-> E4["404 or missing from the list"]
What happens before CDMS, meaning checking the token and picking the tenant, is described in Access without a token and Tenants.
The levels when reading
-
CDMSModelDo you have the read role of
employee?↳ no 403missing-permission|<read role> -
CDMSRowDo the filters of
employeelet this row through?↳ no 404not-found -
CDMSRelationThe
responsenamescompany. Do you have the read role ofcompanyor the field role onemployee.company?↳ no 403missing-permission|<role> -
CDMSRow of the companyDo the filters of
companylet the company through?↳ nocompanyisnull, no error - 200 with employee and company
Searching works the same way, except that invisible rows are simply missing from the list. See Filters that always run along.
The levels when changing and deleting
When writing, the order is different: CDMS checks the row first, then the role.
-
CDMSRowDoes the row exist, and do the filters let it through? The same filters as for reading.↳ no 404
not-found|<Dto>|<id> -
CDMSModelDo you have the update role of
employee?↳ no 403missing-permission|<update role> -
CDMSRelationDoes the request also change a child? Then you need its role or the field role.↳ no 403
missing-permission|<role> - 200, changed and read back
This way CDMS does not reveal whether someone else’s object exists: whoever may not see it gets 404, no matter which roles they have. See Why invisible objects return 404.
The levels compared
- applies only to the path through this field
- missing → 403
- Details: Field roles
- applies to single objects
- invisible → 404 or missing from the list
- Details: Own data, Attribute filter, Custom filters
Simple fields have no level of their own. Whoever may read a model may read its simple fields, unless a field carries a role of its own. Then they also need this role, otherwise the field is missing from the response. See Protected values.
Variants
When: read, query
-
1CDMSchecks the read role of the model
-
2CDMS→Databasereads only rows that pass all filters
-
3CDMSchecks, for each relation in the
response, the role of the target model or the field role
Result: Role missing → 403. Invisible → 404 when reading by id; in a search the row is missing.
When: PUT, PATCH, DELETE, rollback
-
1CDMS→Databasecounts the row with the filters used for reading
-
2CDMSchecks the role of the model for the operation
-
3CDMSchecks, for each child that is changed or deleted along with it, its role or the field role
Result: First 404, then 403. You do not need a read role for this.
When: create
-
1CDMSchecks the create role of the model
-
2CDMSchecks, for each child created along with it, its role or the field role
-
3CDMSreads the new object back, which needs the read role
Result: The row level only checks during the read-back here. For user models CDMS sets the owner itself, see Own data.
Pitfalls
Where to go next
- Which role each operation requires: Model roles
- How the names are built: How role names are built
- Permissions through a relation: Permissions on relations (field roles)
- What happens with a missing role without strict mode: Strict mode