Skip to main content

Concepts

note
OpenFGA is an open source Fine-Grained Authorization solution based on Google's Zanzibar. We welcome community contribution to this project.

The OpenFGA service answers authorization checks by determining whether a relationship exists between an object and a user. Checks takes into consideration the authorization model of the system and the relationship tuples present in the system at that time in order to make a decision.

In this guide you will learn about the most relevant FGA concepts, such as a type or an authorization model, and you will be able to explore them using the FGA playground.

What Is A Type?

A type is a string. It should define a class of objects with similar characteristics.

Examples of types:

  • workspace
  • repository
  • organization
  • document

What Is A Type Definition?

A type definition is a configuration that defines all possible relations a user or another object can have in relation to this type.

Code snippet below is an example of a type definition:

type document
relations
define viewer as self
define commenter as self
define editor as self
define owner as self

What Is An Authorization Model?

An authorization model is a combination of one or more type definitions. This is used to define the permission model of a system.

Code snippet below is an example of an authorization model:

type document
relations
define viewer as self
define commenter as self
define editor as self
define owner as self
type domain
relations
define member as self

Authorization model, together with relationship tuples, allow determination of whether a relationship exists between a user and an object.

The OpenFGA service has two different syntaxes to define the authorization model:

  • A JSON syntax accepted by the OpenFGA API that follows closely the original syntax discussed in the Zanzibar Paper. See Equivalent Zanzibar Concepts.
  • A DSL that we believe is easier to use and is used in the Auth0 FGA Playground to help with modeling. This is translated to the API-supported syntax before being sent to the API.

Learn more about the OpenFGA Configuration Language.

What Is A Store?

A "store" is a OpenFGA entity used for organizing data needed to answer authorization checks.

Each store contains one or more versions of an authorization model and may contain various relationship tuples.

Store data such as the authorization model and relationship tuples cannot be shared across stores, so it is highly recommended to store all data that may be related and may affect your authorization result in a single store.

For completely separate authorization needs or isolated environments where data from one should not affect another (e.g. development/prod), you may want to create separate stores.

What Is An Object?

An object represents an entity in the system. We can define how various users have a relationship to it through relationship tuples and the authorization model.

An object is a combination of a type and an identifier.

For example:

  • workspace:fb83c013-3060-41f4-9590-d3233a67938f
  • repository:auth0/express-jwt
  • organization:org_ajUc9kJ
  • document:new-roadmap

User, relation and object are the building blocks for relationship tuples.

For more information, please see Direct Access.

What Is A User?

A user is an entity in the system that can be related to an object.

A user is

  • any identifier: e.g. anne or 4179af14-f0c0-4930-88fd-5570c7bf6f59
  • any object: e.g. workspace:fb83c013-3060-41f4-9590-d3233a67938f, repository:auth0/express-jwt or organization:org_ajUc9kJ
  • a group or a set of users (also called a userset): e.g. organization:org_ajUc9kJ#members, which represents the set of users related to the object organization:org_ajUc9kJ as member
  • everyone, using the special syntax: *

User, relation and object are the building blocks for relationship tuples.

For more information, please see Direct Access.

What Is A Relation?

A relation is a string defined in the type definition of an authorization model that defines the possibility of a relationship between an object of the same type as the type definition and a user in the system.

Examples of relation:

  • User can be a reader of a document
  • Team can administer a repo
  • User can be a member of a team

What Is A Relation Definition?

A relation definition lists the conditions or requirements under which this relationship would be possible.

For example:

  • editor describing a possible relationship between a user and an object in the document type allows the following:
    • user identifier to object relationship: the user id anne is related to the object document:roadmap as editor
    • object to object relationship: the object application:ifft is related to the object document:roadmap as editor
    • userset to object relationship: the userset organization:auth0.com#member is related to document:roadmap as editor
      • indicating that the set of users who are related to the object organization:auth0.com as member are related to the object document:roadmap as editors
      • this allows for potential solutions to use-cases like sharing a document internally with all members of a company or a team
    • everyone to object relationship: everyone (*) is related to document:roadmap as editor
      • this is how one could model publicly editable documents

These would be defined in the authorization model as such:

type document
relations
define viewer as self
define commenter as self
define editor as self
define owner as self
info

In the configuration of the document type, we have four relations: viewer, commenter, editor and owner.

User, relation and object are the building blocks for relationship tuples.

For more information, please see Direct Access.

What Is A Relationship Tuple?

A relationship tuple is a tuple consisting of a user, relation and object stored in OpenFGA.

A relationship tuple consists of a:

  • user, e.g. anne, 3f7768e0-4fa7-4e93-8417-4da68ce1846c, workspace:auth0 or folder:planning#editor
  • relation, e.g. editor, member or parent_workspace
  • object, e.g repo:auth0/express_jwt, domain:auth0.com or channel:marketing

An authorization model, together with relationship tuples, allow the determination of whether a relationship exists between a user and an object.

Throughout the documentation, you will encounter relationship tuples represented as:

[
{
"user": "anne",
"relation": "editor",
"object": "document:new-roadmap",
},
]

For more information, please see Direct Access.

What Is A Relationship?

A relationship is the realization of a relation between a user and an object.

An authorization model, together with relationship tuples, allow the determination of whether a relationship exists between a user and an object. Relationships may be classified as direct or implied.

What Are Direct And Implied Relationships?

A direct relationship R between user X and object Y means the relationship tuple (user=X, relation=R, object=Y) exists, and the OpenFGA authorization model for that relation allows this direct relationship (by use of self).

An implied (or computed) relationship R exists between user X and object Y if user X is related to an object Z that is in a direct or implied relationship with object Y, and the OpenFGA authorization model allows it.

  • anne has a direct relationship with document:new-roadmap as viewer if the type definition allows it (allows self), and one of the following relationship tuples exist:

    • [
      // Anne is directly related to the document
      {
      "user": "anne",
      "relation": "viewer",
      "object": "document:new-roadmap",
      },
      ]
    • [
      // Everyone (`*`) is directly related to the document
      {
      "user": "*",
      "relation": "viewer",
      "object": "document:new-roadmap",
      },
      ]
    • [
      // The userset is directly related to this document
      {
      "user": "team:product#member",
      "relation": "viewer",
      "object": "document:new-roadmap",
      },
      // AND Anne is a member of a userset (e.g. team:product#member)
      {
      "user": "anne",
      "relation": "member",
      "object": "team:product#member",
      },
      ]
  • anne has an implied relationship with document:new-roadmap as viewer if the type definition allows it, and the presence of relationship tuples satisfying the relationship exist.

    For example, assuming the following type definition:

    type document
    relations
    define viewer as self or editor
    define editor as self

    And assuming the following relationship tuple exists in the system:

    [
    {
    "user": "anne",
    "relation": "editor",
    "object": "document:new-roadmap",
    },
    ]

    In this case, the relationship between anne and document:new-roadmap as a viewer is implied from the direct editor relationship anne has with that same document. Thus, the following request to check whether a viewer relationship exists between anne and document:new-roadmap will return true.

    Initialize the SDK
    // ApiTokenIssuer, ApiAudience, ClientId and ClientSecret are optional.
    // import the SDK
    const { OpenFgaApi } = require('@openfga/sdk');

    // Initialize the SDK with no auth - see "How to setup SDK client" for more options
    const fgaClient = new OpenFgaApi({
    apiScheme: process.env.FGA_API_SCHEME, // Either "http" or "https", defaults to "https"
    apiHost: process.env.FGA_API_HOST, // required, define without the scheme (e.g. api.openfga.example instead of https://api.openfga.example)
    storeId: process.env.FGA_STORE_ID, // Either "http" or "https", defaults to "https"
    });

    // Run a check
    const { allowed } = await fgaClient.check({
    tuple_key: {
    user: 'anne',
    relation: 'viewer',
    object: 'document:new-roadmap',
    },});

    // allowed = true

What Is A Check Request?

A check request is a call to the OpenFGA check endpoint that returns whether the user has a certain relationship with an object.

This can be done using the check methods in the OpenFGA SDKs (JavaScript SDK/Go SDK/.NET SDK), by manually calling the check endpoint using curl, or in your code.

The check endpoint responds with { "allowed": true } if a relationship exists, and with { "allowed": false } if the relationship does not.

For example, the following will check whether anne has a viewer relation to document:new-roadmap:

Initialize the SDK
// ApiTokenIssuer, ApiAudience, ClientId and ClientSecret are optional.
// import the SDK
const { OpenFgaApi } = require('@openfga/sdk');

// Initialize the SDK with no auth - see "How to setup SDK client" for more options
const fgaClient = new OpenFgaApi({
apiScheme: process.env.FGA_API_SCHEME, // Either "http" or "https", defaults to "https"
apiHost: process.env.FGA_API_HOST, // required, define without the scheme (e.g. api.openfga.example instead of https://api.openfga.example)
storeId: process.env.FGA_STORE_ID, // Either "http" or "https", defaults to "https"
});

// Run a check
const { allowed } = await fgaClient.check({
tuple_key: {
user: 'anne',
relation: 'viewer',
object: 'document:new-roadmap',
},});

// allowed = true

For more information, please see the Relationship Queries page and the official Check API Reference.

What Are Contextual Tuples?

Contextual tuples are tuples that can be added to a check request, and only exist within the context of that particular request.

Similar to relationship tuples, contextual tuples are composed of a user, relation and object.

Unlike relationship tuples, they are not written to the store. However, if contextual tuples are sent alongside a check request, in the context of this particular check request, they are treated if they had been written in the store.

For more information, please see Contextual and Time-Based Authorization, Authorization Through Organization Context and Check API Request Documentation.

How Do I Represent "Everyone"?

In OpenFGA the special syntax * means everyone when used as user in a relationship tuple.

For example, in a case where you would like to indicate a certain document document:new-roadmap is publicly writable (i.e. has everyone as an editor), you can add the following relationship tuple:

[
{
"user": "*",
"relation": "editor",
"object": "document:new-roadmap",
},
]

Note that * has no special meaning when used in the relation or object properties. For example, workspace:* as an object means a single object with the type workspace and identifier *. For more information, please see Modeling Public Access and Advanced Modeling: Modeling Google Drive.

OpenFGA Concepts

Learn about the OpenFGA Concepts

Direct access

Get started with modeling your permission system in OpenFGA