Introduction To Modeling
To define a ReBAC model in OpenFGA we recommend:- If you have an existing system: forget about how your system works today and start thinking about how you want it to work in the future.
- Thinking about authorization starting from the resources, or objects as OpenFGA calls them.
In the previous example, a relation R should be defined that implies permission to action A. For example:
We’ll provide more detailed examples throughout this article.
When you are modeling, you need to answer a more general question:
Why could user U perform an action A on an object O?
A Process For Defining Authorization Models
Defining an authorization model requires codifying an answer to the question “why could user U perform an action A on an object O?” for all use cases or actions in your system. This is an iterative process. For the purpose of this guide, we’ll go through one iteration of this process using a simplified Google Drive like system as an example. Steps for defining your authorization model:- Pick the most important feature
- List the object types
- List relations for those types
- Define relations
- Test the model
- Iterate
01. Pick The Most Important Feature
Write It In Plain Language
Once you’ve picked a feature, describe its authorization related scope using simple language. Avoid using the word “roles”, as this ties you to an RBAC way of thinking.Roles don’t “disappear” in ReBAC systems like OpenFGA. Your users might have roles on a given object, rather than the entire system. But starting from the term “role” might lead you down the wrong path. Instead it is better to discover roles while you are modeling.
A user {user} can perform action {action} to/on/in {object types} … IF {conditions}Let’s look at an example of a simplified Google Drive like system. We’ll focus on the feature allowing users to create, read, update, delete, and share documents with other users. This feature can be described with these sentences:
- A user can create a document in a drive if they are the owner of the drive.
- A user can create a folder in a drive if they are the owner of the drive.
- A user can create a document in a folder if they are the owner of the folder. The folder is the parent of the document.
- A user can create a folder in a folder if they are the owner of the folder. The existing folder is the parent of the new folder.
- A user can share a document with another user or an organization as either editor or viewer if they are an owner or editor of a document or if they are an owner of the folder/drive that is the parent of the document.
- A user can share a folder with another user or an organization as a viewer if they are an owner of the folder.
- A user can view a document if they are an owner, viewer or editor of the document or if they are a viewer or owner of the folder/drive that is the parent of the document.
- A user can edit a document if they are an owner or editor of the document or if they are an owner of the folder/drive that is the parent of the document.
- A user can change the owner of a document if they are an owner of the document.
- A user can change the owner of a folder if they are an owner of the folder.
- A user can be a member of an organization. How a user is added as a member to an organization is beyond the scope of the feature we picked to write down.
- A user can view a folder if they are the owner of the folder, or a viewer or owner of either the parent folder of the folder, or the parent drive of the folder.
02. List The Object Types
A user {user} can perform action {action} to/on/in {object type} … IF {conditions}These are all the object types from the previous step (in order of appearance) based on that template:
Document
Folder
Organization
- A user can create a document in a drive if they are the owner of the drive.
- A user can create a folder in a drive if they are the owner of the drive.
- A user can create a document in a folder if they are the owner of the folder.
- A user can create a folder in a folder if they are the owner of the folder.
- A user can share a document with another user or an organization as either editor or viewer if they are an owner or editor of a document or if they are an owner of the folder/drive that is the parent of the document.
- A user can share a folder with another user or an organization as a viewer if they are an owner of the folder.
- A user can view a document if they are an owner, viewer or editor of the document or if they are a viewer, owner of the folder/drive that is the parent of the document.
- A user can edit a document if they are an owner or editor of the document or if they are an owner of the folder/drive that is the parent of the document.
- A user can change the owner of a document if they are an owner of the document.
- A user can change the owner of a folder if they are an owner of the folder.
- A user can be a member of an organization. How a user is added as a member to an organization is beyond the scope of the feature we picked to write down.
- A user can view a folder if they are the owner of the folder, or a viewer or owner of either the parent folder of the folder, or the parent drive of the folder.
… IF {first noun} of a/the {second noun}Let’s highlight those expressions in green:
- A user can create a document in a drive if they are the owner of the drive.
- A user can create a folder in a drive if they are the owner of the drive.
- A user can create a document in a folder if they are the owner of the folder. The folder is the parent of the document.
- A user can create a folder in a folder if they are the owner of the folder. The existing folder is the parent of the new folder .
- A user can share a document with another user or an organization as either editor or viewer if they are an owner or editor of a document or if they are an owner of the folder/drive that is the parent of the document.
- A user can share a folder with another user or an organization as a viewer if they are an owner of the folder.
- A user can view a document if they are an owner, viewer or editor of the document or if they are a viewer or owner of the folder/drive that is the parent of the document.
- A user can edit a document if they are an owner or editor of the document or if they are an owner of the folder/drive that is the parent of the document.
- A user can change the owner of a document if they are an owner of the document.
- A user can change the owner of a folder if they are an owner of the folder.
- A user can be a member of an organization. How a user is added as a member to an organization is beyond the scope of the feature we picked to write down.
- A user can view a folder if they are the owner of the folder, or a viewer or owner of either the parent folder of the folder, or the parent drive of the folder.
User
Document
Folder
Organization
Drive
You’re now in the process of building a version you can use. The model above is not yet a valid authorization model accepted by OpenFGA.
ImportantIn a few cases other users can be part of determining whether an action can be performed on an object or not. Social media is an example of this “a user can comment on a picture if they are a friend of the user that published it”.In those cases User should also be an object type. Following the last recommendation, we would discover the User type because it is a second noun in an expression: “friend of the user”.
03. List Relations For Those Types
- any noun that is the {noun} of a “{noun} of a/an/the {type}” expression. These are typically the Foreign Keys in a database. We’ll highlight these in green.
- any verb or action that is the {action} of a “can {action} (in) a/an {type}” expression. These are typically the permissions for a type. We’ll highlight these in yellow.
- A user can create a document in a drive if they are the owner of the drive.
- A user can create a folder in a drive if they are the owner of the drive.
- A user can create a document in a folder if they are the owner of the folder. The folder is the parent of the document.
- A user can create a folder in a folder if they are the owner of the folder. The existing folder is the parent of the new folder.
- A user can share a document with another user or an organization as either editor or viewer if they are an owner or editor of a document or if they are an owner of the folder/drive that is the parent of the document.
- A user can share a folder with another user or an organization as a viewer if they are an owner of the folder.
- A user can view a document if they are an owner, viewer or editor of the document or if they are a viewer or owner of the folder/drive that is the parent of the document.
- A user can edit a document if they are an owner or editor of the document or if they are an owner of the folder/drive that is the parent of the document.
- A user can change the owner of a document if they are an owner of the document.
- A user can change the owner of a folder if they are an owner of the folder.
- A user can be a member of an organization. How a user is added as a member to an organization is beyond the scope of the feature we picked to write down.
- A user can view a folder if they are the owner of the folder, or a viewer or owner of either the parent folder of the folder, or the parent drive of the folder.
Document
- parent
- can_share
- owner
- editor
- can_write
- can_view
- viewer
- can_change_owner
Folder
- can_create_document
- owner
- can_create_folder
- can_view
- viewer
- parent
Organization
- member
Drive
- can_create_document
- owner
- can_create_folder
In OpenFGA, relations can only have alphanumeric characters, underscores and hyphens. We recommend using underscore (_) to separate words and removing prepositions. E.g.: “can create a document” can become “can_create_document” or “create_document” if you are into brevity.
You’re now in the process of building a version you can use. The model above is not yet a valid authorization model accepted by OpenFGA.
04. Define Relations
Why could a user U, perform an action A on an object O?
Type: Organization
Relation: Member
The member relation is used to tell OpenFGA about the members of an organization.ImportantRelation names in OpenFGA are arbitrary strings. There are no reserved relation names. You can use “member” or “part_of” or anything else to refer to a user that is part of a team/organization.
- That organizations have members
-
That the members of an organization with id {id} are all users described by tuples of the form:
{ user: {user-id}, relation: "member", object: "organization:{id}" }
ImportantRelation definitions of the form “define {relation}: [user, organization#member]” are fairly common. They are used to express that relationships “to the object with that relation” (e.g. “users” of type user or “member of organization”) can be assigned by your system and that only the users that have that relation are those with a direct relationship.
- user
- organization#member (i.e., other organization’s member)
Side noteThis also automatically supports nested organizational membership if you want such a feature in your system. You could use relationship tuples like the following one to express that “members of organization A are members of organization B”:If you want to learn more, you can read further about this in Modeling User Groups and Managing Relationships Between Objects.
Complete Type Definition
The complete type definition for the organization type is:Type: Document
Relation: Owner
The owner relation is used to tell OpenFGA which users are owners of the document.ImportantIn the current version, there is no way to state that there is only one owner in the authorization model. The application must limit this set of users to just one owner if that is a requirement.
- each document can have one or more owners
- owners of a document are assignable by creating a tuple of the format
{ user: "{user_id}", relation: "owner", object: "document:{id}" }for individual users
Relation: Editor
The editor relation is used to tell OpenFGA which users are editors of the document. When a user shares a document with another user or set of users as editor, a relationship tuple will be stored in OpenFGA representing this relationship between editor and document. This is an example of a users to object relationship. The relation definition then should be: Why? This relation definition states that:- each document can have editors
- the editor(s) of a document are assignable by creating a tuple with shape
{ user: "{user_id}", relation: "editor", object: "document:{id}" }for individual users
Relation: Viewer
The viewer relation is similar to the document’s editor relation. It will be defined like this:Relation: Parent
The parent relation is used to tell OpenFGA which folder or drive is the parent of the document. This relation is different from the others we have seen so far, as it is a relation between two objects (a folder and or drive that is the parent of the document). This is known as an object to object relationship, of which parent-child is a particular case. When a document is created a relationship tuple will be stored in OpenFGA to represent this relationship between parent and document. The relation definition then should be: Why? This relation definition states that:- documents may have a parent
- the parent(s) of a document with id {id} is either a folder or a drive, described by one of these relationship tuples:
{ user: "folder:{id}", relation: "parent", object: "document:{id}" }{ user: "drive:{id}", relation: "parent", object: "document:{id}" }
Side noteYou might have noticed that the “user” in the tuple is an object. This is a special syntax OpenFGA accepts in the “user” parameter to write object to object relationships. You can read more about writing data to manage object to object relationships in Managing Relationships Between Objects.
Relation: can_share
We need to express the following in the relation definition: A user can share a document with another user or an organization as either editor or viewer if they are an owner or editor of a document or if they are an owner of the folder that is the parent of the document. We can achieve that with the following definition using OpenFGA Configuration Language: There are a few key things here:- We don’t use a direct relationship type restriction as part of the definition. can_share is a common example of representing a permission that is defined in terms of other relations but is not directly assignable by the system.
- The relation definition contains a union operator separating a list of relations that the user must have with the object in order to “be able to share the document”. It is any of:
- Being an owner of the document
- Being an editor of the document
- Being an owner of the parent of the document. Whether the parent is a drive or a folder is not important, as they both have an owner relation.
Relation: can_view
We need to express the following in the relation definition: A user can view a document if they are an owner, viewer or editor of a document or if they are a viewer, owner of the folder/drive that is the parent of the document. Similar to the can_share relation, we can achieve that with the following definition using OpenFGA Configuration Language:Relation: can_write
We need to express the following in the relation definition: A user can write a document if they are an owner or editor of a document or if they are an owner or editor of the folder/drive that is the parent of the document. Similar to the can_share relation, we can achieve that with the following definition using OpenFGA Configuration Language:Relation: can_change_owner
We need to express the following in the relation definition: A user can change the owner of a document if they are an owner of the document. Similar to the can_share relation, we can achieve that with the following definition using OpenFGA Configuration Language:Complete Type Definition
The complete type definition for the document type is: Combining the type definitions for document and organization, we haveThe OpenFGA authorization model API and SDK only accepts JSON in its input. To convert from DSL to JSON, you may use the FGA CLI to run
fga model transform.05. Test The Model
Can user U, perform an action A on an object O?
What we want is to ensure that given our current authorization model and some sample relationship tuples, we get the expected results for those questions.
So we’ll write some relationship tuples and assertions. An OpenFGA assertion takes one of these forms:
- user U has relation R with object O
- user U does not have relation R with object O
Write Relationship Tuples
The relationship tuples should represent real examples from your system with fake data. At this point you haven’t defined the drive or folder types, so you can only test things based on users or organization members’ relationships to documents. Let’s imagine an example setup and write the relationship tuples for it:
Follow these steps to create relationship tuples.
Create Assertions
According to our written down model and the relationship tuples from the previous step, these assertions should be specified: Because anne is the owner of document:1:- user anne has relation can_share with document:1
- user anne has relation can_write with document:1
- user anne has relation can_view with document:1
- user anne has relation can_change_owner with document:1
- user beth has relation can_share with document:1
- user beth has relation can_write with document:1
- user beth has relation can_view with document:1
- user beth does not have relation can_change_owner with document:1
- user beth has relation can_share with document:2
- user beth has relation can_write with document:2
- user beth has relation can_view with document:2
- user beth has relation can_change_owner with document:2
- user anne does not have relation can_share with document:2
- user anne does not have relation can_write with document:2
- user anne has relation can_view with document:2
- user anne does not have relation can_change_owner with document:2
Run Assertions
Run the assertions. They should all pass. If they don’t you can use the query view to understand what is causing them to fail, and then update your authorization model and relation tuples accordingly. Once all the assertions are working, you should continue the iterative process of working on your model.06. Iterate
Related Sections
Check the following sections for more on how to model with OpenFGA.OpenFGA Concepts
Learn about the OpenFGA Concepts.
Configuration Language
Learn about OpenFGA Configuration Language.
Direct Access
Learn about modeling user access to an object.