Skip to main content

Managing Group Membership

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 a user's membership to a group by adding and removing them from it.

When to use

Suppose:

  • An employee is hired at a company and thus gains access to all of the company's resources.
  • An employee quits and thus loses access to all of the company's resources.
  • A user joins a GitHub organization and gains access to the organizations private repositories.
  • A student graduates from school and loses access to the school's facilities.

These are cases where using group membership can be helpful as you do not need to iterate over all of the group's resources to add or revoke access to particular objects. You can add a relationship tuple indicating that a user belongs to a group, or delete a tuple to indicate that a user is no longer part of the group.

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 two types:

  • org that can have a member relation
  • document that can have a reader relation.
type org
relations
define member as self
type document
relations
define reader as self

Let us also assume that we have an org called "contoso" and a document called planning, and every member of that org can read the document. That is represented by having the following relationship tuple in the store:

[
// Members of the contoso org can read the planning document
{
"user": "org:contoso#member",
"relation": "reader",
"object": "document:planning",
},
]

With the above authorization model and relationship tuples, Auth0 FGA will respond with {"allowed":false} when check is called to see if Anne can read document:planning.

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: 'reader',
object: 'document:planning',
},});

// allowed = false

Now let's make Anne a member of org:contoso by adding another 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: [
// Anne is a member of the contoso org
{ user: 'anne', relation: 'member', object: 'org:contoso'}
]
}
});

The Auth0 FGA service will now correctly respond with {"allowed":true} when check is called to see if Anne can read document:planning, but it will still respond with {"allowed":false} if we ask the same question for another user called Becky, who is not a member of the group org:contoso.

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: 'reader',
object: 'document:planning',
},});

// 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: 'becky',
relation: 'reader',
object: 'document:planning',
},});

// allowed = false

Modeling User Groups

You need to know how to add users to groups and grant groups access to an object. Learn more →

Managing Group Access

You need to know how to manage group 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. Revoking group membership

Imagine that every member of org:contoso has a reader relationship to 1000 documents. Now imagine that anne is no longer a member of org:contoso, so we want to revoke her access to all those documents, including document:planning. To accomplish this, we can simply delete the tuple in Auth0 FGA that specifies that Anne is a member of org:contoso.

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: 'anne', relation: 'member', object: 'org:contoso'}
]
}
});

02. Validating revoked member no longer has access

Once the above relationship tuple is deleted, we can check if Anne can read document:planning. Auth0 FGA will return { "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: 'anne',
relation: 'reader',
object: 'document:planning',
},});

// allowed = false
Modeling User Groups

Learn about how to model users and groups.

Managing Group Access

Learn about managing group access.

Have Feedback?

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