|The policies for this section can be found on GitHub.|
The business requirements for Cerbforce state that only an owner of Contacts and Companies are allowed to delete them from the system. With Cerbos, the aim is to keep policies as simple as possible and not repeat logic across different resources, so in this situation, a Derived Role can enable help.
Derived roles are a way of augmenting the broad roles with are attached to the user in the directory of the authentication system with contextual data to provide more fine-grained control at runtime. On every request, all the relevant derived role policies are evaluated and those matching roles are 'attached' to the user as Cerbos computes access.
In the Cerbforce data model, the
company both have an attribute called
ownerId which is the ID of the user that created the record. Rather than adding a condition to both of these resource policies, you are going to create a derived role that gives the principal an additional
owner role within the context of the request. The policy for this is as follows:
--- apiVersion: "api.cerbos.dev/v1" description: |- Common dynamic roles used within the Cerbforce app derivedRoles: name: cerbforce_derived_roles definitions: - name: owner parentRoles: ["user"] condition: match: expr: request.resource.attr.ownerId == request.principal.id
The structure is similar to a resource policy but rather than defining actions with conditions, it defines roles that are an extension of the listed
parentRoles and can have any number of conditions as with resources.
With this derived role policy setup a resource can import them and then make use of them in rules eg:
--- apiVersion: api.cerbos.dev/v1 resourcePolicy: version: "default" resource: "contact" importDerivedRoles: - cerbforce_derived_roles rules: - actions: - create - read effect: EFFECT_ALLOW roles: - user - actions: - update - delete effect: EFFECT_ALLOW derivedRoles: - owner - actions: - "*" effect: EFFECT_ALLOW roles: - admin
Full documentation can be found here.