Field-Level Authorization in Remult
This lesson builds upon the foundational Authentication & Authorization article, so please review that if you haven’t yet. Now, let’s dive into adding fine-grained access control by managing authorization on a field-by-field basis within your entities.
Adding ownerId
Field with Controlled Updates
To start, we want each task to record the ownerId
, which tracks who created or owns the task.
Here’s how to add the ownerId
field to the Task
entity:
Setting allowApiUpdate: false
ensures that once set, the ownerId
cannot be modified through the API. This is useful for data fields you want to update only on the backend, while still allowing API updates for other fields.
Controlling Field Access by Role
With Remult, the allowApiUpdate
option lets you control which users or roles can update a specific field. For example:
This configuration restricts updates to users with the admin
role only. To see this in action, try signing in as “Alex” (non-admin) and “Jane” (admin), and notice how the ability to change the completed
status differs.
Tip: Try it out in the Admin UI
The same authorization rules apply to fields in the Remult Admin UI. You can experiment further by navigating to the Remult Admin UI
link, where you’ll see that updates follow the same API restrictions set in the code.
Conditional Authorization with Arrow Functions
Authorization can also be controlled using more dynamic conditions through arrow functions. For example, suppose we want either an admin
or the task owner
to be able to update the completed
field. We could define the field like this:
allowApiUpdate
is set to an arrow function that takes thetask
entity as a parameter.- Condition 1:
remult.isAllowed("admin")
checks if the current user has the “admin” role. If they do, they can update the field. - Condition 2:
task.ownerId === remult.user?.id
checks if the current user is the task owner by comparing theownerId
field in the task to the current user’s ID.
If either condition is true (i.e., the user is an “admin” or the task owner), the completed
field can be updated. If both are false, the update is blocked.
This conditional approach allows flexible, role-based, and ownership-based control over specific fields in an entity.
Allowing Updates Only on New Rows
Another useful pattern is to restrict updates to a field when a task is first created but disallow changes afterward:
This ensures the field is set initially but prevents further modifications.
Hiding Fields with includeInApi
The includeInApi
option allows you to prevent specific fields from appearing in the API response altogether. This is particularly useful for sensitive data like passwords or other restricted fields.
Versatile Options for includeInApi
Just like allowApiUpdate
, the includeInApi
option offers versatility. You can set it to true
, false
, specific roles, or an arrow function for dynamic control over who can access the field in the API response. This makes includeInApi
highly adaptable to various access requirements.
Examples:
-
Role-Based Access:
-
Conditional Access with an Arrow Function:
In this example:
- Admin Access: If the user has the “admin” role, they see the
privateNotes
field. - Owner Access: The task owner can also see
privateNotes
.
This flexibility with includeInApi
allows you to apply fine-grained control over which users can access specific data, enhancing security and providing precise control over your API’s data exposure.
Summary
By using allowApiUpdate
and includeInApi
, you have fine-grained control over which fields users can modify or view based on roles, data ownership, and custom conditions.
- Installing dependencies
- Starting http server