Auth0’s OpenFGA explained: Open source universal authorization

Authorization is an essential and non-trivial need in application development. Modern requirements have only increased the complexity of delivering adequate authorization. Auth0 aims to make authorization more standard and streamlined with Open FGA.

Admission tickets in an digital network / access / admittance / authorization / authentication
WildPixel / Your Photo / Getty Images

Auth0’s OpenFGA project is an open source effort that undertakes to provide a universal authorization solution. FGA stands for “Fine Grained Authorization,” a granular approach to authorization modeling that is flexible enough to handle almost any imaginable use case. 

Read on for an introduction to the OpenFGA project.

Authentication vs. authorization

Authentication is concerned with who and authorization with what.  Authentication answers the question: who are you?  Authorization answers the question: given who you are, what can you do?

Both of these are essential areas of cybersecurity, but of the two, authorization presents the more demanding architectural challenge.  That is because authorization deals with more complexity and far more data points. 

Authorization has to track a whole range of permissioned entities, like URLs and business objects, as well as access types like view, create, and edit.  Not only that, it must also deal with granting and revoking permissions to these objects.  Therefore, it is responsible for determining not just who has access to what, but who has permission to control permissions, the hierarchy of control between organizations and individuals.

Anyone who has dealt with these things knows just how messy it can become.  Tracking and applying permissions is a thorny problem, and it’s one that you can’t sidestep or cut corners on.  The difficulties only multiply the larger the system becomes.  Simple scalability begins to become a real challenge in the face of millions of permissions checks against billions of entities.

A universal, open-source authorization mechanism

Defining a generalized system to handle such requirements—one that is flexible enough to deal with the variety of in-the-world requirements, but still reliable, secure, and performant—is a substantial undertaking, but one that promises major benefits to enterprise.  Beyond making authorization more standard and eliminating the need to rebuild it per-application, such a system would enable more streamlined cross-application authorization communication.  Furthermore, concentrating authorization into a single, well-tested system offers security improvements.

Google’s Zanzibar project (whitepaper) describes such a universal authorization layer.  It incorporates a number of technological ideas to achieve the performance and availability goals of the system, and it offers a fairly developer friendly application programming interface (API) for interacting with it.  In particular, it delivers a universal domain-specific language (DSL) for describing users, groups, roles, and access control lists (ACLs) for expressing permissions.

Auth0 (now part of Okta) took up the challenge of delivering a system based on Zanzibar’s ideas in a reusable way with its upcoming Fine Grained Authorization SaaS.  Auth0 FGA essentially creates a remote API with which any app can integrate to obtain a universal permissions service.  Auth0’s Matias Woloski describes it as a high-performance and flexible authorization microservice that you don’t have to build and run yourself.  This allows application developers to offload much of the complexity in authorization to the remote service, while retaining control over most data in-house. 

Although this is a good model for many use cases, Auth0 has taken the further step of open sourcing its FGA core as the OpenFGA project (GitHub repo).  This is a significant move on a couple fronts.  For one, it represents a major commitment to open source by Auth0.  For the other, it contributes an enormous amount of know-how and capability to the OSS community.  Once the community has its hands on things, it tends to elaborate and expand upon them in unexpected ways.

In its announcement of the move, Auth0 gives several reasons and among them are the desire to encourage an active community that will support adoption, integration with technology-specific tooling, and the systemic improvement of security in the industry.  It does indeed appear we are looking at a big enterprise-open-source partnership win here.

Woloski outlines Auth0’s strategy, saying that by “open sourcing it, we let developers embed this component in their own infrastructure. Once they feel comfortable, they can decide to let us run it for them as a service with additional enterprise features, or keep using the open source version. We are committed to maintaining it in the long term."

OpenFGA Server

The core of the project is the permission engine itself, a standalone server that can handle the authorization requests.  The OpenFGA server is modular with respect to data storage, and currently you can choose between an in-memory datastore or PostgresSQL.  The ability to run the server on owned infrastructure is a key benefit, as some compliance situations demand it.   This server is fundamentally an HTTP API allowing for defining permission models, and querying/modifying them. 

The server is written in Go and can be built from sources for those interested in contributing, but most end users will deploy the binaries or Docker image.  Quickstart for running on localhost via Docker is here.

Being based on the Zanzibar architecture, the OpenFGA server is built with an eye to scaling and availability.  Of course, that depends greatly on the underlying infrastructure.

“Zanzibar implementations are heavily optimized to answer if a user can perform an action on a resource in a scalable way. OpenFGA is not an exception,” says Woloski. “When using the Auth0 FGA implementation, Auth0 will own the infrastructure and make sure it is highly scalable and available. OpenFGA users will be responsible for operating the service on their infrastructure, so the scalability/availability characteristics of the service will depend on it.”

OpenFGA Client

Once the server is running, you can set up a client in your application based on the stack you are using—currently, software development kits (SDKs) exist for Node, Go and .NET.  The client allows you to interact with the server API in an idiomatic way. 

The first task is to define a store on the server, the root level container object for holding the auth information, much like a database within a database management system (DBMS).  The store is then configured with the authorization model, analogous to the schema in a database. 

Once you have the server up, a client installed and a store provisioned, you can define the model by issuing a request using JSON.  For example, using the Node client, a simple data model is configured as in Listing 1.  (This is from the Auth0 quick start).

Listing 1. Simple auth model in JSON/Node

const { authorization_model_id: id } = await fgaClient.writeAuthorizationModel({

 "type_definitions": [

   {

     "type": "document",

     "relations": {

       "reader": {

         "this": {}

       },

       "writer": {

         "this": {}

       },

       "owner": {

         "this": {}

       }

     }

   }

 ]

});

OpenFGA also supports a DSL for modeling.  The same model in the DSL is in Listing 2.

Listing 2. Simple DSL model

type document

  relations

    define reader as self

    define writer as self

    define owner as self

At this time it’s not usable with the in-code SDKs, but you can convert between the two and get a visualization using the OpenFGA sandbox here.  (You can also use the SyntexTransformer node library).  The DSL and visualizer are great for refining models.  You can see the simple model from Listings 1 and 2 as seen in the modeler, Figure 1.

Simple auth model in designer Image credit: Matthew Tyson

Figure 1. Simple auth model in designer (Click image to view full-size)

Tuples

Tuples are an association among three entities: a user, a relationship, and an object.  They express the instances of things within the data model.  You can create a tuple in the designer in the lower lefthand pane.  For example: owner: alice, relationship: reader, object: document:z.

With the relationship defined, you can query using the query parser at the bottom of the screen, for example: who is related to document:z as reader.  This will appropriately return the alice user as in screen 2.

Returning the readers on document:z Image credit: Matthew Tyson

Figure 2. Returning the readers on document:z (Click image to view full-size)

All relationships are modifiable via the code client.  This gives you an extraordinary amount of power for controlling authorization from within your application, including self-referential granting and revoking of authority based on groups and roles.

The docs (also now open source) cover a great deal of further ground and use cases including using openID and the specifics of securing resources like URLs.

Copyright © 2022 IDG Communications, Inc.

7 hot cybersecurity trends (and 2 going cold)