OpenFGA - Auth0’s Open Source Fine Grained Authorization System
Tags: fga, security, productivity
Published: 2022-07-19 11:20:18

### Fine grained authorization-at-scale, available for everyone

<br>

[A few months ago](https://auth0.com/blog/auth0-fine-grained-authorization-developer-community-preview-release/) we announced a Developer Preview of Auth0 Fine Grained Authorization (FGA), our upcoming SaaS product to solve authorization-at-scale for developers. Today we’re announcing [OpenFGA](https://openfga.dev/), the open source engine that powers Auth0 FGA.

OpenFGA is a fast, flexible Fine-Grained Authorization System inspired by [Google's Zanzibar](https://research.google/pubs/pub48190/) paper, and has been designed for reliability and low latency at a high scale. It makes it easy for application developers to model their access control layer, and to add and integrate fine-grained authorization in a way that is consistent across all of their applications. It’s designed, built, and sponsored by Okta/Auth0.

## Why Is Fine Grained Authorization Important?

Modern applications have evolved in a way that end-users now drive permission management.  This makes fine grained authorization an increasingly critical element in software. For example:

**Collaboration** and **social** features are things users expect. These features range from the **‘Share’** button where users proactively grant specific permissions to a set of users for a specific resource, to **‘Request Access’** workflows that allows users to reactively grant access on demand. These features are useful both for business-related assets such as documents or project boards, as well as social sharing personal content like photo albums, social media posts, and even IoT devices.

**Security, compliance, and privacy** are mandatory problems to solve for any software application from day one, and authorization is a big part of any solution. In fact, the top [2021 OWASP risk is broken access control.](https://owasp.org/Top10/)

Organizations like Airbnb and Carta have built Zanzibar-like systems to solve their authorization needs. We don’t think organizations should have to keep building the same authorization tools again and again, so we set out to build one version that any developer can use. 

## How Does It Work?

As an example, we’ll use OpenFGA to model a simple expense management system. Imagine expense reports have the following requirements:

* Can be submitted by any employee.
* Can be approved by the submitter’s manager, or by the manager’s manager (or their manager, etc..).
* Can be viewed by the submitter, the approver, and anyone else that got the report shared with them.

To solve this problem in OpenFGA you would define the following authorization model:

```go
// There are reports in the system
type report
 relations
   // Reports have submitters (user who have submitted that report)
  define submitter as self
   // Reports have approvers (users who can approve reports)
   // A report's approvers are the managers of the submitter
   //   of that report
  define approver as manager from submitter
   // Reports have viewers (user who can view that report)
   // The users who can view a report are the submitter,
   //   the users who can approve it, anyone it has been shared directly with
  define viewer as self or submitter or approver

// There are employees in the system
type employee
 relations
   // Employees have managers, managers are those directly assigned
   //   or anyone who's a manager of a manager
  define manager as self or manager from manager
```

The OpenFGA language uses `self` to indicate that the relationship can be assigned.

* Submitters and viewers of a report can be directly assigned.
* Direct managers of an employee can be directly assigned.

Definitions without `self` can not be assigned directly, but can be inherited.

In addition to defining an authorization model, OpenFGA requires you to provide the actual data to instantiate these permissions. In this example, we’ll have 4 participants:

* Daniel, who is Sam’s manager
* Matt, who is Daniel’s manager
* Sam, who will submit an expense report
* Peter, who works in the same team as Sam. Sam wants to share the report with him.

You would provide this data by using the [OpenFGA’s Write API](http://openfga.dev/api/service/#/Tuples/Write) and a few “tuples”. 

Some of the tuples will define the direct reports. This data will probably be synchronized automatically from an HR system (e.g. Workday):


    { "user": "employee:daniel",  "relation": "manager", "object": "employee:sam" }

    { "user": "employee:matt",  "relation": "manager", "object": "employee:daniel" }

Whenever Sam submits an expense report (in this example, ‘sam-trip’), the following tuple should be created:

    { "user": "employee:sam",  "relation": "submitter", "object": "report:sam-trip" }

When Sam later shares the report with Peter, the following tuple should be created:

    { "user": "employee:peter",  "relation": "viewer", "object": "report:sam-trip" }

With the above information now in the system, we can now ask OpenFGA if a specific user has a specific relation with a particular object. We do that by using [OpenFGA’s Check API,](https://openfga.dev/api/service#/Tuples/Check) which will return true or false. For example, if we check `{ "user": "employee:matt",  "relation": "approver", "object": "report:sam-trip" }`, OpenFGA will return **TRUE**, as Matt is the manager of Sam’s manager, and Sam is the submitter of the expense report.

You can also use the [‘Expand’ API](https://openfga.dev/api/service#/Relationship%20Queries/Expand) to understand why OpenFGA returns that result. The Auth0 FGA Playground provides a visualization of the results of calling that API:

![OpenFGA](https://images.ctfassets.net/23aumh6u8s0i/1eSifra3BxJLVtV6XtR4xv/58c1a82f8770c9a2555b9632dbc80507/OpenFGA.jpg)

It needs to answer “is employee:matt related to report:sam-trip as approver”. To do that, OpenFGA:

1. Expands the “approver” relationship for Sam’s report
2. Finds out that the approver needs to be Sam's manager (the report submitter’s manager), and finds out who the managers are <br>
    **a**. Daniel is Sam’s assigned manager, but Daniel is not the one we are looking for <br>
    **b**. Daniel's managers are also Sam's managers, so OpenFGA needs to expand them <br>
3. Expands the “manager” relationship for Daniel <br>
    **a**. Matt is Daniel's manager, which is what we were looking for! <br>
    **b**. Matt's managers would also be Sam's managers, but there's no manager defined for Matt <br>

To summarize, you need to:

* Define a domain-specific authorization model.
* Use the `Write()` API to add relationship tuples.
* Use the `Check()` API to check for permissions.
* Use the `Expand()` API in cases where you need a detailed understanding of the Check() results instead of a simple TRUE or FALSE response

## Why Open Source?

Both Auth0 and Okta maintain a large number of open source projects, and use a myriad of open source products internally. This time we are going one step further than usual and open-sourcing a core Auth0 product. We’ll continue to offer [Auth0 FGA](https://fga.dev/) as a SaaS offering, but also strive to build the best open source implementation of a Zanzibar-style authorization system.

[Read more...](https://auth0.com/blog/auth0s-openfga-open-source-fine-grained-authorization-system/?utm_source=content_synd&utm_medium=sc&utm_campaign=authorization)