Skip to main content

Transactional Writes

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 will learn how to update multiple relationship tuples in a single transaction.

When to use

Updating multiple relationship tuples is useful to keep system state consistent.

Before you start

In order to understand this guide correctly you must be familiar with some Auth0 FGA Concepts and know how to develop the things that we will list below.

Assume that you have the following authorization model.
You have a type called tweet that can have a reader. You have another type called user that can have a follower and followed_by relationship.

type tweet
relations
define reader as self
type user
relations
define follower as self
define followed_by as self

In addition, you will need to know the following:

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 →

Modeling Public Access

You need to know how to grant public 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

Step by Step

01. Adding and removing relationship tuples in the same transaction

When you need to add or delete tuples in your store, you can do so by calling the Write API. For example, if you want to make tweet:1 public by making everyone a viewer, you write one tuple:

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,
});

await fgaClient.write({
writes: {
tuple_keys: [
{ user: '*', relation: 'viewer', object: 'tweet:1'}
]
}
});

And if you want to convert this tweet to private, you would need to delete that tuple:

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,
});

await fgaClient.write({
deletes: {
tuple_keys : [
{ user: '*', relation: 'viewer', object: 'tweet:1'}
]
}
});

By removing the tuple, we made the tweet visible to no-one, which may not be what we want.

The Write API allows you to send up to 10 unique tuples in the request. (This limit applies to the sum of both writes and deletes in that request). This means we can submit one API call that converts the tweet from public to visible to only the user's followers.

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,
});

await fgaClient.write({
writes: {
tuple_keys: [
// Anne's followers can view tweet:1
{ user: 'user:anne#follower', relation: 'viewer', object: 'tweet:1'}
]
},
deletes: {
tuple_keys : [
// tweet:1 is no longer viewable by everyone (*)
{ user: '*', relation: 'viewer', object: 'tweet:1'}
]
}
});

Having the ability to send multiple tuples per request is also useful when you want to maintain consistency. For example, if anne starts following becky, we want to be able to save the following two tuples, or neither of them:

[
// Anne is a follower of Becky
{
"user": "anne",
"relation": "follower",
"object": "user:becky",
},
// Becky is followed by Anne
{
"user": "becky",
"relation": "followed_by",
"object": "user:anne",
},
]
info

We have a type called user in this case because users can be related to each other, so the users now are a type in the system

The Auth0 Fine Grained Authorization (FGA) service will attempt to perform all the changes sent in a single Write API call in one transaction. If it can't (for example, if any of the requested changes fails), it will reject all of the changes.

Update relationship tuples in SDK

Learn about how to update relationship tuples in SDK.

Auth0 FGA API

Details on the write API in the Auth0 FGA reference guide.

Have Feedback?

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