CodamAIDocs
Topicdone

Permissions on relations (field roles)

A field role on a relation allows reading or writing a child model through exactly one field, without direct access to the child model. On simple fields a role works differently: as an additional condition.

Variants
field role instead of class roleonly through this fieldno direct endpointone level only, this operation onlyon simple fields: additional condition

What this is about

Picture a vault vault with notes note. A person should see the notes of a vault when they read the vault. But they should not be able to search all notes through /note/query.

Model roles alone cannot do that: the read role of note always opens the own endpoint of note as well. That is what field roles are for. A field role is attached to a relation, here the field vault.notes, and is named e.g. vault-notes-read.

Two paths to the same child

flowchart LR
    P(["Person with vault-read<br/>and vault-notes-read"])
    P -->|"POST /vault/read/{id}<br/>response: notes"| V["vault"]
    V -->|"through the field notes:<br/>vault-notes-read is enough"| N["note"]
    P -.->|"POST /note/query<br/>requires note-read"| X["403"]
PathWhat CDMS checksResult with vault-read and vault-notes-read
through the vault: POST /vault/read/{id} with notes in the responserole of vault, then field role or read role of note200 with notes
directly: POST /note/queryread role of note403 `missing-permission

When the field role counts

When a request descends through a relation into another model, CDMS checks two things. One of them is enough:

May the request access note through vault.notes?
field role on vault.notes for this operationrole of note for this operationResult
yes–allowed through the field
noyesallowed through the role of the child model
nono403 missing-permission|vault-notes-<operation>
no field role defined on the fieldno403 missing-permission|<role of note>

The operation has to match exactly:

Operation on the childField role
read, including lists in the response…-read
create along with the parent…-create
change along with the parent, by PUT or PATCH…-update
delete along with the parent in a cascade…-delete

Variants

Field roles in the operations

When: response names notes

  1. 1
    CDMS
    checks the read role of vault and reads the vault
  2. 2
    CDMS
    vault-notes-read present → reads the notes without note-read
  3. 3
    CDMS→Database
    reads only notes that the filters of note let through

Result: The filters of the row level still apply. A field role does not make an invisible note visible.

When: POST /vault/create with new notes in notes

  1. 1
    CDMS
    checks the create role of vault
  2. 2
    CDMS
    vault-notes-create present → creates the notes without note-create
  3. 3
    CDMS
    reads the result back. If the response names the notes, the same applies as for reading: vault-notes-read or note-read

Result: Whoever has only vault-notes-create leaves the notes out of the response, otherwise the read-back fails. See Create and read back: STRICT or LENIENT.

When: DELETE /vault/delete/{id}, notes with DELETE flag

  1. 1
    CDMS
    checks the delete role of vault
  2. 2
    CDMS
    vault-notes-delete present → deletes the notes without note-delete
  3. 3
    CDMS
    if a note has dependent children of its own, each of them again needs its own role or a field role on the note's relation

Result: See Dependent objects (cascades).

How far a field role reaches

  • One level only. vault-notes-read applies to the notes, not to what hangs off a note. For the next level you again need the model’s role or a field role on the note’s relation.
  • This operation only. vault-notes-read does not allow changing along. For that you need vault-notes-update or note-update.
  • Different on simple fields. A role on a simple field such as note.text opens no way, it protects the value in addition to the role of the model. See Protected values.
  • Never the direct path. Even with all four vault-notes-… roles, every endpoint under /note/… returns 403 with the role of note.

Where you define field roles

In the hub, on the relation, you mark the operations that should have a field role. The generator builds the name: base role of the model, field name, operation. See How role names are built.

Pitfalls

Where to go next

Sources in the code and the knowledge base
  • CDMS/cdms-authorization – AbstractAuthorizationLayer (accessGrantedByField, fieldRole)
  • CDMS/cdms-system-layer – AbstractLayer (enterField, grantedByField, fetchAndSetModel, fetchAndSetList, recursiveDelete), FieldAccessContext
  • CDMS/cdms-generator – CdmsYamlLoader (field roles), DtoMetaProcessor, RoleRegistryProcessor
  • CDMS/cdms-integrationtest – AbstractFieldRoleTest (e.g. theFieldRoleDoesNotOpenTheChildsOwnApi)
  • CDMS/cdms-generator/docs/adr – ADR-011
Search