-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added abac with rebac example Co-authored-by: Raghd Hamzeh <[email protected]>
- Loading branch information
Showing
2 changed files
with
167 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# OpenFGA Modeling Attribute-Based Access Control with Relationship Based Access Control | ||
|
||
## Use-Case | ||
|
||
This example demonstrates how to model Attribute-Based access control scenarios purely with Relationship Based Access Control constructs. | ||
|
||
In ABAC, you make authorization decisions based on different attributes of the user, the resource, and the environment. Depending on the kind of attribute, you can model them pretty easily in ReBAC or not. | ||
|
||
If the attribute is a **reference to another entity**, e.g. the equivalent of a foreign key in a relational database, then you can model it as a relation. For example, the user's department can be modeled as: | ||
|
||
``` | ||
type user | ||
type department | ||
relations | ||
define member : [user] | ||
type folder | ||
relations | ||
define department : [department] | ||
define viewer : member from department | ||
``` | ||
|
||
If the attribute is a **category with a few values**, e.g. a boolean, a category like `status', then you can model it by defining a relationship for each possible value, where the resource is related to itself. | ||
|
||
For example, the following model defines a policy where the user can only view a document if their email is verified, you'll add an email_verified relation to the user type: | ||
|
||
```` | ||
type user | ||
relations | ||
define email_verified : [user] | ||
type document | ||
relations | ||
define viewer : [user] | ||
define can_view : email_verified from viewer | ||
``` | ||
If you want to model a document status, you'll add a relation for each possible status with the document itself: | ||
```` | ||
type user | ||
|
||
type document | ||
relations | ||
define published : [document] | ||
define draft : [document] | ||
|
||
define viewer : [user] | ||
|
||
define can_view : viewer from published | ||
``` | ||
If the attribute is a discrete variable with many possible values, e.g. birth date, age, IP address, a a currency amount, then it's not possible to be modeled with pure ReBAC and you need to resort to using [OpenFGA conditions](https://openfga.dev/docs/modeling/conditions). | ||
If you can model your attribute as a relation, you should do so, as it will make your model simpler and more efficient. | ||
The example in [store.fga.yaml](./store.fga.yaml) showcases the two examples above. | ||
## Try It Out | ||
1. Make sure you have the [FGA CLI](https://github.com/openfga/cli/?tab=readme-ov-file#installation) | ||
2. In the `abac-with-rebac` directory, run `fga model test --tests store.yaml` | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
model: | | ||
model | ||
schema 1.1 | ||
type user | ||
relations | ||
define email_verified : [user] | ||
type document | ||
relations | ||
define draft : [document] | ||
define published : [document] | ||
define viewer : [user] | ||
define viewer_email_verified : email_verified from viewer | ||
define owner : [user] | ||
define owner_email_verified : email_verified from owner | ||
define can_view : owner_email_verified or viewer_email_verified from published | ||
define can_edit : owner_email_verified from draft | ||
tuples: | ||
|
||
# Whenever bob/anne verify their email, these two tuples should be created | ||
- user: user:bob | ||
relation: email_verified | ||
object: user:bob | ||
|
||
- user: user:anne | ||
relation: email_verified | ||
object: user:anne | ||
|
||
- user: user:bob | ||
relation: owner | ||
object: document:readme | ||
|
||
- user: user:anne | ||
relation: viewer | ||
object: document:readme | ||
|
||
- user: user:jeremy | ||
relation: viewer | ||
object: document:readme | ||
|
||
tests: | ||
- name: Test permissions for draft document | ||
tuples: | ||
# This tuple can be written to OpenFGA when the document status changes | ||
# or can be sent as a contextual tuple | ||
- user: document:readme | ||
relation: draft | ||
object: document:readme | ||
check: | ||
# Only the owner can view and edit a draft document | ||
- user: user:anne | ||
object: document:readme | ||
assertions: | ||
can_edit : false | ||
can_view : false | ||
|
||
- user: user:bob | ||
object: document:readme | ||
assertions: | ||
can_edit : true | ||
can_view : true | ||
|
||
# jeremy does not have a verified email so it's not allowed to edit or view regardless of status | ||
- user: user:jeremy | ||
object: document:readme | ||
assertions: | ||
can_edit : false | ||
can_view : false | ||
|
||
- name: Test permissions for published document | ||
tuples: | ||
# This tuple can be written to OpenFGA when the document status changes | ||
# or can be sent as a contextual tuple | ||
- user: document:readme | ||
relation: published | ||
object: document:readme | ||
check: | ||
# Everyone can view a published document, but nobody can edit it | ||
- user: user:anne | ||
object: document:readme | ||
assertions: | ||
can_edit : false | ||
can_view : true | ||
- user: user:bob | ||
object: document:readme | ||
assertions: | ||
can_edit : false | ||
can_view : true | ||
|
||
# jeremy does not have a verified email so it's not allowed to edit or view regardless of status | ||
- user: user:jeremy | ||
object: document:readme | ||
assertions: | ||
can_edit : false | ||
can_view : false |