Skip to content

Commit

Permalink
feat: added abac with rebac example
Browse files Browse the repository at this point in the history
  • Loading branch information
aaguiarz committed Sep 8, 2024
1 parent dc24e48 commit 3fcabe1
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 0 deletions.
66 changes: 66 additions & 0 deletions stores/abac-with-rebac/README.md
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 with the resource where the attribute is defined with 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`
100 changes: 100 additions & 0 deletions stores/abac-with-rebac/store.fga.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
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

0 comments on commit 3fcabe1

Please sign in to comment.