This example models a simplified version of Google Docs style permission system where users can be granted direct access to a document, or access via organizations and nested groups.
org: Represents organization that document belongs to.
manager: A relationship between users who are authorized to manage the document. This relationship is defined by the @user annotation on both ends, and by the @group#member and @group#manager annotations on the ends corresponding to the group member and manager relations.
viewer: A relationship between users who are authorized to view the document. This relationship is defined by the @user annotation on one end and the @group#member and @group#manager annotations on the other end corresponding to the group entity member and manager relations.
manager: A relationship between users who are authorized to manage the group. This relationship is defined by the @user annotation on both ends, and by the @group#member and @group#manager annotations on the ends corresponding to the group entity member and manager.
direct_member: A relationship between users who are members of the group. This relationship is defined by the @user annotation on one end and the @group#member and @group#manager annotations on the other end corresponding to the group entity member and manager.
group: A relationship between the organization and its groups. This relationship is defined by the @group annotation on the end corresponding to the group entity.
document: A relationship between the organization and its document. This relationship is defined by the @document annotation on the end corresponding to the group entity.
administrator: A relationship between users who are authorized to manage the organization. This relationship is defined by the @user annotation on both ends, and by the @group#member and @group#manager annotations on the ends corresponding to the group entity member and manager.
direct_member: A relationship between users who are directly members of the organization. This relationship is defined by the @user annotation on the end corresponding to the user entity.
The organization entity has two permissions defined:
admin: An permission that can be performed by users who are authorized to manage the organization, as determined by the administrator relationship.
member: An permission that can be performed by users who are directly members of the organization, or who have administrator relationship, or who are members of groups that are part of the organization.
Based on our schema, let’s create some sample relationships to test both our schema and our authorization logic.
Copy
// Assign users to different groupsgroup:tech#manager@user:ashleygroup:tech#direct_member@user:davidgroup:marketing#manager@user:johngroup:marketing#direct_member@user:jennygroup:hr#manager@user:joshgroup:hr#direct_member@user:joe// Assign groups to other groupsgroup:tech#direct_member@group:marketing#direct_membergroup:tech#direct_member@group:hr#direct_member// Connect groups to organizationorganization:acme#group@group:techorganization:acme#group@group:marketingorganization:acme#group@group:hr// Add some documents under the organizationorganization:acme#document@document:product_databaseorganization:acme#document@document:marketing_materialsorganization:acme#document@document:hr_documents// Assign a user and members of a group as administrators for the organizationorganization:acme#administrator@group:tech#managerorganization:acme#administrator@user:jenny// Set the permissions on some documentsdocument:product_database#manager@group:tech#managerdocument:product_database#viewer@group:tech#direct_memberdocument:marketing_materials#viewer@group:marketing#direct_memberdocument:hr_documents#manager@group:hr#managerdocument:hr_documents#viewer@group:hr#direct_member
According what we have defined for the edit action managers and admins, of the organization that document belongs, can edit product database. In this context, Permify engine will check does subject user:ashley has any direct or indirect manager relation within document:product_database. Consecutively it will check does user:ashley has admin relation in the Acme Org - organization:acme#document@document:product_database.
Ashley doesn’t have any administrative relation in Acme Org but she is the manager in group tech (group:tech#manager@user:ashley) and we have defined that manager of group tech is manager of product_database with the tuple (document:product_database#manager@group:tech#manager). Therefore, the user:ashley edit document:product_database check request should yield true response.
Copy
entity document { relation org @organization relation viewer @user @group#direct_member @group#manager relation manager @user @group#direct_member @group#manager action edit = manager or org.admin action view = viewer or manager or org.admin}
According what we have defined for the view action viewers or managers or org.admin’s can view hr documents. In this context, Permify engine will check whether subject user:joe has any direct or indirect manager or viewer relation within document:hr_documents. Also consecutively it will check does user:joe has admin relation in the Acme Org - organization:acme#document@document:hr_documents.
Joe doesn’t have administrative role/relation in Acme Org.
Also he doesn’t have have manager relationship in that document or within any entity.
But he is member in the hr group (group:hr#member@user:joe) and we defined hr members have viewer relationship in hr documents (document:hr_documents#viewer@group:hr#member). So that, this enforcement should yield true response.
Copy
entity document { relation org @organization relation viewer @user @group#direct_member @group#manager relation manager @user @group#direct_member @group#manager action edit = manager or org.admin action view = viewer or manager or org.admin}
According what we have defined for the view action viewers or managers or org.admin’s can view hr documents. In this context, Permify engine will check does subject user:david has any direct or indirect manager or viewer relation within document:marketing_materials. Also consecutively it will check does user:david has admin relation in the Acme Org - organization:acme#document@document:marketing_materials.
Similar Joe and Ashley, David also doesn’t have administrative role/relation in Acme Org.
Also David doesn’t have member or manager relationship related with marketing group - document:marketing_materials. So that, this enforcement should yield false response.
Let’s test these access checks in our local with using permify validator. We’ll use the below schema for the schema validation file.
After cloning Permify, open up a new file and copy the schema yaml file content inside. Then, build and run Permify instance using the command make serve.
Then run permify validate {path of your schema validation file} to start the test process.
The validation result according to our example schema validation file: