Modeling Google Docs Access Management Using Permify
In this article, we will examine the Google Docs authorization model and implement it using Permify.
Introduction
Welcome to our in-depth exploration of the Google Docs authorization model. Collaboration lies at the heart of Google Docs, allowing multiple users to seamlessly collaborate on projects, share ideas, and edit documents in real-time. However, with such collaborative capabilities, it becomes essential to establish a robust authorization framework that ensures the right level of access is granted to the right individuals, groups, or organizations.
In this article, we will discuss the key components of the Google Docs authorization model, including entity, relations, and permissions. We will explore the various levels of access control available, ranging from view-only permissions to full editing capabilities. We will also delve into how this model, permissions, and access controls logic can be implemented using Permify.
By the end of this article, we want to help you understand how to use Permify effectively to set up the permission system in a documentation application.
Let's gain a deeper understanding of the Google Docs authorization model together.
Google Docs and Its Access Control
Google Docs is a powerful cloud-based document collaboration platform that enables users to create, edit, and share documents in real time. It provides robust access control features to ensure secure document sharing and collaboration.
And the platform offers a Relationship-Based Access Control that allows users to define who can access and interact with their documents. This permission system leverages the relationships between entities to determine access levels.
In Google Docs, users can assign different roles and permissions to individuals or groups for each document. Roles such as owner, editor, viewer, or commenter determine the level of access and actions allowed. Owners have full control over the document, editors can make changes, viewers can only view the document, and commenters can add comments. They can also specify whether others can view, comment, or edit the document. Additionally, document owners can revoke or modify permissions at any time.
The use of ReBAC and the permission system in Google Docs provides a flexible and granular approach to access control. It allows users to collaborate effectively while maintaining control over their documents and ensuring data security.
Implementation with Permify
The very first step to building an Authorization model with Permify is defining and creating entities using Permify Schema.
Defining Entities & Relations between them
If we carefully analyze and look into the permission system (especially the sharing settings) of the Google Docs platform, we would realize that the following four (4) entities are involved:
-
Document entity represents the file or digital content being created, stored, and shared. It has a relation to represent the organization the document belongs to, the viewer of the document, and the manager of the document.
-
User entity represents a user in the system.
-
Group entity represents a group of users who can be granted permission to access a document. It has relations including manager and direct member to represent managers and members of a group respectively.
-
Organization entity represents an organization that can contain groups, users, and documents. It has relations to represent group, document, administrator, and direct member.
These relationships allow for efficient management of access control within the authorization model, ensuring that users, groups, organizations, and documents are appropriately connected for effective collaboration and secure document sharing.
Now that we have described our entities and the relations they have with words, let’s create the corresponding model for it using the Permify schema.
// Represents a user
entity user {}
// Represents an Organization
entity organization {
// Relation to represent the groups within the organization
relation group @group
// Relation to represent the administrator of the organization
relation administrator @user @group#direct_member @group#manager
// Relation to represent the direct members of the organization
relation direct_member @user
}
// Represents a group of users
entity group {
// Relation to represent the managers of the group
relation manager @user @group#direct_member @group#manager
// Relation to represent the direct members of the group
relation direct_member @user @group#direct_member @group#manager
}
// Definition of the document entity
entity document {
// Relation to represent the organization the document belongs to
relation org @organization
// Relation to represent the viewers of the document
relation viewer @user @group#direct_member @group#manager
// Relation to represent the manager of the document
relation manager @user @group#direct_member @group#manager
}
Defining Permissions
We have several actions attached to the entities, which are limited by certain permissions. Let’s form permission for viewing a document.
To view document X, a user can either be a viewer/manager of that document or the user should have an admin role in the organization document X belongs to.
Permify Schema language supports and, or, and not operators to achieve permission union, intersection and exclusion. The keywords action or permission can be used with those operators to form rules for your authorization logic.
So if we specify the view document action as view, then the action can be included in the schema definition by adding this: action view = viewer or manager or org.admin
Also, let’s form permission for editing a document.
A user will be granted access to edit a document X if the user meets any of these criteria:
- Is the manager of the document
- Is the administrator of the organization the document belongs to
Now, let’s translate the above criteria to an authorization logic in the Permify schema. We can use the or operator to enforce the ‘any’ rule. To this end, if we specify the edit document action as edit, then the action can be included in the schema definition by adding this: action edit = manager or org.admin.
Based on the two actions added, the document definition can be updated as follows:
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
}
Complete Schema
To maintain simplicity in this post, I will not delve into a detailed breakdown of each individual permission. Instead, let us proceed by incorporating the remaining permissions and finalizing our schema.
entity user {}
entity organization {
relation group @group
relation administrator @user @group#direct_member @group#manager
relation direct_member @user
permission admin = administrator
permission member = direct_member or administrator or group.member
}
entity group {
relation manager @user @group#direct_member @group#manager
relation direct_member @user @group#direct_member @group#manager
permission member = direct_member or manager
}
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
}
Creating Sample Authorization Data
In order to thoroughly test the authorization model we have developed thus far, it is essential to have relevant data that accurately represent the relationships between entities, objects, and users. This data serves as the foundation for constructing a comprehensive collection of access control lists (ACLs), enabling us to assess the efficacy and reliability of the authorization system.
In Permify, we use a specific form to represent object-to-object and object-to-subject relations. It’s called relational tuples.
The simplest form of a relational tuple is structured as entity # relation @ subject. Each relational tuple represents an action that a specific user or user set can do on a resource and takes the form of user U has relation R to object O, where user U could be a simple user or a user set such as group X members.
Here are some relational tuples according to our Google Docs example,
// Assign users to different groups
group:tech#manager@user:ashley
group:tech#direct_member@user:david
group:marketing#manager@user:john
group:marketing#direct_member@user:jenny
group:hr#manager@user:josh
group:hr#direct_member@user:joe
// Assign groups to other groups
group:tech#direct_member@group:marketing#direct_member
group:tech#direct_member@group:hr#direct_member
// Connect groups to organization
organization:acme#group@group:tech
organization:acme#group@group:marketing
organization:acme#group@group:hr
// Add some documents under the organization
organization:acme#document@document:product_database
organization:acme#document@document:marketing_materials
organization:acme#document@document:hr_documents
// Assign a user and members of a group as administrators for the organization
organization:acme#administrator@group:tech#manager
organization:acme#administrator@user:jenny
// Set the permissions on some documents
document:product_database#manager@group:tech#manager
document:product_database#viewer@group:tech#direct_member
document:marketing_materials#viewer@group:marketing#direct_member
document:hr_documents#manager@group:hr#manager
document:hr_documents#viewer@group:hr#direct_member
Note: The relational tuples created will be used to test and validate our authorization model and logic in the next section
Test & Validation
Finally, let's test our authorization logic to ensure we have modeled the schema and permission system correctly.
Can User:jenny view document:hr_documents?
According to what we have defined for the view action, only viewers, managers, and admins of the organization to which the document belongs can view the hr_documents. In this case, the Permify engine will check if the subject - user:jenny has any viewer relation within document:hr_documents. Since user:jenny has no viewer relation to document:hr_documents, the first check will result in a false. And because the or operator is used, the permify engine will then check if user:jenny has a manager relation to document:hr_documents.
Jenny doesn't have any manager relation to document:hr_documents and neither is she an admin in the acme organization the hr_documents belongs to. As a result, the Permify engine having ‘ORed’ the false returned from each check will finally return false. Therefore, the user:jenny view document:hr_documents check request should yield a false response.
Let’s try another one!
Can User:jenny edit document:marketing_materials?
According to what we have defined for the edit action only managers and admins of the organization to which the document belongs, can edit marketing_materials. In this context, the Permify engine will check if the subject - user:jenny has any direct or indirect manager relation within document:marketing_materials. Consecutively it will check does user:jenny has admin relation in the Acme Org - organization:acme#document@document:marketing_materials.
Jenny has an administrator relation to the Acme Org (organization:acme#administrator@user:jenny) and we have defined that admin of organization the document belongs to can edit the document:marketing_materials. Therefore, the user:jenny edit document:marketing_materials check request should yield a true response.
Let's test these two access checks on our local using the Permify validator. We'll use the below schema for the validation YAML file.
schema: >-
entity user {}
entity organization {
relation group @group
relation administrator @user @group#direct_member @group#manager
relation direct_member @user
permission admin = administrator
permission member = direct_member or administrator or group.member
}
entity group {
relation manager @user @group#direct_member @group#manager
relation direct_member @user @group#direct_member @group#manager
permission member = direct_member or manager
}
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
}
relationships:
- group:tech#manager@user:ashley
- group:tech#direct_member@user:david
- group:marketing#manager@user:john
- group:marketing#direct_member@user:jenny
- group:hr#manager@user:josh
- group:hr#direct_member@user:joe
- group:tech#direct_member@group:marketing#direct_member
- group:tech#direct_member@group:hr#direct_member
- organization:acme#group@group:tech
- organization:acme#group@group:marketing
- organization:acme#group@group:hr
- organization:acme#administrator@group:tech#manager
- organization:acme#administrator@user:jenny
- document:marketing_materials#org@organization:acme
- document:product_database#manager@group:tech#manager
- document:product_database#viewer@group:tech#direct_member
- document:marketing_materials#viewer@group:marketing#direct_member
- document:hr_documents#manager@group:hr#manager
- document:hr_documents#viewer@group:hr#direct_member
scenarios:
- name: "scenario 1"
description: "test description"
checks:
- entity: "document:hr_documents"
subject: "user:jenny"
assertions:
view: false
- entity: "document:marketing_materials"
subject: "user:jenny"
assertions:
edit: true
To use the Permify Validate function, follow the steps below.
First, Permify needs to be installed on your system. You can accomplish this using the Brew package manager. After Brew is installed, input the following command in your terminal to install Permify:
brew install permify
Upon successfully installing Permify, create a new YAML file in your local directory. This YAML file will contain the schema, relationships and assertions against which your data will be validated.
touch your-schema-file.yaml
Then, open the file with your preferred text editor to paste the schema, relationships and assertions.
Now that Permify is installed and your schema is ready, it's time to run the Validate function. Execute the appropriate command in your terminal, directing it to your schema file.
permify validate your-schema-file.yaml
Result:
Conclusion
We have reached the end of our demonstration and implementation of the authorization model for Google Docs using Permify. You can find this example on our playground to explore it in your browser. If you are interested in delving deeper into our solution or believe it could be valuable for your organization, we encourage you to join our community on Discord. We are excited to engage in discussions and exchange insights with you.