Skip to main content

Direct Relationships

note
Auth0 Fine Grained Authorization (FGA) is the early-stage product we are building at Auth0 to solve fine-grained authorization at scale. Sign up for the Developer Community Preview to try it out, and join our Discord community if you are interested in learning more about our plans.

Please note that at this point in time, it is not considered production-ready and does not come with any SLAs; availability and uptime are not guaranteed. Limitations of Auth0 FGA during the Developer Community Preview can be found here.

In this guide you'll learn how to model relationships that may or may not be assigned directly to individual users.

When to use

Disabling direct relationships for a certain relation on an objects are useful especially in cases where you are trying to model some permissions that are not usually granted individually to a user.

This is useful when:

  • For security reason, not permitting permissions assigned directly to individuals without associating roles

Before you start

To better understand this guide, you should be familiar with some Auth0 FGA Concepts and know how to develop the things listed below.

You will need to know the following:

  • Modeling Basics
  • Auth0 FGA Concepts

Modeling Basics

You need to know how to create an authorization model and create a relationship tuple to grant a user access to an object. Learn more →

Auth0 FGA Concepts

  • A Type: a class of objects that have similar characteristics
  • A User: an entity in the system that can be related to an object
  • A Relation: is a string defined in the type definition of an authorization model that defines the possibility of a relationship between objects of this type and other users in the system
  • An Object: represents an entity in the system. Users' relationships to it can be define through relationship tuples and the authorization model
  • A Relationship Tuple: a grouping consisting of a user, a relation and an object stored in Auth0 FGA
  • Direct Relationship Keyword: self used in the context of the relation definition can be used to allow direct relationships to the objects of this type

The Playground

Try this guide out on the Auth0 FGA Playground

What are direct relationships?

Direct relationships are relationships where a user has a relationship to an object that is not dependent on any other relationship they have with that object.

When checking for a relationship, a direct relationship exists if a relationship tuple is present in the system with the exact same object and relation that were in the query and where the user is one of:

  • the same user ID as that in the query
  • everyone (*)
  • a set of users that contains the user ID present in the query

Enable or disable direct relationships

Direct relationships can be enabled for a specific relation on an object type by adding the direct relationship keyword from that relation's definition. Likewise, they can be disabled by removing that keyword.

type document
relations
define viewer as self or editor
define editor as self
type team
relations
define member as self
info

The authorization model describes two object types: document and team.

The document type definition has two relations, editor and viewer. Both relations allow a direct relationship; viewer also allows an indirect relationshipthrough editor.

In the team type definition, there is a single member relation that only allows direct relationships.

How it affects your system

To illustrate the effect enabling or disabling direct relationships on a specific relation has, we'll investigate several situations.

1. With direct relationships enabled

Let us start with the authorization model we had above:

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

Now choose the type of relation to see how it affects your system:

Assume you have a tuple that states that Anne is a viewer of document:planning

[
{
"user": "anne",
"relation": "viewer",
"object": "document:planning",
},
]

Now if we do a check request to see if Anne can view the planning document, we will get a response of {"allowed": true}.

Initialize the SDK
// FGA_ENVIRONMENT can be "us" (default if not set) for Developer Community Preview or "playground" for the Playground API
// import the SDK
const { Auth0FgaApi } = require('@auth0/fga');

// Initialize the SDK
const fgaClient = new Auth0FgaApi({
environment: process.env.FGA_ENVIRONMENT,
storeId: process.env.FGA_STORE_ID,
clientId: process.env.FGA_CLIENT_ID,
clientSecret: process.env.FGA_CLIENT_SECRET,
});

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

// allowed = true

This is because:

  • There is a relationship tuple specifying that Anne has a viewer relationship with document:planning.
  • Direct relationships are allowed in the viewer relation definition in the document type definition.

2. With direct relationships disabled

In this section, we will investigate the effect of disabling direct relationships on the document's viewer relation.

type document
relations
define viewer as editor
define editor as self
type team
relations
define member as self
info

Notice that in this updated authorization model, the direct relationship keyword has been removed from the document's viewer relation definition.

Now choose the type of relation to see how it affects your system:

Assume you have a tuple that states that Fred is a viewer of document:planning

[
{
"user": "fred",
"relation": "viewer",
"object": "document:planning",
},
]

Now if we do a check request to see if Fred can view the planning document, we will get a response of {"allowed": false}.

Initialize the SDK
// FGA_ENVIRONMENT can be "us" (default if not set) for Developer Community Preview or "playground" for the Playground API
// import the SDK
const { Auth0FgaApi } = require('@auth0/fga');

// Initialize the SDK
const fgaClient = new Auth0FgaApi({
environment: process.env.FGA_ENVIRONMENT,
storeId: process.env.FGA_STORE_ID,
clientId: process.env.FGA_CLIENT_ID,
clientSecret: process.env.FGA_CLIENT_SECRET,
});

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

// allowed = false

This is because:

  • Even though there is a relationship tuple specifying that Fred has a viewer relationship with document:planning.
  • Direct relationships are NOT allowed in the viewer relation definition in the document type definition.
Modeling Roles and Permissions

Learn how to remove the direct relationship to indicate nonassignable permissions.

Modeling for IoT

See how Roles and Permissions can be used in an IoT use-case.

Modeling Entitlements

Take a look at the access relation in the feature type for an example of removing the direct relationship

Have Feedback?

Join us on the Discord community if you have any questions or suggestions.