Skip to main content

User Groups

To add users to groups and grant groups access to an object using OpenFGA.

When to use

Relationship tuples can specify that an entire group has a relation to an object, which is helpful when you want to encompass a set of users with the same relation to an object. For example:

  • Grant viewer access to a group of engineers in roadmap.doc
  • Create a block_list of members who can't access a document
  • Sharing a document with a team
  • Granting viewer access to a photo to followers only
  • Making a file viewable for all users within an organization
  • Restricting access from or to users in a certain locale

Before you start

Familiarize yourself with the OpenFGA Concepts.

Assume you have the following authorization model.
: you have an object called document that users can relate to as an editor.

model
schema 1.1

type user

type document
relations
define editor: [user]

In addition, you will need to know the following:

Direct Access

You need to know how to create an authorization model and a relationship tuple to grant a user access to an object. To learn more, see direct access.

OpenFGA 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: 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.
  • An Object: represents an entity in the system. Users' relationships to it can be defined with relationship tuples and the authorization model.
  • A Relationship Tuple: a grouping consisting of a user, a relation and an object stored in OpenFGA.

Step By Step

There are possible use cases where a group of users have a certain role on or permission to an object. For example, members of a certain team could have an editor relation to a certain document.

To represent this in OpenFGA:

  1. Introduce the concept of a team to the authorization model.
  2. Add users as members to the team.
  3. Assign the team members a relation to an object.
  4. Check an individual member's access to the object.

01. Introduce the concept of a team to the authorization model

First, define the object team in your authorization model. In this use case, a team can have members, so you make the following changes to the authorization model:

model
schema 1.1

type user

type document
relations
define editor: [team#member]

type team
relations
define member: [user]

02. Add users as members to the team

You can now assign users as members of teams. Create a new relationship tuple that states user:alice is a member of team:writers.

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

// Initialize the SDK with no auth - see "How to setup SDK client" for more options
const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL, // required, e.g. https://api.fga.example
storeId: process.env.FGA_STORE_ID,
authorizationModelId: process.env.FGA_MODEL_ID, // Optional, can be overridden per request
});

await fgaClient.write({
writes: [
{"user":"user:alice","relation":"member","object":"team:writers"}
],
}, {
authorization_model_id: "01HVMMBCMGZNT3SED4Z17ECXCA"
});

03. Assign the team members a relation to an object

To represent groups, use the type:object_id#relation format, which represents the set of users related to the type:object_id as a certain relation. For example, team:writers#members represents the set of users related to the team:writers object as members.

In order to assign members of a team a relation to a document, create the following relationship tuple stating that members of team:writers are editors of document:meeting_notes.doc.

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

// Initialize the SDK with no auth - see "How to setup SDK client" for more options
const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL, // required, e.g. https://api.fga.example
storeId: process.env.FGA_STORE_ID,
authorizationModelId: process.env.FGA_MODEL_ID, // Optional, can be overridden per request
});

await fgaClient.write({
writes: [
// Set of users related to 'team:writers' as 'member'
{"_description":"Set of users related to 'team:writers' as 'member'","user":"team:writers#member","relation":"editor","object":"document:meeting_notes.doc"}
],
}, {
authorization_model_id: "01HVMMBCMGZNT3SED4Z17ECXCA"
});

04. Check an individual member's access to an object

Now that you have:

  • a relationship tuple indicating that alice is a member of team:writers
  • a relationship tuple indicating that members of team:writers are editors of document:meeting_notes.doc

The *check\ is alice an editor of document:meeting_notes.doc returns the following:

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

// Initialize the SDK with no auth - see "How to setup SDK client" for more options
const fgaClient = new OpenFgaClient({
apiUrl: process.env.FGA_API_URL, // required, e.g. https://api.fga.example
storeId: process.env.FGA_STORE_ID,
authorizationModelId: process.env.FGA_MODEL_ID, // Optional, can be overridden per request
});

// Run a check
const { allowed } = await fgaClient.check({
user: 'user:alice',
relation: 'editor',
object: 'document:meeting_notes.doc',
}, {
authorization_model_id: '01HVMMBCMGZNT3SED4Z17ECXCA',
});

// allowed = true

The chain of resolution is:

  • alice is member of team:writers
  • members of team:writers are editors of document:meeting_notes
  • therefore, alice is editor of document:meeting_notes
caution

Note: When creating relationship tuples for OpenFGA, use unique ids for each object and user in your application domain. This example uses first names and simple ids as a suggested example.

Managing Group Membership

Learn how to add and remove users from groups

Modeling Google Drive

See how User Groups can be used to share documents within a domain in the Google Drive use-case.

Modeling GitHub

Granting teams permissions to a repo in the GitHub use-case.