Sign Up
Hero

Announcing OpenFGA - Auth0’s Open Source Fine Grained Authorization System

Fine grained authorization-at-scale, available for everyone

A few months ago 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, the open-source engine that powers Auth0 FGA.

OpenFGA is a fast, flexible Fine-Grained Authorization System inspired by Google's Zanzibar 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 allow 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.

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:

// 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 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, 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 to understand why OpenFGA returns that result. The Auth0 FGA Playground provides a visualization of the results of calling that API:

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
    a. Daniel is Sam’s assigned manager, but Daniel is not the one we are looking for
    b. Daniel's managers are also Sam's managers, so OpenFGA needs to expand them
  3. Expands the “manager” relationship for Daniel
    a. Matt is Daniel's manager, which is what we were looking for!
    b. Matt's managers would also be Sam's managers, but there's no manager defined for Matt

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 as a SaaS offering, but also strive to build the best open source implementation of a Zanzibar-style authorization system.

We’re doing this for several reasons:

  • We believe there’s an opportunity to create a large ecosystem around a fine-grained authorization system, and that making our FGA offering open source will maximize the chances for this to happen. We expect OpenFGA integrations for authorization policies products like OPA, proxies like Envoy, API gateways like Kong; identity providers (Auth0, Okta, AzureAD), SDKs for platforms and frameworks (Python, Java, Spring, Next.js), etc.
  • We want to enable customers that require deploying in different cloud providers, on-premise, in multiple regions, with FedRAMP compliance, or those that have a low tolerance to the risk of delegating authorization to a third party provider. From our experience with Auth0, we know those are difficult problems for a SaaS product.
  • The industry will benefit by having a common way to manage Fine Grained Authorization. We believe Auth0/Okta is the company that can make this happen. It’s a leader in the Identity Access Management space, is trusted by thousands of customers, is cloud-agnostic, and has the financial capacity to invest in the product long-term.

What Are We Open Sourcing?

We are open sourcing the engine that drives our SaaS product, and the SDKs that make it so easy to use.

You can find all of these projects hosted in an OpenFGA organization on Github.

  • OpenFGA Server: the core FGA server which provides:
    • An expressive language to define your authorization model.
    • HTTP APIs for checking and granting permission, authoring models, query tuples.
    • A graph querying implementation inspired by Google Zanzibar
    • Pluggable storage adapters, with support for an in-memory database and PostgreSQL
    • OpenTelemetry tracing, metrics, and structured logging
  • Website and Docs: The openfga.dev website, which includes our product documentation.
  • SDK Generator: Tooling to generate SDKs based on OpenAPI definitions.
  • Go SDK, .NET SDK, Javascript SDK: SDKs for different languages, with more to come soon!
  • Auth0’s FGA Playground, which is not open source now but it will be in the following weeks.

OpenFGA and the Cloud Native Computing Foundation

The Cloud Native Computing Foundation (CNCF) is an open-source software foundation that promotes the adoption of cloud-native computing. It hosts projects like Kubernetes, Envoy, and Open Policy Agent, along with a hundred others.

As we mentioned earlier, we believe there needs to be an open source version of a Zanzibar-inspired Fine Grained Authorization product. Creating such a product requires an initiative that early adopters can trust. To further accelerate this process, we submitted OpenFGA to the Cloud Native Computing Foundation sandbox.

By joining the CNCF, the OpenFGA project will find a larger, vibrant community that will help this initiative to continue growing and attract more users and developers.

Try It!

An open source project is only as good as its community, so we are extending a warm welcome to everyone that wants to get involved.

You can help by simply trying the product, providing feedback, and engaging with other OpenFGA users in Discord / Github Discussions, attending our bi-monthly office hours, or contributing to the project.

Find out more by visiting openfga.dev, and learn how to use it in our awesome documentation. Keep up to date with the latest news by following us on Twitter.